diff --git a/src/CFGraph/IR_SSAForm.cpp b/src/CFGraph/IR_SSAForm.cpp index 117cb60..0b1fb5f 100644 --- a/src/CFGraph/IR_SSAForm.cpp +++ b/src/CFGraph/IR_SSAForm.cpp @@ -14,62 +14,9 @@ using namespace std; using namespace SAPFOR; -typedef SAPFOR::BasicBlock BBlock; -typedef SAPFOR::Argument BArgument; +static const SAPFOR::Argument CONST_UNDEFINED_ARG(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1"); -static void printBlock(BBlock* 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() != NULL && 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() != NULL && 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() != NULL && 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() != NULL && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) - i->getInstruction()->getResult()->setValue(resValue); - - if (i->getInstruction()->getArg1() != NULL && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) - i->getInstruction()->getArg1()->setValue(arg1Value); - - if (i->getInstruction()->getArg2() != NULL && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) - i->getInstruction()->getArg2()->setValue(arg2Value); - } - - cout << endl; -} - -template -static bool compareVectors(const vector* vec1, const vector* vec2) +template static bool compareVectors(const vector* vec1, const vector* vec2) { if (vec1 == vec2) return true; @@ -86,35 +33,29 @@ static bool compareVectors(const vector* vec1, const vector* vec2) return sortedVec1 == sortedVec2; } -template -static vector* getCommonElements(const vector>* vectors) +template static vector* getCommonElements(const vector>* vectors) { if (!vectors || vectors->empty()) - return new vector(); // Return an empty vector if input is null or empty + return new vector(); - // Start with the first vector vector* commonElements = new vector((*vectors)[0]); for (size_t i = 1; i < vectors->size(); ++i) { vector tempCommon; - // Sort the current vector and common result for intersection vector sortedVec = (*vectors)[i]; sort(commonElements->begin(), commonElements->end()); sort(sortedVec.begin(), sortedVec.end()); - // Find the intersection set_intersection( commonElements->begin(), commonElements->end(), sortedVec.begin(), sortedVec.end(), back_inserter(tempCommon) ); - // Update common result *commonElements = tempCommon; - // If no common elements left, break early if (commonElements->empty()) break; } @@ -123,19 +64,19 @@ static vector* getCommonElements(const vector>* vectors) } -static map> findDominators(const vector& blocks) +static map> findDominators(const vector& blocks) { - map> result; + map> result; bool changed = true; - while (changed) + while (changed) { changed = false; for (auto& currentBlock : blocks) { auto pred = currentBlock->getPrev(); - auto prevDominators = new vector>(); + auto prevDominators = new vector>(); for (auto predBlock : pred) prevDominators->push_back(result.find(predBlock) != result.end() ? result[predBlock] : blocks); @@ -154,29 +95,12 @@ static map> findDominators(const vector& block return result; } -static void renumberBlocks(BBlock* current, int* n, map* res, set* visited) { - if (visited->find(current) != visited->end()) - return; - - visited->insert(current); - vector nextBlocks = current->getNext(); - - sort(nextBlocks.begin(), nextBlocks.end(), [](BBlock* a, BBlock* b) { - return a->getInstructions()[0]->getInstruction()->getOperator()->lineNumber() > b->getInstructions()[0]->getInstruction()->getOperator()->lineNumber(); - }); - - for (auto& i : nextBlocks) - renumberBlocks(i, n, res, visited); - - (*res)[current->getNumber()] = *n; - *n -= 1; -} - -static map> findDominatorBorders(const vector& blocks, map& iDominators) { - map> result; +static map> findDominatorBorders(const vector& blocks) +{ + map> result; for (auto& block : blocks) - result[block] = *(new vector()); + result[block] = *(new vector()); for (auto& block : blocks) { @@ -185,13 +109,11 @@ static map> findDominatorBorders(const vector& for (auto prev : block->getPrev()) { auto tmpBlock = prev; - auto test = iDominators[block]; - auto test2 = iDominators[prev]; - while (tmpBlock != iDominators[block]) + while (tmpBlock != block->getDom()) { result[tmpBlock].push_back(block); - tmpBlock = iDominators[tmpBlock]; + tmpBlock = tmpBlock->getDom(); } } } @@ -200,122 +122,14 @@ static map> findDominatorBorders(const vector& return result; } -static BBlock* findImmediateDominatorsDfsHelper(BBlock* block, BBlock* currentBlock, BBlock* currentImmediateDominator, vector &visited, map>& dominators) +static pair, map>> getGlobalsAndVarBlocks(const vector& blocks) { - if (block == currentBlock) - return currentImmediateDominator; - - if (find(visited.begin(), visited.end(), currentBlock) != visited.end()) - return NULL; - - visited.push_back(currentBlock); - - if (find(dominators[block].begin(), dominators[block].end(), currentBlock) != dominators[block].end()) - currentImmediateDominator = currentBlock; - - for (auto& nextBlock : currentBlock->getNext()) - { - auto result = findImmediateDominatorsDfsHelper(block, nextBlock, currentImmediateDominator, visited, dominators); - - if (result) - return result; - } - - return NULL; -} - -bool checkoDom(vector a, vector b, BBlock* c) { - if (a.size() != b.size() + 1) { - return false; - } - - for (auto i : a) - { - if (i != c && find(b.begin(), b.end(), i) == b.end()) { - return false; - } - } - - return true; -} - -static map findImmediateDominators1(const map>& dominators, BBlock* entry) -{ - map iDom; - - for (const auto& pair : dominators) { - BBlock* b = pair.first; - - if (b == entry) continue; - - const auto& doms = pair.second; - - // candidates = all dominators of b except itself - bool found = false; - for (auto& d : doms) { - if (d == b) continue; - - if (checkoDom(doms, dominators.at(d), b)) { - iDom[b] = d; - found = true; - break; - } - } - - if (!found) { - cout << "ERRORERRORERROR " << b->getNumber() << endl; - } - } - - return iDom; -} - -static map findImmediateDominators(map>& dominators, BBlock* fistBlock) -{ - map iDominators; - - for (const auto& [block, domBlocks] : dominators) { - vector visited; - - if (block == fistBlock) - continue; - - iDominators[block] = findImmediateDominatorsDfsHelper(block, fistBlock, fistBlock, visited, dominators); - } - - return iDominators; -} - -static vector getDefForBlock(const BBlock& block) -{ - vector def; - const auto& instructions = block.getInstructions(); - - for (const auto& irBlock : instructions) - { - if (irBlock) - { - Instruction* instr = irBlock->getInstruction(); - - if (instr) - { - BArgument* result = instr->getResult(); - if (result) - def.push_back(result); - } - } - } - - return def; -} - -static pair, map>> getGlobalsAndVarBlocks(const vector& blocks) { - set globals; - map> varBlocks; + set globals; + map> varBlocks; for (auto& block : blocks) { - set def; + set def; const auto& instructions = block->getInstructions(); for (const auto& irBlock : instructions) @@ -349,18 +163,18 @@ static pair, map>> getGlobalsAndVarBloc return make_pair(globals, varBlocks); } -static void getBlocksWithFiFunctions(const vector blocks, set& globals, - map>& varBlocks, - map>& dominatorBorders) +static void getBlocksWithFiFunctions(const vector blocks, set& globals, + map>& varBlocks, + map>& dominatorBorders) { - vector blocksWithFiFunctions; - auto fiFunc = new BArgument(CFG_ARG_TYPE::FUNC, CFG_MEM_TYPE::NONE_, "FI_FUNCTION"); - auto paramCount = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::LOCAL_, "0"); + vector blocksWithFiFunctions; + auto fiFunc = new SAPFOR::Argument(CFG_ARG_TYPE::FUNC, CFG_MEM_TYPE::NONE_, "FI_FUNCTION"); + auto paramCount = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::LOCAL_, "0"); for (auto& var : globals) { auto worklist = varBlocks[var]; - set hasFiFunction; + set hasFiFunction; while (!worklist.empty()) { @@ -372,81 +186,53 @@ static void getBlocksWithFiFunctions(const vector blocks, setgetInstructions()[0]->getInstruction()->getOperator()); + Instruction* phiInstruction = new Instruction(CFG_OP::F_CALL, new SAPFOR::Argument(*fiFunc), new SAPFOR::Argument(*paramCount), var, dfBlock->getInstructions()[0]->getInstruction()->getOperator()); IR_Block* phiBlock = new IR_Block(phiInstruction); dfBlock->addInstruction(phiBlock, true); - - //blocksWithFiFunctions.push_back(dfBlock); } } } } - - //return blocksWithFiFunctions; } -static string ToString(CFG_ARG_TYPE type) +static void restoreConnections(const vector& originalBlocks, vector& copiedBlocks) { - switch (type) { - case CFG_ARG_TYPE::NONE: return "NONE"; - case CFG_ARG_TYPE::REG: return "REG"; - case CFG_ARG_TYPE::VAR: return "VAR"; - case CFG_ARG_TYPE::ARRAY: return "ARRAY"; - case CFG_ARG_TYPE::CONST: return "CONST"; - case CFG_ARG_TYPE::FUNC: return "FUNC"; - case CFG_ARG_TYPE::LAB: return "LAB"; - case CFG_ARG_TYPE::INSTR: return "INSTR"; - case CFG_ARG_TYPE::CONST_STR: return "CONST_STR"; - case CFG_ARG_TYPE::RECORD: return "RECORD"; - case CFG_ARG_TYPE::CONSTR_REF: return "CONSTR_REF"; - default: return "UNKNOWN"; - } -} - -static void restoreConnections(const vector& originalBlocks, vector& copiedBlocks) -{ - // Создаем отображение оригинальных блоков в их копии - map blockMapping; + map blockMapping; for (size_t i = 0; i < originalBlocks.size(); ++i) blockMapping[originalBlocks[i]] = copiedBlocks[i]; - - // Восстанавливаем связи между копиями + for (size_t i = 0; i < originalBlocks.size(); ++i) { - BBlock* originalBlock = originalBlocks[i]; - BBlock* copiedBlock = copiedBlocks[i]; + SAPFOR::BasicBlock* originalBlock = originalBlocks[i]; + SAPFOR::BasicBlock* copiedBlock = copiedBlocks[i]; auto prevCopy = copiedBlock->getPrev(); for (auto j : prevCopy) copiedBlock->removePrev(j); - // Копируем, затем удаляем next связи auto nextCopy = copiedBlock->getNext(); for (auto j : nextCopy) copiedBlock->removeNext(j); - // Восстанавливаем связи succ (следующих блоков) for (auto* succ : originalBlock->getNext()) copiedBlock->addNext(blockMapping[succ]); - // Восстанавливаем связи prev (предыдущих блоков) for (auto* prev : originalBlock->getPrev()) copiedBlock->addPrev(blockMapping[prev]); } } -static BArgument* newName(BArgument* var, map& counter, map>& stack, int number) { - //int index = counter[var->getValue()]; +static SAPFOR::Argument* newName(SAPFOR::Argument* var, map& counter, map>& stack, int number) { counter[var->getValue()]++; - BArgument* newName = new BArgument(var->getType(), var->getMemType(), var->getValue(), number); + SAPFOR::Argument* newName = new SAPFOR::Argument(var->getType(), var->getMemType(), var->getValue(), number); stack[var->getValue()].push(newName); return newName; } -static void renameFiFunctionResultVar(BBlock* block, map& counter, map>& stack) { +static void renameFiFunctionResultVar(SAPFOR::BasicBlock* block, map& counter, map>& stack) { for (auto& irBlock : block->getInstructions()) { auto instruction = irBlock->getInstruction(); @@ -458,7 +244,7 @@ static void renameFiFunctionResultVar(BBlock* block, map& counter, } } -static void renameInstructionVars(BBlock* block, map& counter, map>& stack) +static void renameInstructionVars(SAPFOR::BasicBlock* block, map& counter, map>& stack) { for (auto& irBlock : block->getInstructions()) { @@ -475,13 +261,11 @@ static void renameInstructionVars(BBlock* block, map& counter, map< } } -static void renameFiFunctionArgsVar(BBlock* block, map>& stack) +static void renameFiFunctionArgsVar(SAPFOR::BasicBlock* block, map>& stack) { auto size = block->getInstructions().size(); auto& instructions = block->getInstructions(); - //cout << "try to insert Phi to block - " << block->getNumber() << endl; - for (size_t i = 0; i < size; ++i) { auto irBlock = instructions[i]; @@ -490,17 +274,16 @@ static void renameFiFunctionArgsVar(BBlock* block, map instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL && instruction->getArg2() != NULL) { - //cout << "Insert Phi to block - " << block->getNumber() << endl; Instruction* paramInstruction; if (stack[instruction->getResult()->getValue()].size() > 0) { - BArgument* tmp = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, to_string(stack[instruction->getResult()->getValue()].top()->getNumber())); + SAPFOR::Argument* tmp = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, to_string(stack[instruction->getResult()->getValue()].top()->getNumber())); paramInstruction = new Instruction(CFG_OP::PARAM, tmp); } else { - BArgument* tmp = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1"); + SAPFOR::Argument* tmp = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1"); paramInstruction = new Instruction(CFG_OP::PARAM, tmp); } @@ -513,30 +296,27 @@ static void renameFiFunctionArgsVar(BBlock* block, map } } -static vector findBlocksWithValue(map& iDominators, BBlock* x) +static vector findBlocksWithValue(vector& blocks, SAPFOR::BasicBlock* x) { - vector result; + vector result; - // Проходим по всем элементам map - for (auto& pair : iDominators) - if (pair.second == x) // Если значение равно x, добавляем ключ в результат - result.push_back(pair.first); + for (auto& block : blocks) + if (block->getDom() == x) + result.push_back(block); return result; } -static void renameIR(BBlock* block, map& iDominators, map& counter, map>& stack) { - - //cout << "renameIR for block " << block->getNumber() << endl; - +static void renameIR(SAPFOR::BasicBlock* block, vector& blocks, map& counter, map>& stack) +{ renameFiFunctionResultVar(block, counter, stack); renameInstructionVars(block, counter, stack); for (auto& successor : block->getNext()) renameFiFunctionArgsVar(successor, stack); - for (auto& child : findBlocksWithValue(iDominators, block)) - renameIR(child, iDominators, counter, stack); + for (auto& child : findBlocksWithValue(blocks, block)) + renameIR(child, blocks, counter, stack); for (auto& irBlock : block->getInstructions()) { @@ -560,119 +340,47 @@ static void renameIR(BBlock* block, map& iDominators, map& funcIRConst, std::map>& result) +{ + vector funcIR; -void buildIRSSAForm(const map>& fullIR, - map>& result) { + for (auto& i : funcIRConst) + funcIR.push_back(new SAPFOR::BasicBlock(*i)); - for (auto& [funcinfo, funcIRConst]: fullIR) { - if (isEqual1("csol.for", funcinfo->fileName) || isEqual1("reblns.for", funcinfo->fileName) || isEqual1("adjont.for", funcinfo->fileName) - || isEqual1("beginf.for", funcinfo->fileName) || isEqual1("dsnp1.for", funcinfo->fileName) || isEqual1("dsnpnm.for", funcinfo->fileName) - || isEqual1("decod3.for", funcinfo->fileName)) - continue; + restoreConnections(funcIRConst, funcIR); - cout << "Testing " << funcinfo->funcName << endl; + SAPFOR::buildDominatorTree(funcIR); - vector funcIR; + auto dominatorBorders = findDominatorBorders(funcIR); - /* for (auto& i : funcIRConst) { - printBlock(i); - }*/ + auto globalsAndVarBlocks = getGlobalsAndVarBlocks(funcIR); + auto globals = globalsAndVarBlocks.first; + auto varBlocks = globalsAndVarBlocks.second; - for (auto& i : funcIRConst) - funcIR.push_back(new BBlock(*i)); + getBlocksWithFiFunctions(funcIR, globals, varBlocks, dominatorBorders); - restoreConnections(funcIRConst, funcIR); + map count; + map> varStack; - /*for (auto& i : funcIR) { - printBlock(i); - }*/ - for (auto& [func, bblocks] : result) - SAPFOR::buildDominatorTree(bblocks); - auto dominators = findDominators(funcIR); + for (auto& var : globals) + { + count[var->getValue()] = 0; - /*cout << endl << endl << endl << "DOMINATORS" << endl << endl << endl; - - for (auto i : dominators) { - cout << "block - " << i.first->getNumber() << endl; - for (auto j : i.second) { - cout << "dominators - " << j->getNumber() << endl; - } - - cout << endl; - }*/ - - auto iDominators = findImmediateDominators1(dominators, funcIR[0]); - - /*for (auto i : iDominators) { - cout << "block - " << i.first->getNumber() << endl; - cout << "Idominators - " << i.second->getNumber() << endl; - cout << endl; - } - */ - auto dominatorBorders = findDominatorBorders(funcIR, iDominators); - - /*for (auto i : dominatorBorders) { - cout << "block - " << i.first->getNumber() << endl; - for (auto j : i.second) { - cout << "border - " << j->getNumber() << endl; - } - - cout << endl; - }*/ - - auto globalsAndVarBlocks = getGlobalsAndVarBlocks(funcIR); - auto globals = globalsAndVarBlocks.first; - auto varBlocks = globalsAndVarBlocks.second; - - /*for (auto i : globals) { - cout << i->getValue() << " " << ToString(i->getType()) << " " << i->getNumber() << endl; - - } - cout << endl; - for (auto i : varBlocks) { - cout << i.first->getValue() << " - "; - for (auto j : i.second) { - cout << j->getNumber() << ", "; - } - cout << endl; - } - cout << endl; - */ - - getBlocksWithFiFunctions(funcIR, globals, varBlocks, dominatorBorders); - - map count; - map> varStack; - - for (auto& var : globals) - { - count[var->getValue()] = 0; - - stack tmp; - BArgument* tmpArgument = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1"); - tmp.push(tmpArgument); - varStack[var->getValue()] = tmp; - } - - /*for (auto& i : funcIR) { - printBlock(i); - }*/ - - renameIR(funcIR[0], iDominators, count, varStack); - - //cout << endl << endl << "___________________" << endl << endl; - - /*for (auto& i : funcIR) { - printBlock(i); - }*/ - //cout << endl << endl << endl << endl << endl; - //for (auto i : funcIRConst) { - // printBlock(i); - //} - - result[funcinfo] = funcIR; + stack tmp; + tmp.push(new SAPFOR::Argument(CONST_UNDEFINED_ARG)); + varStack[var->getValue()] = tmp; } + + renameIR(funcIR[0], funcIR, count, varStack); + + result[funcInfo] = funcIR; } + +FuncInfo* getIRByFilename(const std::map>& fullIR, const char* filename) +{ + for (auto ir : fullIR) + if (ir.first->fileName == filename) + return ir.first; + + return nullptr; +} \ No newline at end of file diff --git a/src/CFGraph/IR_SSAForm.h b/src/CFGraph/IR_SSAForm.h index cdc2efc..6f616e3 100644 --- a/src/CFGraph/IR_SSAForm.h +++ b/src/CFGraph/IR_SSAForm.h @@ -3,4 +3,6 @@ #include "CFGraph.h" #include "IR.h" -void buildIRSSAForm(const std::map>& fullIR, std::map>& result); \ No newline at end of file +void buildFuncIRSSAForm(FuncInfo* funcInfo, const std::vector& fullIR, std::map>& result); + +FuncInfo* getIRByFilename(const std::map>& fullIR, const char* filename); \ No newline at end of file diff --git a/src/LoopAnalyzer/implicit_loops_analyzer.cpp b/src/LoopAnalyzer/implicit_loops_analyzer.cpp index e2dbd30..c0213d7 100644 --- a/src/LoopAnalyzer/implicit_loops_analyzer.cpp +++ b/src/LoopAnalyzer/implicit_loops_analyzer.cpp @@ -27,97 +27,51 @@ enum VisitState { UNVISITED = 0, VISITING = 1, VISITED = 2 }; void dfs(SAPFOR::BasicBlock* block, std::map& visit, std::vector>& startAndEnd, - SAPFOR::BasicBlock* prev) { - if (!block) return; + SAPFOR::BasicBlock* prev) +{ + if (!block) + return; int id = block->getNumber(); if (visit[id] == VISITING) { - // Обратное ребро — фиксируем цикл startAndEnd.emplace_back(prev, block); - //std::cout << "Back edge detected: " << prev->getNumber() << " -> " << id << std::endl; return; } - if (visit[id] == VISITED) { + if (visit[id] == VISITED) return; - } visit[id] = VISITING; - for (auto next : block->getNext()) { + for (auto next : block->getNext()) dfs(next, visit, startAndEnd, block); - } visit[id] = VISITED; } -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) { +void getLoopBody(SAPFOR::BasicBlock* loopHeader, const std::set& loopExits, std::vector& loopBody) +{ std::set visited; std::stack stack; stack.push(loopHeader); - while (!stack.empty()) { + while (!stack.empty()) + { auto block = stack.top(); stack.pop(); - if (visited.count(block)) continue; + if (visited.count(block)) + continue; visited.insert(block); - for (auto succ : block->getNext()) { - if (loopExits.count(succ)) continue; - if (!visited.count(succ)) { + for (auto succ : block->getNext()) + { + if (loopExits.count(succ)) + continue; + if (!visited.count(succ)) stack.push(succ); - } } } @@ -125,127 +79,127 @@ void getLoopBody(SAPFOR::BasicBlock* loopHeader, const std::set reverseStack; reverseStack.push(loopHeader); - while (!reverseStack.empty()) { + while (!reverseStack.empty()) + { auto block = reverseStack.top(); reverseStack.pop(); - if (backReachable.count(block)) continue; + if (backReachable.count(block)) + continue; backReachable.insert(block); - for (auto pred : block->getPrev()) { - if (visited.count(pred) && !backReachable.count(pred)) { + for (auto pred : block->getPrev()) + if (visited.count(pred) && !backReachable.count(pred)) reverseStack.push(pred); - } - } } - for (auto block : visited) { - if (backReachable.count(block)) { + for (auto block : visited) + if (backReachable.count(block)) loopBody.push_back(block); - } - } } SAPFOR::Instruction* findDef(const SAPFOR::Argument* arg, - const std::vector& blocks) { - if (!arg) return nullptr; + const std::vector& blocks) +{ + if (!arg) + return nullptr; std::string argName = arg->getValue(); for (auto block : blocks) { for (auto instrWrapper : block->getInstructions()) { auto instr = instrWrapper->getInstruction(); - if (!instr) continue; + if (!instr) + continue; auto res = instr->getResult(); - if (!res) continue; + if (!res) + continue; - if (res->getValue() == argName) { + if (res->getValue() == argName) return instr; - } } } return nullptr; } -const SAPFOR::Argument* getBaseSource(const SAPFOR::Argument* arg, const std::vector& blocks) { - while (arg && arg->getType() == CFG_ARG_TYPE::REG) { +const SAPFOR::Argument* getBaseSource(const SAPFOR::Argument* arg, const std::vector& blocks) +{ + while (arg && arg->getType() == CFG_ARG_TYPE::REG) + { auto defInstr = findDef(arg, blocks); - if (!defInstr) break; + if (!defInstr) + break; auto defOp = defInstr->getOperation(); - if (defOp == CFG_OP::ASSIGN) { + if (defOp == CFG_OP::ASSIGN) arg = defInstr->getArg1(); - } - else { + else break; - } } return arg; } -void findInductiveVars(const std::vector& Loopblocks, const std::vector& blocks) { +void findInductiveVars(const std::vector& Loopblocks, const std::vector& blocks) +{ std::set inductiveVars; - for (auto block : Loopblocks) { - for (auto instrWrapper : block->getInstructions()) { + for (auto block : Loopblocks) + { + for (auto instrWrapper : block->getInstructions()) + { auto instr = instrWrapper->getInstruction(); - if (!instr) continue; + if (!instr) + continue; auto res = instr->getResult(); - if (!res || res->getType() != SAPFOR::CFG_ARG_TYPE::VAR) continue; + if (!res || res->getType() != SAPFOR::CFG_ARG_TYPE::VAR) + continue; - while (instr && instr->getOperation() == CFG_OP::ASSIGN) { + while (instr && instr->getOperation() == CFG_OP::ASSIGN) instr = findDef(instr->getArg1(), blocks); - } - if (!instr || instr->getOperation() != CFG_OP::ADD && instr->getOperation() != CFG_OP::SUBT) continue; + if (!instr || instr->getOperation() != CFG_OP::ADD && instr->getOperation() != CFG_OP::SUBT) + continue; auto arg1 = getBaseSource(instr->getArg1(), blocks); auto arg2 = getBaseSource(instr->getArg2(), blocks); bool ok = false; - if (res->getValue() == arg1->getValue() && - arg2->getType() == CFG_ARG_TYPE::CONST) { + if (res->getValue() == arg1->getValue() && arg2->getType() == CFG_ARG_TYPE::CONST) ok = true; - } - else if (res->getValue() == arg2->getValue() && - arg1->getType() == CFG_ARG_TYPE::CONST) { + else if (res->getValue() == arg2->getValue() && arg1->getType() == CFG_ARG_TYPE::CONST) ok = true; - } - if (ok) { + if (ok) inductiveVars.insert(res->getValue()); - } } } - if (inductiveVars.empty()) { + if (inductiveVars.empty()) std::cout << "No inductive variables found." << std::endl; - } - else { - for (const auto& var : inductiveVars) { + else + for (const auto& var : inductiveVars) std::cout << "Inductive variable: " << var << std::endl; - } - } } -Instruction* findInstructionAfterLoop(const std::vector& loopBody) { +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)) { - // Нашли выход из цикла — возьмём первую инструкцию + for (auto block : loopBody) + { + for (auto succ : block->getNext()) + { + if (!loopSet.count(succ)) + { auto instructions = succ->getInstructions(); - if (instructions.empty()) { + if (instructions.empty()) std::cout << "Exit block has no instructions." << std::endl; - } - for (auto wrapper : instructions) { - if (auto instr = wrapper->getInstruction()) { + + for (auto wrapper : instructions) + if (auto instr = wrapper->getInstruction()) return instr; - } - } } } } @@ -253,118 +207,75 @@ Instruction* findInstructionAfterLoop(const std::vector& lo return nullptr; } -bool isEqual(const char* cstr, const std::string& str) { - return str == cstr; -} +void findImplicitLoops(const std::vector& irSSA, const std::vector loopGraph) +{ + map visited; + for (auto i : irSSA) + visited[i->getNumber()] = UNVISITED; -void findImplicitLoops(const std::map>& fullIR_SSA, const char* fileName) { - for (auto& i : fullIR_SSA) + vector> startAndEnd; + dfs(irSSA[0], visited, startAndEnd, NULL); + + vector loops; + + for (auto& [tail, header] : startAndEnd) { - //for (auto j : i.second) - // printblock(j); + set loopExits; - if (!isEqual(fileName, i.first->fileName)) + for (auto succ : tail->getNext()) + if (succ != header) + loopExits.insert(succ); + + vector loopBody; + getLoopBody(header, loopExits, loopBody); + + findInductiveVars(loopBody, irSSA); + + Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody); + + if (instructionAfterLoop == NULL) + { + cout << "Warning: instruction after loop not found!" << endl; continue; - - if (isEqual("csol.for", i.first->fileName) || isEqual("reblns.for", i.first->fileName) || isEqual("adjont.for", i.first->fileName) - || isEqual("beginf.for", i.first->fileName) || isEqual("dsnp1.for", i.first->fileName) || isEqual("dsnpnm.for", i.first->fileName) - || isEqual("decod3.for", i.first->fileName)) - continue; - - //if (!isEqual("iter3.for", i.first->fileName)) - // continue; - - map visited; - for (auto i : i.second) - visited[i->getNumber()] = UNVISITED; - - //for (auto j : i.second) - // printBlock(j); - - //continue; - - //vector visited(i.second.size(), UNVISITED); - vector> startAndEnd; - dfs(i.second[0], visited, startAndEnd, NULL); - - //continue; - - 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(loopBody, i.second); - - continue; - - - Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody); - - if (instructionAfterLoop == NULL) { - cout << "Warning: instruction after loop not found!" << endl; - cout << i.first->fileName << 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(); - - //continue; - - 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); } + + auto firstInstruction = header->getInstructions()[0]->getInstruction(); + auto lastInstruction = tail->getInstructions().back()->getInstruction(); + auto tmpLoop = new LoopGraph(); + 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; + } + else if (firstInstruction->getOperator()->variant() == WHILE_NODE) + { + SgWhileStmt* stmt = isSgWhileStmt(firstInstruction->getOperator()); + + cout << (stmt->conditional() == NULL ? "infinit" : "") << "while loop" << endl; + } + else if (firstInstruction->getOperator()->variant() == DO_WHILE_NODE) + { + SgWhileStmt* stmt = isSgDoWhileStmt(firstInstruction->getOperator()); + + cout << "do while loop" << endl; + } + else if (firstInstruction->getOperator()->variant() == LOOP_NODE) + { + cout << "not known loop" << endl; + } + else + { + cout << "goto loop" << 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/LoopAnalyzer/implicit_loops_analyzer.h b/src/LoopAnalyzer/implicit_loops_analyzer.h index 3ed59e2..e5857e3 100644 --- a/src/LoopAnalyzer/implicit_loops_analyzer.h +++ b/src/LoopAnalyzer/implicit_loops_analyzer.h @@ -4,4 +4,4 @@ #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 +void findImplicitLoops(const std::vector& fullIR_SSA, const std::vector loopGraph); \ No newline at end of file diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 42c92fe..e40aeeb 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1023,11 +1023,15 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne } else if (curr_regime == BUILD_IR_SSA_FORM) { - if (fullIR_SSA.size() == 0) - buildIRSSAForm(fullIR, fullIR_SSA); + auto irFound = getIRByFilename(fullIR, file_name); + buildFuncIRSSAForm(irFound, fullIR[irFound], fullIR_SSA); } - else if (curr_regime == FIND_IMPLICIT_LOOPS) - findImplicitLoops(fullIR_SSA, file_name); + else if (curr_regime == FIND_IMPLICIT_LOOPS) + { + auto itFound = loopGraph.find(file_name); + auto irFound = getIRByFilename(fullIR_SSA, file_name); + findImplicitLoops(fullIR_SSA[irFound], itFound->second); + } else if (curr_regime == FIND_PRIVATE_ARRAYS) findPrivateArrays(loopGraph, fullIR); else if (curr_regime == TEST_PASS)