Compare commits
2 Commits
1522dc7f27
...
d267dc047a
| Author | SHA1 | Date | |
|---|---|---|---|
| d267dc047a | |||
| 12a810ad35 |
@@ -56,6 +56,12 @@ void BBlock::addInstruction(IR_Block* item)
|
|||||||
item->setBasicBlock(this);
|
item->setBasicBlock(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BBlock::addInstructionInFront(IR_Block* item)
|
||||||
|
{
|
||||||
|
instructions.insert(instructions.begin(), item);
|
||||||
|
item->setBasicBlock(this);
|
||||||
|
}
|
||||||
|
|
||||||
int BBlock::removePrev(BBlock* removed)
|
int BBlock::removePrev(BBlock* removed)
|
||||||
{
|
{
|
||||||
auto it = std::remove(prev.begin(), prev.end(), removed);
|
auto it = std::remove(prev.begin(), prev.end(), removed);
|
||||||
@@ -512,7 +518,7 @@ static int buildReachingDefs(const vector<BBlock*>& CFG, const FuncInfo* currF,
|
|||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Kosaraju<6A>Sharir algorithm
|
//Kosaraju<6A>Sharir algorithm
|
||||||
static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) {
|
static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) {
|
||||||
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||||
auto size = g.size();
|
auto size = g.size();
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace SAPFOR
|
|||||||
BasicBlock(IR_Block* item);
|
BasicBlock(IR_Block* item);
|
||||||
BasicBlock(const BasicBlock& copyFrom);
|
BasicBlock(const BasicBlock& copyFrom);
|
||||||
|
|
||||||
|
void addInstructionInFront(IR_Block* item);
|
||||||
void addInstruction(IR_Block* item);
|
void addInstruction(IR_Block* item);
|
||||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
|
|||||||
if (ex)
|
if (ex)
|
||||||
{
|
{
|
||||||
const int var = ex->variant();
|
const int var = ex->variant();
|
||||||
if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // обращение к переменной
|
||||||
{
|
{
|
||||||
if (var == CONST_REF)
|
if (var == CONST_REF)
|
||||||
{
|
{
|
||||||
@@ -1572,7 +1572,7 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
|
|||||||
else
|
else
|
||||||
findReturn(0, blocks.size(), blocks, blocks.back()->getNumber());
|
findReturn(0, blocks.size(), blocks, blocks.back()->getNumber());
|
||||||
|
|
||||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> GOTO <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// добавление связей по GOTO и переходам
|
||||||
for (int z = 0; z < blocks.size(); ++z)
|
for (int z = 0; z < blocks.size(); ++z)
|
||||||
{
|
{
|
||||||
auto op = blocks[z]->getInstruction()->getOperation();
|
auto op = blocks[z]->getInstruction()->getOperation();
|
||||||
@@ -1592,7 +1592,7 @@ vector<IR_Block*> buildIR(SgStatement* function, const FuncInfo* func, const vec
|
|||||||
|
|
||||||
blocks[z]->setJump(it->second);
|
blocks[z]->setJump(it->second);
|
||||||
|
|
||||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// заменим метку на номер инструкции
|
||||||
arg->setValue(to_string(it->second->getNumber()));
|
arg->setValue(to_string(it->second->getNumber()));
|
||||||
arg->setType(CFG_ARG_TYPE::INSTR);
|
arg->setType(CFG_ARG_TYPE::INSTR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ namespace SAPFOR
|
|||||||
Argument() : number(lastNumArg++), type(CFG_ARG_TYPE::NONE), value(""), mType(CFG_MEM_TYPE::NONE_) { }
|
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) : 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) : 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)
|
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 &&
|
if (type != CFG_ARG_TYPE::INSTR && type == CFG_ARG_TYPE::LAB &&
|
||||||
|
|||||||
@@ -16,15 +16,16 @@ using namespace std;
|
|||||||
using namespace SAPFOR;
|
using namespace SAPFOR;
|
||||||
|
|
||||||
typedef SAPFOR::BasicBlock BBlock;
|
typedef SAPFOR::BasicBlock BBlock;
|
||||||
|
typedef SAPFOR::Argument BArgument;
|
||||||
|
|
||||||
static void printBlock(BBlock* block) {
|
static void printBlock(BBlock* block) {
|
||||||
std::cout << "block - " << block->getNumber() << endl;
|
cout << "block - " << block->getNumber() << endl;
|
||||||
cout << "next -";
|
cout << "next -";
|
||||||
for (auto i : block->getNext())
|
for (auto i : block->getNext())
|
||||||
{
|
{
|
||||||
cout << " " << i->getNumber();
|
cout << " " << i->getNumber();
|
||||||
}
|
}
|
||||||
/*cout << endl << "prev -";
|
cout << endl << "prev -";
|
||||||
for (auto i : block->getPrev())
|
for (auto i : block->getPrev())
|
||||||
{
|
{
|
||||||
cout << " " << i->getNumber();
|
cout << " " << i->getNumber();
|
||||||
@@ -34,12 +35,21 @@ static void printBlock(BBlock* block) {
|
|||||||
for (auto i : block->getInstructions())
|
for (auto i : block->getInstructions())
|
||||||
{
|
{
|
||||||
cout << i->getNumber() << " " << i->getInstruction()->dump() << endl;
|
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;
|
cout << endl;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static bool compareVectors(const std::vector<T>* vec1, const std::vector<T>* vec2) {
|
static bool compareVectors(const vector<T>* vec1, const vector<T>* vec2) {
|
||||||
if (vec1 == vec2) {
|
if (vec1 == vec2) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -48,37 +58,37 @@ static bool compareVectors(const std::vector<T>* vec1, const std::vector<T>* vec
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<T> sortedVec1 = *vec1;
|
vector<T> sortedVec1 = *vec1;
|
||||||
std::vector<T> sortedVec2 = *vec2;
|
vector<T> sortedVec2 = *vec2;
|
||||||
|
|
||||||
std::sort(sortedVec1.begin(), sortedVec1.end());
|
sort(sortedVec1.begin(), sortedVec1.end());
|
||||||
std::sort(sortedVec2.begin(), sortedVec2.end());
|
sort(sortedVec2.begin(), sortedVec2.end());
|
||||||
|
|
||||||
return sortedVec1 == sortedVec2;
|
return sortedVec1 == sortedVec2;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::vector<T>* getCommonElements(const std::vector<std::vector<T>>* vectors) {
|
static vector<T>* getCommonElements(const vector<vector<T>>* vectors) {
|
||||||
if (!vectors || vectors->empty()) {
|
if (!vectors || vectors->empty()) {
|
||||||
return new std::vector<T>(); // Return an empty vector if input is null or empty
|
return new vector<T>(); // Return an empty vector if input is null or empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start with the first vector
|
// Start with the first vector
|
||||||
std::vector<T>* commonElements = new std::vector<T>((*vectors)[0]);
|
vector<T>* commonElements = new vector<T>((*vectors)[0]);
|
||||||
|
|
||||||
for (size_t i = 1; i < vectors->size(); ++i) {
|
for (size_t i = 1; i < vectors->size(); ++i) {
|
||||||
std::vector<T> tempCommon;
|
vector<T> tempCommon;
|
||||||
|
|
||||||
// Sort the current vector and common result for intersection
|
// Sort the current vector and common result for intersection
|
||||||
std::vector<T> sortedVec = (*vectors)[i];
|
vector<T> sortedVec = (*vectors)[i];
|
||||||
std::sort(commonElements->begin(), commonElements->end());
|
sort(commonElements->begin(), commonElements->end());
|
||||||
std::sort(sortedVec.begin(), sortedVec.end());
|
sort(sortedVec.begin(), sortedVec.end());
|
||||||
|
|
||||||
// Find the intersection
|
// Find the intersection
|
||||||
std::set_intersection(
|
set_intersection(
|
||||||
commonElements->begin(), commonElements->end(),
|
commonElements->begin(), commonElements->end(),
|
||||||
sortedVec.begin(), sortedVec.end(),
|
sortedVec.begin(), sortedVec.end(),
|
||||||
std::back_inserter(tempCommon)
|
back_inserter(tempCommon)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update common result
|
// Update common result
|
||||||
@@ -128,9 +138,9 @@ static void RenumberBlocks(BBlock* current, int* n, map<int, int>* res, set<BBlo
|
|||||||
|
|
||||||
visited->insert(current);
|
visited->insert(current);
|
||||||
|
|
||||||
std::vector<BBlock*> nextBlocks = current->getNext();
|
vector<BBlock*> 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();
|
return a->getInstructions()[0]->getInstruction()->getOperator()->lineNumber() > b->getInstructions()[0]->getInstruction()->getOperator()->lineNumber();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -155,11 +165,6 @@ static map<BBlock*, vector<BBlock*>> findDominatorBorders(vector<BBlock*>& block
|
|||||||
auto tmpBlock = prev;
|
auto tmpBlock = prev;
|
||||||
|
|
||||||
while (tmpBlock != iDominators[block]) {
|
while (tmpBlock != iDominators[block]) {
|
||||||
|
|
||||||
if (tmpBlock->getNumber() == 8 && block->getNumber() == 8) {
|
|
||||||
cout << "okjdwebnfklwedhfgklhwdgklvhvbklwdfhgvlhbwsdfgvlikbdflwkgb" << endl << prev->getNumber() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
result[tmpBlock].push_back(block);
|
result[tmpBlock].push_back(block);
|
||||||
tmpBlock = iDominators[tmpBlock];
|
tmpBlock = iDominators[tmpBlock];
|
||||||
}
|
}
|
||||||
@@ -170,15 +175,278 @@ static map<BBlock*, vector<BBlock*>> findDominatorBorders(vector<BBlock*>& block
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BBlock* findImmediateDominatorsDfsHelper(BBlock* block, BBlock* currentBlock, BBlock* currentImmediateDominator, vector<BBlock*> &visited, map<BBlock*, vector<BBlock*>>& 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<BBlock*, BBlock*> findImmediateDominators(map<BBlock*, vector<BBlock*>>& dominators, BBlock* fistBlock) {
|
||||||
|
map<BBlock*, BBlock*> iDominators;
|
||||||
|
|
||||||
|
for (const auto& domPair : dominators) {
|
||||||
|
BBlock* block = domPair.first;
|
||||||
|
const vector<BBlock*>& domBlocks = domPair.second;
|
||||||
|
vector<BBlock*> visited;
|
||||||
|
|
||||||
|
if (block == fistBlock) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
iDominators[block] = findImmediateDominatorsDfsHelper(block, fistBlock, fistBlock, visited, dominators);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iDominators;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<BArgument*> getDefForBlock(const BBlock& block) {
|
||||||
|
vector<BArgument*> 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<set<BArgument*>, map<BArgument*, set<BBlock*>>> getGlobalsAndVarBlocks(vector<BBlock*> blocks) {
|
||||||
|
set<BArgument*> globals;
|
||||||
|
map<BArgument*, set<BBlock*>> varBlocks;
|
||||||
|
|
||||||
|
for (auto block : blocks) {
|
||||||
|
set<BArgument*> 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<BBlock*> getBlocksWithFiFunctions(vector<BBlock*> blocks, set<BArgument*> globals, map<BArgument*, set<BBlock*>> varBlocks, map<BBlock*, vector<BBlock*>> dominatorBorders) {
|
||||||
|
vector<BBlock*> 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<BBlock*> 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<BBlock*>& originalBlocks, vector<BBlock*>& copiedBlocks) {
|
||||||
|
// Создаем отображение оригинальных блоков в их копии
|
||||||
|
map<BBlock*, BBlock*> 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<string, int>& counter, map<string, stack<BArgument*>>& 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<string, int>& counter, map<string, stack<BArgument*>>& 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<string, int>& counter, map<string, stack<BArgument*>>& 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<BBlock*, vector<BBlock*>>& dominatorTree, map<string, int>& counter, map<string, stack<BArgument*>>& 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<FuncInfo*, vector<BBlock*>> buildIRSSAForm(map<FuncInfo*, vector<BBlock*>> fullIR) {
|
map<FuncInfo*, vector<BBlock*>> buildIRSSAForm(map<FuncInfo*, vector<BBlock*>> fullIR) {
|
||||||
|
|
||||||
map<FuncInfo*, vector<BBlock*>> result;
|
map<FuncInfo*, vector<BBlock*>> result;
|
||||||
|
|
||||||
for (auto item : fullIR) {
|
for (auto item : fullIR) {
|
||||||
auto funcinfo = item.first;
|
auto funcinfo = item.first;
|
||||||
auto funcIR = item.second;
|
auto funcIRConst = item.second;
|
||||||
|
|
||||||
auto funcResult = new vector<BBlock*>();
|
vector<BBlock*> funcIR;
|
||||||
|
vector<BBlock*> funcResult;
|
||||||
|
|
||||||
|
for (auto i : funcIRConst) {
|
||||||
|
funcIR.push_back(new BBlock(*i));
|
||||||
|
}
|
||||||
|
restoreConnections(funcIRConst, funcIR);
|
||||||
|
|
||||||
for (auto i : funcIR) {
|
for (auto i : funcIR) {
|
||||||
printBlock(i);
|
printBlock(i);
|
||||||
@@ -197,41 +465,7 @@ map<FuncInfo*, vector<BBlock*>> buildIRSSAForm(map<FuncInfo*, vector<BBlock*>> f
|
|||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<int, int> numbers;
|
auto iDominators = findImmediateDominators(dominators, funcIR[0]);
|
||||||
int n = funcIR.size() - 1;
|
|
||||||
RenumberBlocks(funcIR[0], &n, &numbers, new set<BBlock*>);
|
|
||||||
|
|
||||||
for (auto i : numbers) {
|
|
||||||
cout << i.first << " " << i.second << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
map<BBlock*, BBlock*> iDominators;
|
|
||||||
|
|
||||||
for (const auto& domPair : dominators) {
|
|
||||||
BBlock* block = domPair.first;
|
|
||||||
const std::vector<BBlock*>& domBlocks = domPair.second;
|
|
||||||
|
|
||||||
std::vector<int> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto i : iDominators) {
|
for (auto i : iDominators) {
|
||||||
cout << "block - " << i.first->getNumber() << endl;
|
cout << "block - " << i.first->getNumber() << endl;
|
||||||
@@ -251,7 +485,49 @@ map<FuncInfo*, vector<BBlock*>> buildIRSSAForm(map<FuncInfo*, vector<BBlock*>> f
|
|||||||
cout << endl;
|
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<string, int> count;
|
||||||
|
map<string, stack<BArgument*>> varStack;
|
||||||
|
|
||||||
|
for (auto var : globals) {
|
||||||
|
count[var->getValue()] = 0;
|
||||||
|
|
||||||
|
stack<BArgument*> 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;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user