diff --git a/src/CFGraph/IR.h b/src/CFGraph/IR.h index bcb68e4..a5d34f3 100644 --- a/src/CFGraph/IR.h +++ b/src/CFGraph/IR.h @@ -52,10 +52,7 @@ namespace SAPFOR } } Argument(const Argument& other) - : number(other.number), - type(other.type), - mType(other.mType), - value(other.value) + : number(other.number), type(other.type), mType(other.mType), value(other.value) { } void setType(CFG_ARG_TYPE newType) { type = newType; } @@ -137,7 +134,7 @@ namespace SAPFOR { if (arg == NULL) return ""; - return arg->getValue(); + return arg->getValue(); } public: @@ -205,7 +202,7 @@ namespace SAPFOR { std::string res = ""; - std::string resultVal = getArgValue(result); + std::string resultVal = getArgValue(result); std::string arg1Val = getArgValue(arg1); std::string arg2Val = getArgValue(arg2); diff --git a/src/CFGraph/IR_SSAForm.cpp b/src/CFGraph/IR_SSAForm.cpp index f751a63..8783417 100644 --- a/src/CFGraph/IR_SSAForm.cpp +++ b/src/CFGraph/IR_SSAForm.cpp @@ -18,18 +18,16 @@ using namespace SAPFOR; typedef SAPFOR::BasicBlock BBlock; typedef SAPFOR::Argument BArgument; -static void printBlock(BBlock* block) { +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()) @@ -37,45 +35,46 @@ static void printBlock(BBlock* block) { string resValue = ""; string arg1Value = ""; string arg2Value = ""; - if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) { + + 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() != nullptr && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) { + } + + 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() != nullptr && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) { + + 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() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) { + if (i->getInstruction()->getResult() != NULL && 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) { + + if (i->getInstruction()->getArg1() != NULL && 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) { + + 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) { - if (vec1 == vec2) { +static bool compareVectors(const vector* vec1, const vector* vec2) +{ + if (vec1 == vec2) return true; - } - - if (!vec1 || !vec2) { + + if (!vec1 || !vec2) return false; - } - + vector sortedVec1 = *vec1; vector sortedVec2 = *vec2; @@ -86,15 +85,16 @@ static bool compareVectors(const vector* vec1, const vector* vec2) { } template -static vector* getCommonElements(const vector>* vectors) { - if (!vectors || vectors->empty()) { +static vector* getCommonElements(const vector>* vectors) +{ + if (!vectors || vectors->empty()) return new vector(); // Return an empty vector if input is null or empty - } - + // Start with the first vector vector* commonElements = new vector((*vectors)[0]); - for (size_t i = 1; i < vectors->size(); ++i) { + for (size_t i = 1; i < vectors->size(); ++i) + { vector tempCommon; // Sort the current vector and common result for intersection @@ -113,23 +113,25 @@ static vector* getCommonElements(const vector>* vectors) { *commonElements = tempCommon; // If no common elements left, break early - if (commonElements->empty()) { + if (commonElements->empty()) break; - } } return commonElements; } -static map> findDominators(vector blocks) { +static map> findDominators(vector blocks) +{ map> result; bool changed = true; - while (changed) { + while (changed) + { changed = false; - for (auto currentBlock : blocks) { + for (auto currentBlock : blocks) + { auto pred = currentBlock->getPrev(); auto prevDominators = new vector>(); @@ -139,7 +141,8 @@ static map> findDominators(vector blocks) { auto currentBlockResult = getCommonElements(prevDominators); currentBlockResult->push_back(currentBlock); - if (result.find(currentBlock) == result.end() || !compareVectors(currentBlockResult, &result[currentBlock])) { + if (result.find(currentBlock) == result.end() || !compareVectors(currentBlockResult, &result[currentBlock])) + { result[currentBlock] = *currentBlockResult; changed = true; } @@ -149,42 +152,42 @@ static map> findDominators(vector blocks) { return result; } -static void RenumberBlocks(BBlock* current, int* n, map* res, set* visited) { - if (visited->find(current) != visited->end()) { +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); - } - + for (auto i : nextBlocks) + renumberBlocks(i, n, res, visited); + (*res)[current->getNumber()] = *n; *n -= 1; } -static map> findDominatorBorders(vector& blocks, map& iDominators) { +static map> findDominatorBorders(const vector& blocks, map& iDominators) { map> result; - for (auto block : blocks) { + for (auto& block : blocks) result[block] = *(new vector()); - } - for (auto block : blocks) { - if (block->getPrev().size() > 1) { - for (auto prev : block->getPrev()) { + for (auto& block : blocks) + { + if (block->getPrev().size() > 1) + { + for (auto prev : block->getPrev()) + { auto tmpBlock = prev; auto test = iDominators[block]; auto test2 = iDominators[prev]; - while (tmpBlock != iDominators[block]) { + while (tmpBlock != iDominators[block]) + { result[tmpBlock].push_back(block); tmpBlock = iDominators[tmpBlock]; } @@ -195,82 +198,87 @@ static map> findDominatorBorders(vector& block return result; } -static BBlock* findImmediateDominatorsDfsHelper(BBlock* block, BBlock* currentBlock, BBlock* currentImmediateDominator, vector &visited, map>& dominators) { - if (block == currentBlock) { +static BBlock* findImmediateDominatorsDfsHelper(BBlock* block, BBlock* currentBlock, BBlock* currentImmediateDominator, vector &visited, map>& dominators) +{ + if (block == currentBlock) return currentImmediateDominator; - } - if (find(visited.begin(), visited.end(), currentBlock) != visited.end()) { - return nullptr; - } + 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()) { + if (find(dominators[block].begin(), dominators[block].end(), currentBlock) != dominators[block].end()) currentImmediateDominator = currentBlock; - } - for (auto nextBlock : currentBlock->getNext()) { + for (auto nextBlock : currentBlock->getNext()) + { auto result = findImmediateDominatorsDfsHelper(block, nextBlock, currentImmediateDominator, visited, dominators); - if (result) { + if (result) return result; - } } - return nullptr; + return NULL; } -static map findImmediateDominators1(const map>& dominators, BBlock* entry) { +static map findImmediateDominators1(const map>& dominators, BBlock* entry) +{ map iDom; - for (const auto& pair : dominators) { + for (const auto& pair : dominators) + { BBlock* b = pair.first; - if (b == entry) continue; + if (b == entry) + continue; const auto& doms = pair.second; - BBlock* candidate = nullptr; - for (auto d : doms) { - if (d == b) continue; - bool isImmediate = true; + BBlock* candidate = NULL; + for (auto d : doms) + { + if (d == b) + continue; + + bool isImmediate = true; + for (auto other : doms) + { + if (other == b || other == d) + continue; - for (auto other : doms) { - if (other == b || other == d) continue; const auto& domsOfOther = dominators.at(other); - if (std::find(domsOfOther.begin(), domsOfOther.end(), d) != domsOfOther.end()) { + if (std::find(domsOfOther.begin(), domsOfOther.end(), d) != domsOfOther.end()) + { isImmediate = false; break; } } - if (isImmediate) { + if (isImmediate) + { candidate = d; break; } } - if (candidate) { + if (candidate) iDom[b] = candidate; - } } return iDom; } -static map findImmediateDominators(map>& dominators, BBlock* fistBlock) { +static map findImmediateDominators(map>& dominators, BBlock* fistBlock) +{ map iDominators; - for (const auto& domPair : dominators) { - BBlock* block = domPair.first; - const vector& domBlocks = domPair.second; + for (const auto& [block, domBlocks] : dominators) { vector visited; - if (block == fistBlock) { + if (block == fistBlock) continue; - } iDominators[block] = findImmediateDominatorsDfsHelper(block, fistBlock, fistBlock, visited, dominators); } @@ -278,19 +286,22 @@ static map findImmediateDominators(map getDefForBlock(const BBlock& block) { +static vector getDefForBlock(const BBlock& block) +{ vector def; const auto& instructions = block.getInstructions(); - for (const auto& irBlock : instructions) { - if (irBlock) { + for (const auto& irBlock : instructions) + { + if (irBlock) + { Instruction* instr = irBlock->getInstruction(); - if (instr) { + if (instr) + { BArgument* result = instr->getResult(); - if (result) { + if (result) def.push_back(result); - } } } } @@ -298,31 +309,35 @@ static vector getDefForBlock(const BBlock& block) { return def; } -static pair, map>> getGlobalsAndVarBlocks(vector blocks) { +static pair, map>> getGlobalsAndVarBlocks(const vector& blocks) { set globals; map> varBlocks; - for (auto block : blocks) { + for (auto& block : blocks) + { set def; const auto& instructions = block->getInstructions(); - for (const auto& irBlock : instructions) { - if (irBlock) { + for (const auto& irBlock : instructions) + { + if (irBlock) + { Instruction* instr = irBlock->getInstruction(); - if (instr) { + if (instr) + { auto arg1 = instr->getArg1(); auto arg2 = instr->getArg2(); auto res = instr->getResult(); - if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg1) == def.end()) { + if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg1) == def.end()) globals.insert(arg1); - } - if (arg2 && arg2->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg2) == def.end()) { - globals.insert(arg2); - } - if (res && res->getType() == CFG_ARG_TYPE::VAR) { + if (arg2 && arg2->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg2) == def.end()) + globals.insert(arg2); + + if (res && res->getType() == CFG_ARG_TYPE::VAR) + { def.insert(res); varBlocks[res].insert(block); } @@ -334,23 +349,29 @@ static pair, map>> getGlobalsAndVarBloc return make_pair(globals, varBlocks); } -static void getBlocksWithFiFunctions(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"); - for (auto var : globals) { + for (auto& var : globals) + { auto worklist = varBlocks[var]; set hasFiFunction; - while (!worklist.empty()) { + while (!worklist.empty()) + { auto block = *worklist.begin(); worklist.erase(block); - for (auto dfBlock : dominatorBorders[block]) { - if (hasFiFunction.find(dfBlock) == hasFiFunction.end()) { + for (auto dfBlock : dominatorBorders[block]) + { + if (hasFiFunction.find(dfBlock) == hasFiFunction.end()) + { hasFiFunction.insert(dfBlock); - Instruction* phiInstruction = new Instruction(CFG_OP::F_CALL, new BArgument(*fiFunc), new BArgument(*paramCount), var, dfBlock->getInstructions()[0]->getInstruction()->getOperator()); IR_Block* phiBlock = new IR_Block(phiInstruction); @@ -365,7 +386,8 @@ static void getBlocksWithFiFunctions(vector blocks, set glo //return blocksWithFiFunctions; } -static 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"; @@ -382,43 +404,40 @@ static string ToString(CFG_ARG_TYPE type) { } } -static 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) { + for (size_t i = 0; i < originalBlocks.size(); ++i) blockMapping[originalBlocks[i]] = copiedBlocks[i]; - } - + // Восстанавливаем связи между копиями - for (size_t i = 0; i < originalBlocks.size(); ++i) { + for (size_t i = 0; i < originalBlocks.size(); ++i) + { BBlock* originalBlock = originalBlocks[i]; BBlock* copiedBlock = copiedBlocks[i]; auto prevCopy = copiedBlock->getPrev(); - for (auto j : prevCopy) { + for (auto j : prevCopy) copiedBlock->removePrev(j); - } - + // Копируем, затем удаляем next связи auto nextCopy = copiedBlock->getNext(); - for (auto j : nextCopy) { + for (auto j : nextCopy) copiedBlock->removeNext(j); - } - + // Восстанавливаем связи succ (следующих блоков) - for (auto* succ : originalBlock->getNext()) { + for (auto* succ : originalBlock->getNext()) copiedBlock->addNext(blockMapping[succ]); - } - + // Восстанавливаем связи prev (предыдущих блоков) - for (auto* prev : originalBlock->getPrev()) { + for (auto* prev : originalBlock->getPrev()) copiedBlock->addPrev(blockMapping[prev]); - } } } -static 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()]++; @@ -427,48 +446,57 @@ static BArgument* NewName(BArgument* var, map& counter, map& counter, map>& stack) { - for (auto irBlock : block->getInstructions()) { +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) { - instruction->setResult(NewName(instruction->getResult(), counter, stack, instruction->getNumber())); + if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL && + instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL) + { + instruction->setResult(newName(instruction->getResult(), counter, stack, instruction->getNumber())); } } } -static void RenameInstructionVars(BBlock* block, map& counter, map>& stack) { - for (auto irBlock : block->getInstructions()) { +static void renameInstructionVars(BBlock* block, map& counter, map>& stack) +{ + for (auto irBlock : block->getInstructions()) + { auto instruction = irBlock->getInstruction(); - if (instruction->getArg1() != nullptr && instruction->getArg1()->getType() == CFG_ARG_TYPE::VAR) { + if (instruction->getArg1() != NULL && instruction->getArg1()->getType() == CFG_ARG_TYPE::VAR) instruction->setArg1(stack[instruction->getArg1()->getValue()].top()); - } - if (instruction->getArg2() != nullptr && instruction->getArg2()->getType() == CFG_ARG_TYPE::VAR) { + if (instruction->getArg2() != NULL && instruction->getArg2()->getType() == CFG_ARG_TYPE::VAR) instruction->setArg2(stack[instruction->getArg2()->getValue()].top()); - } - if (instruction->getResult() != nullptr && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR) { - instruction->setResult(NewName(instruction->getResult(), counter, stack, instruction->getNumber())); - } + if (instruction->getResult() != NULL && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR) + instruction->setResult(newName(instruction->getResult(), counter, stack, instruction->getNumber())); } } -static void RenameFiFunctionArgsVar(BBlock* block, 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++) { + + for (auto i = 0; i < size; i++) + { auto irBlock = instructions[i]; auto instruction = irBlock->getInstruction(); - if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != nullptr && instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != nullptr && instruction->getArg2() != nullptr) { - + if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL && + instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL && + instruction->getArg2() != NULL) + { Instruction* paramInstruction; - if (stack[instruction->getResult()->getValue()].size() > 0) { + 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())); paramInstruction = new Instruction(CFG_OP::PARAM, tmp); } - else { + else + { BArgument* tmp = new BArgument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1"); paramInstruction = new Instruction(CFG_OP::PARAM, tmp); } @@ -482,67 +510,63 @@ static void RenameFiFunctionArgsVar(BBlock* block, map } } -static vector findBlocksWithValue(map& iDominators, BBlock* x) { +static vector findBlocksWithValue(map& iDominators, BBlock* x) +{ vector result; // Проходим по всем элементам map - for (auto& pair : iDominators) { + for (auto& pair : iDominators) // Если значение равно x, добавляем ключ в результат - if (pair.second == x) { + if (pair.second == x) result.push_back(pair.first); - } - } return result; } -static 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); + renameFiFunctionResultVar(block, counter, stack); + renameInstructionVars(block, counter, stack); - RenameInstructionVars(block, counter, stack); + for (auto* successor : block->getNext()) + renameFiFunctionArgsVar(successor, stack); - for (auto* successor : block->getNext()) { - RenameFiFunctionArgsVar(successor, stack); - } + for (auto* child : findBlocksWithValue(iDominators, block)) + renameIR(child, iDominators, counter, stack); - for (auto* child : findBlocksWithValue(iDominators, block)) { - RenameIR(child, iDominators, counter, stack); - } - - for (auto& irBlock : block->getInstructions()) { + for (auto& irBlock : block->getInstructions()) + { auto instruction = irBlock->getInstruction(); - if (instruction->getResult() != nullptr && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR) { + if (instruction->getResult() != NULL && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR) + { string varName = instruction->getResult()->getValue(); stack[varName].pop(); } } - for (auto& irBlock : block->getInstructions()) { + 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) { + if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL && + instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL) + { string varName = instruction->getResult()->getValue(); stack[varName].pop(); } } } -void buildIRSSAForm(map> fullIR, map>* result) { - - for (auto item : fullIR) { - - auto funcinfo = item.first; - auto funcIRConst = item.second; - - cout << "Testing " << item.first->funcName << endl; - +void buildIRSSAForm(const map>& fullIR, + map>& result) { + for (auto& [funcinfo, funcIRConst]: fullIR) { + cout << "Testing " << funcinfo->funcName << endl; vector funcIR; - for (auto i : funcIRConst) { + for (auto i : funcIRConst) funcIR.push_back(new BBlock(*i)); - } + restoreConnections(funcIRConst, funcIR); for (auto i : funcIR) { @@ -571,7 +595,6 @@ void buildIRSSAForm(map> fullIR, mapgetNumber() << endl; for (auto j : i.second) { @@ -581,7 +604,6 @@ void buildIRSSAForm(map> fullIR, map> fullIR, map count; map> varStack; - for (auto var : globals) { + for (auto var : globals) + { count[var->getValue()] = 0; stack tmp; @@ -615,7 +638,7 @@ void buildIRSSAForm(map> fullIR, mapgetValue()] = tmp; } - RenameIR(funcIR[0], iDominators, count, varStack); + renameIR(funcIR[0], iDominators, count, varStack); for (auto i : funcIR) { //printBlock(i); @@ -625,6 +648,6 @@ void buildIRSSAForm(map> fullIR, map> fullIR, std::map>* result); \ No newline at end of file +void buildIRSSAForm(const std::map>& fullIR, std::map>& result); \ No newline at end of file diff --git a/src/LoopAnalyzer/implicit_loops_analyzer.cpp b/src/LoopAnalyzer/implicit_loops_analyzer.cpp index ba516e6..c89c658 100644 --- a/src/LoopAnalyzer/implicit_loops_analyzer.cpp +++ b/src/LoopAnalyzer/implicit_loops_analyzer.cpp @@ -21,38 +21,37 @@ 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; +static void dfs(SAPFOR::BasicBlock* block, map& visit, vector>& startAndEnd, SAPFOR::BasicBlock* prev) { + if (!block) + return; - if (visit[block->getNumber()] == VISITED) { + if (visit[block->getNumber()] == VISITED) + { cout << "error"; return; } - if (visit[block->getNumber()] == VISITING) { + 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()) { + 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()) @@ -60,53 +59,59 @@ static void printBlock(SAPFOR::BasicBlock* block) { string resValue = ""; string arg1Value = ""; string arg2Value = ""; - if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + if (i->getInstruction()->getResult() != NULL && 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) { + + if (i->getInstruction()->getArg1() != NULL && 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) { + + if (i->getInstruction()->getArg2() != NULL && 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) { + if (i->getInstruction()->getResult() != NULL && i->getInstruction()->getResult()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) + i->getInstruction()->getResult()->setValue(resValue); + + if (i->getInstruction()->getArg1() != NULL && 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) { + + if (i->getInstruction()->getArg2() != NULL && 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) { +static void getLoopBody(SAPFOR::BasicBlock* loopHeader, const set& loopExits, std::vector& loopBody) +{ 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)) { - stack.push(succ); - } + for (auto succ : block->getNext()) + { + if (loopExits.count(succ)) + continue; + + if (!visited.count(succ)) + stack.push(succ); } } @@ -114,29 +119,27 @@ void getLoopBody(SAPFOR::BasicBlock* loopHeader, const set& std::stack 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); - } - } } -set findRegisterSourceVariables(const std::vector& blocks, SAPFOR::Argument* var) +static set findRegisterSourceVariables(const std::vector& blocks, SAPFOR::Argument* var) { set result; set visited; @@ -159,7 +162,8 @@ set findRegisterSourceVariables(const std::vector findRegisterSourceVariables(const std::vectorgetInstructions()) { + for (auto block : blocks) + { + for (auto instrWrapper : block->getInstructions()) + { auto instr = instrWrapper->getInstruction(); if (!instr || instr->getResult() != variable) continue; @@ -177,7 +183,8 @@ set findRegisterSourceVariables(const std::vectorgetArg1(); auto arg2 = instr->getArg2(); - if (isBinaryOp(op) && arg1 && arg2) { + 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) @@ -188,7 +195,8 @@ set findRegisterSourceVariables(const std::vectorgetType() == SAPFOR::CFG_ARG_TYPE::REG) workStack.push(arg2); } - else if (isUnaryOp(op) && arg1) { + 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) @@ -201,7 +209,8 @@ set findRegisterSourceVariables(const std::vector getPhiArguments(SAPFOR::BasicBlock* block, SAPFOR::Instruction* phiInstr) { +static std::vector getPhiArguments(SAPFOR::BasicBlock* block, SAPFOR::Instruction* phiInstr) +{ std::vector result; auto& instructions = block->getInstructions(); @@ -209,21 +218,23 @@ std::vector getPhiArguments(SAPFOR::BasicBlock* block, SAP for (int i = instructions.size() - 1; i >= 0; --i) { auto instr = instructions[i]->getInstruction(); - if (collecting) { - if (instr->getOperation() == SAPFOR::CFG_OP::PARAM) { + if (collecting) + { + if (instr->getOperation() == SAPFOR::CFG_OP::PARAM) + { auto arg = instr->getArg1(); - if (arg) { - result.push_back(instr); - } - } - else { - break; + if (arg) + result.push_back(instr); } + else + break; } - if (!instr) continue; + if (!instr) + continue; - if (instr == phiInstr) { + if (instr == phiInstr) + { collecting = true; continue; } @@ -233,55 +244,64 @@ std::vector getPhiArguments(SAPFOR::BasicBlock* block, SAP return result; } -SAPFOR::BasicBlock* findInstructionBlock(SAPFOR::Instruction* targetInstr, const std::vector& blocks) { - for (auto block : blocks) { - for (auto instrWrapper : block->getInstructions()) { +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) { + if (instr == targetInstr) return block; - } } } - return nullptr; + return NULL; } -SAPFOR::BasicBlock* findInstructionBlockByNumber(int number, const std::vector& blocks) { - for (auto block : blocks) { - for (auto instrWrapper : block->getInstructions()) { +static 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) { + if (instr->getNumber() == number) return block; - } } } - return nullptr; + return NULL; } - -void findInductiveVars(const std::vector& blocks, const std::vector& Loopblocks, SAPFOR::BasicBlock* loopHeader, const set& loopExits) { +static 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()) { + for (auto block : relevantBlocks) + { + for (auto instrWrapper : block->getInstructions()) + { auto instr = instrWrapper->getInstruction(); - if (!instr) continue; + 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) { + 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) { + + if (arg1 && arg1->getType() == SAPFOR::CFG_ARG_TYPE::REG) + { auto foundVariables = findRegisterSourceVariables(blocks, arg1); - for (auto var : foundVariables) { + for (auto var : foundVariables) inductiveVars.insert(var->getValue()); - } } } } @@ -289,70 +309,71 @@ void findInductiveVars(const std::vector& blocks, const std set finalInductiveVars; - for (auto instrWrapper : loopHeader->getInstructions()) { + 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; + 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; + if (!phiRes || !inductiveVars.count(phiRes->getValue())) + continue; auto currentBlock = findInstructionBlock(instr, blocks); - if (!currentBlock) continue; + if (!currentBlock) + continue; auto phiArgs = getPhiArguments(currentBlock, instr); - bool hasInLoopDefinition = false; - for (const auto& argInstr : phiArgs) { - if (!argInstr) continue; + for (const auto& argInstr : phiArgs) + { + if (!argInstr) + continue; int definitionInstrNumber = stoi(argInstr->getArg1()->getValue()); - if (definitionInstrNumber == -1) continue; + if (definitionInstrNumber == -1) + continue; auto phiBlock = findInstructionBlockByNumber(definitionInstrNumber, blocks); - if (!phiBlock) continue; + if (!phiBlock) + continue; - if (std::find(Loopblocks.begin(), Loopblocks.end(), phiBlock) != Loopblocks.end()) { + if (std::find(Loopblocks.begin(), Loopblocks.end(), phiBlock) != Loopblocks.end()) hasInLoopDefinition = true; - } } - if (hasInLoopDefinition) { + if (hasInLoopDefinition) finalInductiveVars.insert(phiRes->getValue()); - } } - for (auto i : finalInductiveVars) { - std::cout << "Confirmed inductive variable: " << i << std::endl; - } + for (auto i : finalInductiveVars) + cout << "Confirmed inductive variable: " << i << endl; - if (finalInductiveVars.empty()) { - std::cout << "No confirmed inductive variables found." << std::endl; - } + if (finalInductiveVars.empty()) + cout << "No confirmed inductive variables found." << endl; } -SAPFOR::Instruction* findInstructionAfterLoop(const std::vector& loopBody) { +static 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)) { + 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()) { + 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; + return NULL; // } void findImplicitLoops(const map>& fullIR_SSA, const char* fileName) @@ -362,7 +383,7 @@ void findImplicitLoops(const map>& fullIR //for (auto j : i.second) // printblock(j); - if (!isEqual(fileName, i.first->fileName)) + if (fileName != i.first->fileName) continue; map visited; @@ -398,7 +419,6 @@ void findImplicitLoops(const map>& fullIR findInductiveVars(i.second, loopBody, header, loopExits); - SAPFOR::Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody); if (instructionAfterLoop == NULL) { @@ -419,24 +439,20 @@ void findImplicitLoops(const map>& fullIR 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; } diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 61d190b..9d7287d 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -1032,10 +1032,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks); } else if (curr_regime == BUILD_IR_SSA_FORM) - { - if (fullIR_SSA.size() == 0) - buildIRSSAForm(fullIR, &fullIR_SSA); - } + buildIRSSAForm(fullIR, fullIR_SSA); else if (curr_regime == FIND_IMPLICIT_LOOPS) findImplicitLoops(fullIR_SSA, file_name); else if (curr_regime == FIND_PRIVATE_ARRAYS)