From d267dc047a1a847639a5e89748ce326501fcec18 Mon Sep 17 00:00:00 2001 From: Dudarenko Date: Thu, 19 Dec 2024 15:37:34 +0300 Subject: [PATCH] WIP: add fi functions and rename vars --- .../Sapfor_2017/_src/CFGraph/CFGraph.cpp | 8 +- .../Sapfor_2017/_src/CFGraph/CFGraph.h | 1 + sapfor/experts/Sapfor_2017/_src/CFGraph/IR.h | 1 + .../Sapfor_2017/_src/CFGraph/IRSSAForm.cpp | 400 +++++++++++++++--- 4 files changed, 347 insertions(+), 63 deletions(-) diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp index b00a2b1..02455d5 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.cpp @@ -56,6 +56,12 @@ void BBlock::addInstruction(IR_Block* item) item->setBasicBlock(this); } +void BBlock::addInstructionInFront(IR_Block* item) +{ + instructions.insert(instructions.begin(), item); + item->setBasicBlock(this); +} + int BBlock::removePrev(BBlock* removed) { auto it = std::remove(prev.begin(), prev.end(), removed); @@ -512,7 +518,7 @@ static int buildReachingDefs(const vector& CFG, const FuncInfo* currF, return iter; } -//KosarajuSharir algorithm +//Kosaraju�Sharir algorithm static vector getStronglyConnectedComps(vector>& g) { // 1. For each vertex u of the graph, mark u as unvisited. Let l be empty. auto size = g.size(); diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h index 319b420..3ea24d3 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/CFGraph.h @@ -39,6 +39,7 @@ namespace SAPFOR BasicBlock(IR_Block* item); BasicBlock(const BasicBlock& copyFrom); + void addInstructionInFront(IR_Block* item); void addInstruction(IR_Block* item); void addPrev(BasicBlock* prev_) { prev.push_back(prev_); } void addNext(BasicBlock* next_) { next.push_back(next_); } diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/IR.h b/sapfor/experts/Sapfor_2017/_src/CFGraph/IR.h index 2077177..c3c51a2 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/IR.h +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/IR.h @@ -42,6 +42,7 @@ namespace SAPFOR Argument() : number(lastNumArg++), type(CFG_ARG_TYPE::NONE), value(""), mType(CFG_MEM_TYPE::NONE_) { } Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType) : number(lastNumArg++), type(type), mType(mType), value("") { } Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value) : number(lastNumArg++), type(type), mType(mType), value(value) { } + Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value, int num) : number(num), type(type), mType(mType), value(value) { } Argument(CFG_ARG_TYPE type, const std::string& value) : number(lastNumArg++), type(type), mType(CFG_MEM_TYPE::NONE_), value(value) { if (type != CFG_ARG_TYPE::INSTR && type == CFG_ARG_TYPE::LAB && diff --git a/sapfor/experts/Sapfor_2017/_src/CFGraph/IRSSAForm.cpp b/sapfor/experts/Sapfor_2017/_src/CFGraph/IRSSAForm.cpp index f8497d7..3832a31 100644 --- a/sapfor/experts/Sapfor_2017/_src/CFGraph/IRSSAForm.cpp +++ b/sapfor/experts/Sapfor_2017/_src/CFGraph/IRSSAForm.cpp @@ -16,15 +16,16 @@ using namespace std; using namespace SAPFOR; typedef SAPFOR::BasicBlock BBlock; +typedef SAPFOR::Argument BArgument; static void printBlock(BBlock* block) { - std::cout << "block - " << block->getNumber() << endl; + cout << "block - " << block->getNumber() << endl; cout << "next -"; for (auto i : block->getNext()) { cout << " " << i->getNumber(); } - /*cout << endl << "prev -"; + cout << endl << "prev -"; for (auto i : block->getPrev()) { cout << " " << i->getNumber(); @@ -34,12 +35,21 @@ static void printBlock(BBlock* block) { for (auto i : block->getInstructions()) { cout << i->getNumber() << " " << i->getInstruction()->dump() << endl; - }*/ + + if (i->getInstruction()->getResult() != nullptr) { + cout << "num - " << i->getInstruction()->getResult()->getNumber() << endl; + } + + /*if (i->getInstruction()->getOperation() == CFG_OP::F_CALL) { + cout << endl; + cout << "arg1 - " << (i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::FUNC ? "1" : "0") << "arg2 - " << (i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::CONST ? "1" : "0") << "res - " << i->getInstruction()->getResult() << endl; + }*/ + } cout << endl; } template -static bool compareVectors(const std::vector* vec1, const std::vector* vec2) { +static bool compareVectors(const vector* vec1, const vector* vec2) { if (vec1 == vec2) { return true; } @@ -48,37 +58,37 @@ static bool compareVectors(const std::vector* vec1, const std::vector* vec return false; } - std::vector sortedVec1 = *vec1; - std::vector sortedVec2 = *vec2; + vector sortedVec1 = *vec1; + vector sortedVec2 = *vec2; - std::sort(sortedVec1.begin(), sortedVec1.end()); - std::sort(sortedVec2.begin(), sortedVec2.end()); + sort(sortedVec1.begin(), sortedVec1.end()); + sort(sortedVec2.begin(), sortedVec2.end()); return sortedVec1 == sortedVec2; } template -static std::vector* getCommonElements(const std::vector>* vectors) { +static vector* getCommonElements(const vector>* vectors) { if (!vectors || vectors->empty()) { - return new std::vector(); // Return an empty vector if input is null or empty + return new vector(); // Return an empty vector if input is null or empty } // Start with the first vector - std::vector* commonElements = new std::vector((*vectors)[0]); + vector* commonElements = new vector((*vectors)[0]); for (size_t i = 1; i < vectors->size(); ++i) { - std::vector tempCommon; + vector tempCommon; // Sort the current vector and common result for intersection - std::vector sortedVec = (*vectors)[i]; - std::sort(commonElements->begin(), commonElements->end()); - std::sort(sortedVec.begin(), sortedVec.end()); + vector sortedVec = (*vectors)[i]; + sort(commonElements->begin(), commonElements->end()); + sort(sortedVec.begin(), sortedVec.end()); // Find the intersection - std::set_intersection( + set_intersection( commonElements->begin(), commonElements->end(), sortedVec.begin(), sortedVec.end(), - std::back_inserter(tempCommon) + back_inserter(tempCommon) ); // Update common result @@ -128,9 +138,9 @@ static void RenumberBlocks(BBlock* current, int* n, map* res, setinsert(current); - std::vector nextBlocks = current->getNext(); + vector nextBlocks = current->getNext(); - std::sort(nextBlocks.begin(), nextBlocks.end(), [](BBlock* a, BBlock* b) { + sort(nextBlocks.begin(), nextBlocks.end(), [](BBlock* a, BBlock* b) { return a->getInstructions()[0]->getInstruction()->getOperator()->lineNumber() > b->getInstructions()[0]->getInstruction()->getOperator()->lineNumber(); }); @@ -155,11 +165,6 @@ static map> findDominatorBorders(vector& block auto tmpBlock = prev; while (tmpBlock != iDominators[block]) { - - if (tmpBlock->getNumber() == 8 && block->getNumber() == 8) { - cout << "okjdwebnfklwedhfgklhwdgklvhvbklwdfhgvlhbwsdfgvlikbdflwkgb" << endl << prev->getNumber() << endl; - } - result[tmpBlock].push_back(block); tmpBlock = iDominators[tmpBlock]; } @@ -170,15 +175,278 @@ static map> findDominatorBorders(vector& block return result; } +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; + } + + 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 nullptr; +} + +static map findImmediateDominators(map>& dominators, BBlock* fistBlock) { + map iDominators; + + for (const auto& domPair : dominators) { + BBlock* block = domPair.first; + const vector& domBlocks = domPair.second; + 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(vector blocks) { + set globals; + map> varBlocks; + + for (auto block : blocks) { + set def; + const auto& instructions = block->getInstructions(); + + for (const auto& irBlock : instructions) { + if (irBlock) { + Instruction* instr = irBlock->getInstruction(); + + 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()) { + 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) { + def.insert(res); + varBlocks[res].insert(block); + } + } + } + } + } + + return make_pair(globals, varBlocks); +} + +static vector getBlocksWithFiFunctions(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) { + auto worklist = varBlocks[var]; + set hasFiFunction; + + while (!worklist.empty()) { + auto block = *worklist.begin(); + worklist.erase(block); + + for (auto dfBlock : dominatorBorders[block]) { + if (hasFiFunction.find(dfBlock) == hasFiFunction.end()) { + hasFiFunction.insert(dfBlock); + + Instruction* phiInstruction = new Instruction(CFG_OP::F_CALL, fiFunc, paramCount, var); + + IR_Block* phiBlock = new IR_Block(phiInstruction); + dfBlock->addInstructionInFront(phiBlock); + + blocksWithFiFunctions.push_back(dfBlock); + } + } + } + } + + return blocksWithFiFunctions; +} + + + + +string ToString(CFG_ARG_TYPE type) { + 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"; + } +} + +void restoreConnections(const vector& originalBlocks, vector& copiedBlocks) { + // Создаем отображение оригинальных блоков в их копии + 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]; + + for (auto j : copiedBlock->getPrev()) { + copiedBlock->removePrev(j); + } + for (auto j : copiedBlock->getNext()) { + copiedBlock->removeNext(j); + } + + // Восстанавливаем связи succ (следующих блоков) + for (auto* succ : originalBlock->getNext()) { + copiedBlock->addNext(blockMapping[succ]); + } + + // Восстанавливаем связи prev (предыдущих блоков) + for (auto* prev : originalBlock->getPrev()) { + copiedBlock->addPrev(blockMapping[prev]); + } + } +} + + +BArgument* NewName(BArgument* var, map& counter, map>& stack) { + int index = counter[var->getValue()]; + counter[var->getValue()]++; + + BArgument* newName = new BArgument(var->getType(), var->getMemType(), var->getValue(), index + 1); + stack[var->getValue()].push(newName); + return newName; +} + +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)); + } + } +} + +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) { + instruction->setArg1(stack[instruction->getArg1()->getValue()].top()); + } + + if (instruction->getArg2() != nullptr && 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)); + } + } +} + + +void RenameIR(BBlock* block, map>& dominatorTree, map& counter, map>& stack) { + + RenameFiFunctionResultVar(block, counter, stack); + + RenameInstructionVars(block, counter, stack); + + for (auto* successor : block->getNext()) { + + } + + for (auto* child : dominatorTree.at(block)) { + RenameIR(child, dominatorTree, counter, stack); + } + + // Очистка стека после обработки инструкций + for (auto& irBlock : block->getInstructions()) { + auto instruction = irBlock->getInstruction(); + if (instruction->getResult() != nullptr && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR) { + string varName = instruction->getResult()->getValue(); + stack[varName].pop(); + } + } + + // Очистка стека после φ-функций + 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) { + string varName = instruction->getResult()->getValue(); + stack[varName].pop(); + } + } +} + + + + + map> buildIRSSAForm(map> fullIR) { map> result; for (auto item : fullIR) { auto funcinfo = item.first; - auto funcIR = item.second; + auto funcIRConst = item.second; - auto funcResult = new vector(); + vector funcIR; + vector funcResult; + + for (auto i : funcIRConst) { + funcIR.push_back(new BBlock(*i)); + } + restoreConnections(funcIRConst, funcIR); for (auto i : funcIR) { printBlock(i); @@ -197,41 +465,7 @@ map> buildIRSSAForm(map> f cout << endl; } - map numbers; - int n = funcIR.size() - 1; - RenumberBlocks(funcIR[0], &n, &numbers, new set); - - for (auto i : numbers) { - cout << i.first << " " << i.second << endl; - } - - map iDominators; - - for (const auto& domPair : dominators) { - BBlock* block = domPair.first; - const std::vector& domBlocks = domPair.second; - - std::vector domNumbers; - for (BBlock* domBlock : domBlocks) { - int number = numbers[domBlock->getNumber()]; - domNumbers.push_back(number); - } - - std::sort(domNumbers.begin(), domNumbers.end()); - - if (domNumbers.size() < 2) { - continue; - } - - int secondLargestNumber = *(std::prev(domNumbers.end(), 2)); - - for (BBlock* domBlock : domBlocks) { - if (numbers[domBlock->getNumber()] == secondLargestNumber) { - iDominators[block] = domBlock; - break; - } - } - } + auto iDominators = findImmediateDominators(dominators, funcIR[0]); for (auto i : iDominators) { cout << "block - " << i.first->getNumber() << endl; @@ -251,7 +485,49 @@ map> buildIRSSAForm(map> f cout << endl; } - result[funcinfo] = *funcResult; + 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; + + funcResult = getBlocksWithFiFunctions(funcIR, globals, varBlocks, dominatorBorders); + + map count; + map> varStack; + + for (auto var : globals) { + count[var->getValue()] = 0; + + stack tmp; + varStack[var->getValue()] = tmp; + } + + RenameIR(funcIR[0], dominatorBorders, count, varStack); + + + for (auto i : funcIR) { + printBlock(i); + } + cout << endl << endl << endl << endl << endl; + for (auto i : funcIRConst) { + printBlock(i); + } + + + result[funcinfo] = funcResult; } return result;