WIP change logic of inductive variables
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "../ExpressionTransform/expr_transform.h"
|
||||
|
||||
#include "dvm.h"
|
||||
#include "IR.h"
|
||||
|
||||
@@ -146,312 +146,89 @@ void getLoopBody(SAPFOR::BasicBlock* loopHeader, const std::set<SAPFOR::BasicBlo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
set<SAPFOR::Argument*> findRegisterSourceVariables(const std::vector<SAPFOR::BasicBlock*>& blocks, SAPFOR::Argument* var) {
|
||||
std::set<SAPFOR::Argument*> result;
|
||||
std::set<SAPFOR::Argument*> visited;
|
||||
std::stack<SAPFOR::Argument*> workStack;
|
||||
workStack.push(var);
|
||||
|
||||
auto isBinaryOp = [](SAPFOR::CFG_OP op) {
|
||||
return op == SAPFOR::CFG_OP::ADD || op == SAPFOR::CFG_OP::SUBT ||
|
||||
op == SAPFOR::CFG_OP::MULT || op == SAPFOR::CFG_OP::DIV ||
|
||||
op == SAPFOR::CFG_OP::POW ||
|
||||
op == SAPFOR::CFG_OP::GE || op == SAPFOR::CFG_OP::LE ||
|
||||
op == SAPFOR::CFG_OP::GT || op == SAPFOR::CFG_OP::LT ||
|
||||
op == SAPFOR::CFG_OP::EQ || op == SAPFOR::CFG_OP::NEQV ||
|
||||
op == SAPFOR::CFG_OP::EQV || op == SAPFOR::CFG_OP::EMPTY ||
|
||||
op == SAPFOR::CFG_OP::OR || op == SAPFOR::CFG_OP::AND;
|
||||
};
|
||||
|
||||
auto isUnaryOp = [](SAPFOR::CFG_OP op) {
|
||||
return op == SAPFOR::CFG_OP::UN_ADD || op == SAPFOR::CFG_OP::UN_MINUS ||
|
||||
op == SAPFOR::CFG_OP::NOT || op == SAPFOR::CFG_OP::ASSIGN;
|
||||
};
|
||||
|
||||
while (!workStack.empty()) {
|
||||
auto variable = workStack.top();
|
||||
workStack.pop();
|
||||
if (!variable || visited.count(variable))
|
||||
continue;
|
||||
|
||||
visited.insert(variable);
|
||||
SAPFOR::Instruction* findDef(const SAPFOR::Argument* arg,
|
||||
const std::vector<SAPFOR::BasicBlock*>& 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 || instr->getResult() != variable)
|
||||
continue;
|
||||
if (!instr) continue;
|
||||
|
||||
auto op = instr->getOperation();
|
||||
auto arg1 = instr->getArg1();
|
||||
auto arg2 = instr->getArg2();
|
||||
auto res = instr->getResult();
|
||||
if (!res) continue;
|
||||
|
||||
if (isBinaryOp(op) && arg1 && arg2) {
|
||||
if (arg1->getType() == CFG_ARG_TYPE::VAR)
|
||||
result.insert(arg1);
|
||||
else if (arg1->getType() == CFG_ARG_TYPE::REG)
|
||||
workStack.push(arg1);
|
||||
|
||||
if (arg2->getType() == CFG_ARG_TYPE::VAR)
|
||||
result.insert(arg2);
|
||||
else if (arg2->getType() == CFG_ARG_TYPE::REG)
|
||||
workStack.push(arg2);
|
||||
}
|
||||
else if (isUnaryOp(op) && arg1) {
|
||||
if (arg1->getType() == CFG_ARG_TYPE::VAR)
|
||||
result.insert(arg1);
|
||||
else if (arg1->getType() == CFG_ARG_TYPE::REG)
|
||||
workStack.push(arg1);
|
||||
}
|
||||
if (res->getValue() == argName) {
|
||||
return instr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<SAPFOR::Instruction*> getPhiArguments(SAPFOR::BasicBlock* block, SAPFOR::Instruction* phiInstr) {
|
||||
std::vector<SAPFOR::Instruction*> result;
|
||||
const SAPFOR::Argument* getBaseSource(const SAPFOR::Argument* arg, const std::vector<SAPFOR::BasicBlock*>& blocks) {
|
||||
while (arg && arg->getType() == CFG_ARG_TYPE::REG) {
|
||||
auto defInstr = findDef(arg, blocks);
|
||||
if (!defInstr) break;
|
||||
auto defOp = defInstr->getOperation();
|
||||
|
||||
auto& instructions = block->getInstructions();
|
||||
bool collecting = false;
|
||||
for (int i = instructions.size() - 1; i >= 0; --i) {
|
||||
auto instr = instructions[i]->getInstruction();
|
||||
|
||||
if (collecting) {
|
||||
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM) {
|
||||
auto arg = instr->getArg1();
|
||||
if (arg) {
|
||||
result.push_back(instr);
|
||||
}
|
||||
if (defOp == CFG_OP::ASSIGN) {
|
||||
arg = defInstr->getArg1();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!instr) continue;
|
||||
|
||||
if (instr == phiInstr) {
|
||||
collecting = true;
|
||||
continue;
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
std::reverse(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
SAPFOR::BasicBlock* findInstructionBlock(SAPFOR::Instruction* targetInstr, const std::vector<SAPFOR::BasicBlock*>& blocks) {
|
||||
for (auto block : blocks) {
|
||||
for (auto instrWrapper : block->getInstructions()) {
|
||||
auto instr = instrWrapper->getInstruction();
|
||||
if (instr == targetInstr) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SAPFOR::BasicBlock* findInstructionBlockByNumber(int number, const std::vector<SAPFOR::BasicBlock*>& blocks) {
|
||||
for (auto block : blocks) {
|
||||
for (auto instrWrapper : block->getInstructions()) {
|
||||
auto instr = instrWrapper->getInstruction();
|
||||
if (instr->getNumber() == number) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
set<SAPFOR::Argument*> findSourceVariablesRecursive(const std::vector<SAPFOR::BasicBlock*>& blocks, SAPFOR::Argument* var) {
|
||||
std::set<SAPFOR::Argument*> result;
|
||||
std::set<SAPFOR::Argument*> visited;
|
||||
std::stack<SAPFOR::Argument*> workStack;
|
||||
workStack.push(var);
|
||||
|
||||
while (!workStack.empty()) {
|
||||
auto variable = workStack.top(); workStack.pop();
|
||||
if (!variable || visited.count(variable)) continue;
|
||||
visited.insert(variable);
|
||||
|
||||
bool foundDefinition = false;
|
||||
for (auto block : blocks) {
|
||||
for (auto instrWrapper : block->getInstructions()) {
|
||||
auto instr = instrWrapper->getInstruction();
|
||||
if (!instr || instr->getResult() != variable) continue;
|
||||
|
||||
foundDefinition = true;
|
||||
auto arg1 = instr->getArg1();
|
||||
auto arg2 = instr->getArg2();
|
||||
if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR) result.insert(arg1);
|
||||
if (arg1 && arg1->getType() == CFG_ARG_TYPE::REG) workStack.push(arg1);
|
||||
if (arg2 && arg2->getType() == CFG_ARG_TYPE::VAR) result.insert(arg2);
|
||||
if (arg2 && arg2->getType() == CFG_ARG_TYPE::REG) workStack.push(arg2);
|
||||
}
|
||||
}
|
||||
if (!foundDefinition) result.insert(variable); // параметр
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Версия findInductiveVars без логов, только финальная статистика
|
||||
|
||||
// Версия findInductiveVars с расширенной поддержкой и анализом цепочек зависимостей через регистры и другие операции
|
||||
|
||||
std::set<std::string> traceRecursiveSources(const std::vector<SAPFOR::BasicBlock*>& blocks, SAPFOR::Argument* arg) {
|
||||
std::set<std::string> result;
|
||||
std::set<SAPFOR::Argument*> visited;
|
||||
std::stack<SAPFOR::Argument*> stack;
|
||||
stack.push(arg);
|
||||
|
||||
while (!stack.empty()) {
|
||||
auto curr = stack.top(); stack.pop();
|
||||
if (!curr || visited.count(curr)) continue;
|
||||
visited.insert(curr);
|
||||
|
||||
if (curr->getType() == CFG_ARG_TYPE::VAR) {
|
||||
result.insert(curr->getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto block : blocks) {
|
||||
for (auto instrWrapper : block->getInstructions()) {
|
||||
auto instr = instrWrapper->getInstruction();
|
||||
if (!instr) continue;
|
||||
if (instr->getResult() != curr) continue;
|
||||
|
||||
auto a1 = instr->getArg1();
|
||||
auto a2 = instr->getArg2();
|
||||
if (a1) stack.push(a1);
|
||||
if (a2) stack.push(a2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Улучшенная версия с трассировкой цепочек регистров до phi-переменных
|
||||
|
||||
std::set<std::string> traceSourcesDeepToPhi(const std::vector<SAPFOR::BasicBlock*>& blocks, SAPFOR::Argument* arg, const std::set<std::string>& phiNames) {
|
||||
std::set<std::string> reachedPhi;
|
||||
std::set<SAPFOR::Argument*> visited;
|
||||
std::stack<SAPFOR::Argument*> stack;
|
||||
stack.push(arg);
|
||||
|
||||
while (!stack.empty()) {
|
||||
auto curr = stack.top(); stack.pop();
|
||||
if (!curr || visited.count(curr)) continue;
|
||||
visited.insert(curr);
|
||||
|
||||
//std::cout << "[DEBUG] visiting "
|
||||
// << (curr->getType() == CFG_ARG_TYPE::VAR ? "VAR" :
|
||||
// curr->getType() == CFG_ARG_TYPE::REG ? "REG" : "OTHER")
|
||||
// << ": ." << curr->getValue() << "." << std::endl;
|
||||
|
||||
if (phiNames.count(curr->getValue())) {
|
||||
//std::cout << "[DEBUG] REACHED phi: ." << curr->getValue() << "." << std::endl;
|
||||
reachedPhi.insert(curr->getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto block : blocks) {
|
||||
for (auto instrWrapper : block->getInstructions()) {
|
||||
auto instr = instrWrapper->getInstruction();
|
||||
if (!instr) continue;
|
||||
if (instr->getResult() != curr) continue;
|
||||
|
||||
auto a1 = instr->getArg1();
|
||||
auto a2 = instr->getArg2();
|
||||
if (a1) stack.push(a1);
|
||||
if (a2) stack.push(a2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return reachedPhi;
|
||||
}
|
||||
|
||||
void findInductiveVars(const std::vector<SAPFOR::BasicBlock*>& blocks,
|
||||
const std::vector<SAPFOR::BasicBlock*>& Loopblocks,
|
||||
SAPFOR::BasicBlock* loopHeader,
|
||||
const std::set<SAPFOR::BasicBlock*>& loopExits) {
|
||||
void findInductiveVars(const std::vector<SAPFOR::BasicBlock*>& Loopblocks, const std::vector<SAPFOR::BasicBlock*>& blocks) {
|
||||
std::set<std::string> inductiveVars;
|
||||
std::set<SAPFOR::BasicBlock*> relevantBlocks = { loopHeader };
|
||||
|
||||
for (auto block : relevantBlocks) {
|
||||
for (auto block : Loopblocks) {
|
||||
for (auto instrWrapper : block->getInstructions()) {
|
||||
auto instr = instrWrapper->getInstruction();
|
||||
if (!instr) continue;
|
||||
|
||||
auto op = instr->getOperation();
|
||||
auto res = instr->getResult();
|
||||
auto arg1 = instr->getArg1();
|
||||
auto arg2 = instr->getArg2();
|
||||
if (!res || res->getType() != SAPFOR::CFG_ARG_TYPE::VAR) continue;
|
||||
|
||||
if (op == CFG_OP::JUMP_IF) {
|
||||
if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR) {
|
||||
inductiveVars.insert(arg1->getValue());
|
||||
while (instr && instr->getOperation() == CFG_OP::ASSIGN) {
|
||||
instr = findDef(instr->getArg1(), blocks);
|
||||
}
|
||||
if (arg1 && arg1->getType() == CFG_ARG_TYPE::REG) {
|
||||
auto foundVariables = findRegisterSourceVariables(blocks, arg1);
|
||||
for (auto var : foundVariables) {
|
||||
inductiveVars.insert(var->getValue());
|
||||
|
||||
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) {
|
||||
ok = true;
|
||||
}
|
||||
else if (res->getValue() == arg2->getValue() &&
|
||||
arg1->getType() == CFG_ARG_TYPE::CONST) {
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
inductiveVars.insert(res->getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inductiveVars.empty()) {
|
||||
std::cout << "No inductive variables found." << std::endl;
|
||||
}
|
||||
else {
|
||||
for (const auto& var : inductiveVars) {
|
||||
std::cout << "Inductive variable: " << var << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> finalInductiveVars;
|
||||
|
||||
for (auto instrWrapper : loopHeader->getInstructions()) {
|
||||
auto instr = instrWrapper->getInstruction();
|
||||
if (!instr || instr->getOperation() != SAPFOR::CFG_OP::F_CALL || !instr->getArg1() || instr->getArg1()->getValue() != "FI_FUNCTION") continue;
|
||||
|
||||
auto phiRes = instr->getResult();
|
||||
if (!phiRes || !inductiveVars.count(phiRes->getValue())) continue;
|
||||
|
||||
auto currentBlock = findInstructionBlock(instr, blocks);
|
||||
if (!currentBlock) continue;
|
||||
|
||||
auto phiArgs = getPhiArguments(currentBlock, instr);
|
||||
|
||||
bool hasInLoopDefinition = false;
|
||||
|
||||
for (const auto& argInstr : phiArgs) {
|
||||
if (!argInstr) continue;
|
||||
|
||||
int definitionInstrNumber = std::stoi(argInstr->getArg1()->getValue());
|
||||
if (definitionInstrNumber == -1) continue;
|
||||
|
||||
auto phiBlock = findInstructionBlockByNumber(definitionInstrNumber, blocks);
|
||||
if (!phiBlock) continue;
|
||||
|
||||
if (std::find(Loopblocks.begin(), Loopblocks.end(), phiBlock) != Loopblocks.end()) {
|
||||
hasInLoopDefinition = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasInLoopDefinition) {
|
||||
finalInductiveVars.insert(phiRes->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& var : finalInductiveVars) {
|
||||
std::cout << "Confirmed inductive variable: " << var << std::endl;
|
||||
}
|
||||
|
||||
if (finalInductiveVars.empty()) {
|
||||
std::cout << "No confirmed inductive variables found." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Instruction* findInstructionAfterLoop(const std::vector<SAPFOR::BasicBlock*>& loopBody) {
|
||||
std::set<SAPFOR::BasicBlock*> loopSet(loopBody.begin(), loopBody.end());
|
||||
@@ -473,7 +250,7 @@ Instruction* findInstructionAfterLoop(const std::vector<SAPFOR::BasicBlock*>& lo
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr; // не нашли
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool isEqual(const char* cstr, const std::string& str) {
|
||||
@@ -494,8 +271,8 @@ void findImplicitLoops(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
|
||||
|| isEqual("decod3.for", i.first->fileName))
|
||||
continue;
|
||||
|
||||
/*if (!isEqual("ddst2.for", i.first->fileName))
|
||||
continue;*/
|
||||
//if (!isEqual("iter3.for", i.first->fileName))
|
||||
// continue;
|
||||
|
||||
map<int, int> visited;
|
||||
for (auto i : i.second)
|
||||
@@ -504,7 +281,7 @@ void findImplicitLoops(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
|
||||
//for (auto j : i.second)
|
||||
// printBlock(j);
|
||||
|
||||
|
||||
//continue;
|
||||
|
||||
//vector<int> visited(i.second.size(), UNVISITED);
|
||||
vector<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> startAndEnd;
|
||||
@@ -535,7 +312,7 @@ void findImplicitLoops(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
|
||||
//}
|
||||
//cout << endl;
|
||||
|
||||
findInductiveVars(i.second, loopBody, header, loopExits);
|
||||
findInductiveVars(loopBody, i.second);
|
||||
|
||||
continue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user