fixed code style, moved dom tree building to IR

This commit is contained in:
ALEXks
2025-05-30 11:34:32 +03:00
parent 4e16638c36
commit d3e8c481d2
11 changed files with 155 additions and 213 deletions

View File

@@ -205,6 +205,8 @@ set(TRANSFORMS
set(CFG src/CFGraph/IR.cpp set(CFG src/CFGraph/IR.cpp
src/CFGraph/IR.h src/CFGraph/IR.h
src/CFGraph/IR_domTree.cpp
src/CFGraph/IR_domTree.h
src/CFGraph/CFGraph.cpp src/CFGraph/CFGraph.cpp
src/CFGraph/CFGraph.h src/CFGraph/CFGraph.h
src/CFGraph/RD_subst.cpp src/CFGraph/RD_subst.cpp

View File

@@ -1149,6 +1149,16 @@ map<FuncInfo*, vector<BBlock*>> buildCFG(const map<string, CommonBlock*>& common
if (settings.withRD) if (settings.withRD)
buildReachingDefs(result, settings); buildReachingDefs(result, settings);
if (settings.withDominators)
{
auto t = high_resolution_clock::now();
for (auto& [func, bblocks] : result)
SAPFOR::buildDominatorTree(bblocks);
auto msec = duration_cast<milliseconds>(high_resolution_clock::now() - t).count();
__spf_print(1, "dominator build time is %.3f sec\n", msec / 1000.);
}
if (SgFile::switchToFile(oldFile) == -1) if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);

View File

@@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include "IR.h" #include "IR.h"
#include "IR_domTree.h"
namespace SAPFOR namespace SAPFOR
{ {
@@ -24,7 +25,7 @@ namespace SAPFOR
std::vector<BasicBlock*> next; std::vector<BasicBlock*> next;
std::vector<BasicBlock*> prev; std::vector<BasicBlock*> prev;
BasicBlock* idom{}; BasicBlock* directDominator = NULL;
//reaching definition //reaching definition
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out; std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
@@ -34,6 +35,7 @@ namespace SAPFOR
bool addLive(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add, bool in); bool addLive(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add, bool in);
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLive(bool in) const; std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLive(bool in) const;
bool removeLive(SAPFOR::Argument* to_remove, bool in); bool removeLive(SAPFOR::Argument* to_remove, bool in);
public: public:
BasicBlock() { num = lastNumBlock++; } BasicBlock() { num = lastNumBlock++; }
BasicBlock(IR_Block* item); BasicBlock(IR_Block* item);
@@ -42,7 +44,7 @@ namespace SAPFOR
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_); }
void setIdom(BasicBlock* idom_) { idom = idom_; } void setDom(BasicBlock* dom) { directDominator = dom; }
int removePrev(BasicBlock* removed); int removePrev(BasicBlock* removed);
int removeNext(BasicBlock* removed); int removeNext(BasicBlock* removed);
@@ -70,7 +72,16 @@ namespace SAPFOR
const std::vector<IR_Block*>& getInstructions() const { return instructions; } const std::vector<IR_Block*>& getInstructions() const { return instructions; }
const std::vector<BasicBlock*>& getNext() const { return next; } const std::vector<BasicBlock*>& getNext() const { return next; }
const std::vector<BasicBlock*>& getPrev() const { return prev; } const std::vector<BasicBlock*>& getPrev() const { return prev; }
BasicBlock* getIdom() const { return idom; } BasicBlock* getDom() const
{
if (!directDominator)
{
__spf_print(1, "%s\n", "the dominator tree was built with an error or was not built at all");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
return directDominator;
}
/* /*
* FOR LIVE ANALYSIS * FOR LIVE ANALYSIS
@@ -107,13 +118,15 @@ namespace SAPFOR
bool withDVM = false; bool withDVM = false;
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
bool withCallFrom = true; bool withCallFrom = true;
bool withDominators = true;
explicit CFG_Settings(int) { } explicit CFG_Settings(int) { }
explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false, explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false, bool withCallFrom = true) : bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false,
bool withCallFrom = true, bool withDominators = true) :
atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF), atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom) withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom), withDominators(withDominators)
{ } { }
}; };
} }

View File

@@ -7,6 +7,7 @@
#include "CFGraph.h" #include "CFGraph.h"
#include "../Utils/CommonBlock.h" #include "../Utils/CommonBlock.h"
#include "../GraphCall/graph_calls.h"
namespace SAPFOR namespace SAPFOR
{ {

35
src/CFGraph/IR_domTree.h Normal file
View File

@@ -0,0 +1,35 @@
#pragma once
#include <vector>
#include <map>
#include <unordered_map>
#include "CFGraph.h"
// Lengauer, Thomas. A fast algorithm for finding dominators in a flowgraph / Thomas Lengauer, Robert Endre Tarjan
// ACM Transactions on Programming Languages and Systems (TOPLAS). <20> 1979. <20> Vol. 1, no. 1. <20> Pp. 121<32>141.
namespace SAPFOR {
class BasicBlock;
class DominatorFinder {
private:
BasicBlock* entry;
std::vector<BasicBlock*> vertices;
std::unordered_map<BasicBlock*, int> dfs_num;
std::vector<int> parent, semi, vertex, ancestor, label;
std::vector<std::vector<int>> bucket;
int n;
void DFS(BasicBlock* v, int parent_num);
void Compress(int v);
int Eval(int v);
void Link(int v, int w);
public:
DominatorFinder(std::vector<BasicBlock*>& blocks);
};
void buildDominatorTree(std::vector<BasicBlock*>& blocks);
}

View File

@@ -1,111 +0,0 @@
#pragma once
#include "vector"
#include "map"
#include "../CFGraph/CFGraph.h"
#include <unordered_map>
using namespace std;
namespace SAPFOR {
class DominatorFinder {
private:
BasicBlock* entry;
std::vector<BasicBlock*> vertices;
std::unordered_map<BasicBlock*, int> dfs_num;
std::vector<int> parent, semi, vertex, ancestor, label;
std::vector<std::vector<int>> bucket;
int n;
void DFS(BasicBlock* v, int parent_num) {
dfs_num[v] = n;
vertex[n] = n;
semi[n] = n;
label[n] = n;
ancestor[n] = -1;
parent[n] = parent_num;
vertices[n++] = v;
for (const auto& w : v->getNext()) {
if (dfs_num[w] == -1) {
DFS(w, dfs_num[v]);
}
}
}
void Compress(int v) {
if (ancestor[ancestor[v]] != -1) {
Compress(ancestor[v]);
if (semi[label[ancestor[v]]] < semi[label[v]])
label[v] = label[ancestor[v]];
ancestor[v] = ancestor[ancestor[v]];
}
}
int Eval(int v) {
if (ancestor[v] == -1) return v;
Compress(v);
return label[v];
}
void Link(int v, int w) {
ancestor[w] = v;
}
public:
DominatorFinder(std::vector<BasicBlock*>& blocks) {
if (blocks.empty()) return;
entry = blocks[0];
n = 0;
for (auto block : blocks) dfs_num[block] = -1;
int max_size = blocks.size();
vertices.resize(max_size);
parent.assign(max_size, -1);
semi.assign(max_size, -1);
vertex.assign(max_size, -1);
ancestor.assign(max_size, -1);
label.assign(max_size, -1);
bucket.resize(max_size);
DFS(entry, -1);
for (int i = n - 1; i > 0; --i) {
int w = vertex[i];
for (BasicBlock* v : vertices[w]->getPrev()) {
int u = Eval(dfs_num[v]);
if (semi[u] < semi[w])
semi[w] = semi[u];
}
bucket[vertex[semi[w]]].push_back(w);
Link(parent[w], w);
for (int v : bucket[parent[w]])
{
int u = Eval(v);
if (semi[u] < semi[v])
vertices[v]->setIdom(vertices[u]);
else
vertices[v]->setIdom(vertices[parent[w]]);
}
bucket[parent[w]].clear();
}
for (int i = 1; i < n; ++i) {
int w = vertex[i];
if (vertices[w]->getIdom() != vertices[vertex[semi[w]]])
vertices[w]->setIdom(vertices[w]->getIdom()->getIdom());
}
entry->setIdom(nullptr);
}
};
void buildDominatorTreeLT(std::vector<BasicBlock*>& blocks) {
DominatorFinder finder(blocks);
}
}

View File

@@ -18,13 +18,27 @@
#include "../GraphCall/graph_calls.h" #include "../GraphCall/graph_calls.h"
#include "../GraphCall/graph_calls_func.h" #include "../GraphCall/graph_calls_func.h"
#include "libSage++.h"
#include "projectParameters.h" #include "projectParameters.h"
#include "domTree.h"
using namespace std; using std::set;
using std::map;
using std::string;
using std::vector;
using std::tuple;
using std::pair;
using std::make_tuple;
using std::find_if;
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt) static map<FuncInfo*, vector<SAPFOR::Instruction*>> call_sites;
enum class MODE
{
BEFORE,
AFTER
};
static tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*>
stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt)
{ {
SgStatement* cur = stmt; SgStatement* cur = stmt;
cur->switchToFile(); cur->switchToFile();
@@ -49,7 +63,8 @@ tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> stmtToIR(const map<F
return { NULL, NULL, NULL }; return { NULL, NULL, NULL };
} }
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> IRByNumber(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, int num) static tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*>
IRByNumber(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, int num)
{ {
if (num < 0) if (num < 0)
return { NULL, NULL, NULL }; return { NULL, NULL, NULL };
@@ -60,30 +75,27 @@ tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> IRByNumber(const map
return make_tuple(func, getInstructionByNumber(byBB->getInstructions(), num), byBB); return make_tuple(func, getInstructionByNumber(byBB->getInstructions(), num), byBB);
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return { NULL, NULL, NULL}; return { NULL, NULL, NULL };
} }
template<typename Iterator> template<typename Iterator>
void processArgument(set<SAPFOR::Argument*>& worklist, static void processArgument(set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* arg, SAPFOR::Argument* arg,
Iterator instr, Iterator instr, Iterator first_instr)
Iterator first_instr)
{ {
if (arg == NULL) if (arg == NULL)
return; return;
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG) if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
extract_vars_from_reg(worklist, arg, instr, first_instr); extract_vars_from_reg(worklist, arg, instr, first_instr);
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR) else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
{
worklist.insert(arg); worklist.insert(arg);
}
} }
template<typename Iterator> template<typename Iterator>
void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist, static void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* reg, SAPFOR::Argument* reg,
Iterator instr, Iterator instr, Iterator first_instr)
Iterator first_instr)
{ {
for (; instr >= first_instr; instr--) for (; instr >= first_instr; instr--)
{ {
@@ -96,21 +108,21 @@ void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
} }
} }
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add, static void lookup_for_vars(set<tuple<SgStatement*, string, MODE>>& where_to_add,
set<SAPFOR::Argument*>& worklist, set<SAPFOR::Argument*>& worklist,
SAPFOR::Instruction* instr, SAPFOR::Instruction* instr,
SAPFOR::BasicBlock* bblock, SAPFOR::BasicBlock* bblock,
FuncInfo* cur_func, FuncInfo* cur_func,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR) const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR)
{ {
while (bblock) while (bblock)
{ {
auto first_instr = bblock->getInstructions().begin(); auto first_instr = bblock->getInstructions().begin();
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) { auto cur_instr = find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == instr; return i->getInstruction() == instr;
}); });
for (; cur_instr >= bblock->getInstructions().begin(); cur_instr--) for (; cur_instr >= bblock->getInstructions().begin(); --cur_instr)
{ {
auto instr = (*cur_instr)->getInstruction(); auto instr = (*cur_instr)->getInstruction();
auto result_arg = instr->getResult(); auto result_arg = instr->getResult();
@@ -123,6 +135,7 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
processArgument(worklist, arg2, cur_instr, first_instr); processArgument(worklist, arg2, cur_instr, first_instr);
worklist.erase(result_arg); worklist.erase(result_arg);
} }
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1)) if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1))
{ {
// skip to F_CALL // skip to F_CALL
@@ -136,7 +149,7 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
auto filename = stmt_before->fileName(); auto filename = stmt_before->fileName();
auto line = stmt_before->lineNumber(); auto line = stmt_before->lineNumber();
auto var_name = arg1->getValue().substr(arg1->getValue().find('%') + 1); auto var_name = arg1->getValue().substr(arg1->getValue().find('%') + 1);
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg1->getValue().c_str(), line, filename); __spf_print(1, "Please specify value of variable %s on line %d of file %s\n", arg1->getValue().c_str(), line, filename);
auto toAdd = make_tuple(stmt_before, var_name, MODE::AFTER); auto toAdd = make_tuple(stmt_before, var_name, MODE::AFTER);
where_to_add.insert(toAdd); where_to_add.insert(toAdd);
worklist.erase(arg1); worklist.erase(arg1);
@@ -159,7 +172,7 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
auto line = stmt_after->lineNumber(); auto line = stmt_after->lineNumber();
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1); auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str()); __spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename); __spf_print(1, "Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE); auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
where_to_add.insert(toAdd); where_to_add.insert(toAdd);
worklist.erase(arg); worklist.erase(arg);
@@ -175,7 +188,8 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
} }
while (bblock && group_by_block.find(bblock) == group_by_block.end()) while (bblock && group_by_block.find(bblock) == group_by_block.end())
bblock = bblock->getIdom(); bblock = bblock->getDom();
if (bblock) if (bblock)
instr = group_by_block[bblock]; instr = group_by_block[bblock];
} }
@@ -189,6 +203,7 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
set<int> found_rd; set<int> found_rd;
if (RD.count(arg)) if (RD.count(arg))
found_rd = RD.at(arg); found_rd = RD.at(arg);
if (found_rd.size() == 0) if (found_rd.size() == 0)
{ {
auto call_instr = call_sites[cur_func].size() ? call_sites[cur_func].front() : NULL; auto call_instr = call_sites[cur_func].size() ? call_sites[cur_func].front() : NULL;
@@ -202,10 +217,10 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
call_instr = call_sites[call_func].size() ? call_sites[call_func].front() : NULL; call_instr = call_sites[call_func].size() ? call_sites[call_func].front() : NULL;
} }
} }
if (found_rd.size() == 1 && *found_rd.begin() == SAPFOR::CFG_VAL::UNINIT) if (found_rd.size() == 1 && *found_rd.begin() == SAPFOR::CFG_VAL::UNINIT)
{
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str()); __spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
} else if (found_rd.size() > 1) else if (found_rd.size() > 1)
{ {
auto first_instr = fullIR.at(cur_func).front()->getInstructions().begin(); auto first_instr = fullIR.at(cur_func).front()->getInstructions().begin();
auto stmt_after = (*first_instr)->getInstruction()->getOperator(); auto stmt_after = (*first_instr)->getInstruction()->getOperator();
@@ -213,7 +228,7 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
auto line = stmt_after->lineNumber(); auto line = stmt_after->lineNumber();
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1); auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str()); __spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename); __spf_print(1, "Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE); auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
where_to_add.insert(toAdd); where_to_add.insert(toAdd);
} }
@@ -221,7 +236,7 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
{ {
auto instr_num = *found_rd.begin(); auto instr_num = *found_rd.begin();
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num); auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
set<SAPFOR::Argument*> new_worklist = {arg}; set<SAPFOR::Argument*> new_worklist = { arg };
lookup_for_vars(where_to_add, new_worklist, instr, bblock, func, fullIR); lookup_for_vars(where_to_add, new_worklist, instr, bblock, func, fullIR);
} }
@@ -236,14 +251,15 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber()); auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
auto first_instr = call_bblock->getInstructions().begin(); auto first_instr = call_bblock->getInstructions().begin();
auto cur_instr = std::find_if(first_instr, call_bblock->getInstructions().end(), [call_instr](SAPFOR::IR_Block* i) { auto cur_instr = find_if(first_instr, call_bblock->getInstructions().end(), [call_instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == call_instr; return i->getInstruction() == call_instr;
}); });
for (auto& arg : worklist) for (auto& arg : worklist)
{ {
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_) if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
{ {
auto param_num= stoi(arg->getValue().substr(arg->getValue().find('%', arg->getValue().find('%') + 1) + 1)); auto param_num = stoi(arg->getValue().substr(arg->getValue().find('%', arg->getValue().find('%') + 1) + 1));
auto param_instr = (cur_instr - (params_num - param_num)); auto param_instr = (cur_instr - (params_num - param_num));
auto param_arg = (*param_instr)->getInstruction()->getArg1(); auto param_arg = (*param_instr)->getInstruction()->getArg1();
processArgument(new_worklist, param_arg, param_instr, first_instr); processArgument(new_worklist, param_arg, param_instr, first_instr);
@@ -254,24 +270,23 @@ void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& wher
} }
void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add, static void handle_single_allocate(set<tuple<SgStatement*, string, MODE>>& where_to_add,
SgStatement* alloc_statement, SgStatement* alloc_statement,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR) const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR)
{ {
auto [func, instr, bblock] = stmtToIR(fullIR, alloc_statement); auto [func, instr, bblock] = stmtToIR(fullIR, alloc_statement);
auto first_instr = bblock->getInstructions().begin(); auto first_instr = bblock->getInstructions().begin();
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) { auto cur_instr = find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == instr; return i->getInstruction() == instr;
}); });
auto alloc_instr = cur_instr; auto alloc_instr = cur_instr;
// skip to F_CALL _ALLOC n // skip to F_CALL _ALLOC n
while ((*alloc_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL || while ((*alloc_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL ||
(*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC") (*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC")
alloc_instr++; alloc_instr++;
auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue()); auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue());
set<SAPFOR::Argument*> worklist; set<SAPFOR::Argument*> worklist;
@@ -281,7 +296,7 @@ void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& wh
auto param_reg = (*param_instr)->getInstruction()->getArg1(); auto param_reg = (*param_instr)->getInstruction()->getArg1();
while ((*param_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::LOAD || while ((*param_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::LOAD ||
(*param_instr)->getInstruction()->getResult() != param_reg) (*param_instr)->getInstruction()->getResult() != param_reg)
param_instr--; param_instr--;
@@ -292,29 +307,29 @@ void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& wh
auto ref_instr = --param_instr; auto ref_instr = --param_instr;
if ((*ref_instr)->getInstruction()->getOperation() == SAPFOR::CFG_OP::RANGE) if ((*ref_instr)->getInstruction()->getOperation() == SAPFOR::CFG_OP::RANGE)
{ {
vector<SAPFOR::Argument*> range_args = {(*ref_instr)->getInstruction()->getArg1(), vector<SAPFOR::Argument*> range_args = { (*ref_instr)->getInstruction()->getArg1(),
(*ref_instr)->getInstruction()->getArg2(), (*ref_instr)->getInstruction()->getArg2(),
(*ref_instr)->getInstruction()->getResult()}; (*ref_instr)->getInstruction()->getResult() };
for (auto& arg : range_args) for (auto& arg : range_args)
processArgument(worklist, arg, ref_instr, first_instr); processArgument(worklist, arg, ref_instr, first_instr);
} else }
else
{ {
auto arg = (*ref_instr)->getInstruction()->getArg1(); auto arg = (*ref_instr)->getInstruction()->getArg1();
processArgument(worklist, arg, ref_instr, first_instr); processArgument(worklist, arg, ref_instr, first_instr);
} }
} }
} }
lookup_for_vars(where_to_add,worklist, instr, bblock, func, fullIR); lookup_for_vars(where_to_add, worklist, instr, bblock, func, fullIR);
} }
void handle_single_loop(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add, static void handle_single_loop(set<tuple<SgStatement*, string, MODE>>& where_to_add,
SgStatement* loop_stmt, SgStatement* loop_stmt,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR) const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR)
{ {
auto [func, instr, bblock] = stmtToIR(fullIR, loop_stmt); auto [func, instr, bblock] = stmtToIR(fullIR, loop_stmt);
auto cur_instr = bblock->getInstructions().end() - 1; auto cur_instr = bblock->getInstructions().end() - 1;
set<SAPFOR::Argument*> worklist; set<SAPFOR::Argument*> worklist;
@@ -323,10 +338,9 @@ void handle_single_loop(std::set<tuple<SgStatement*, std::string, MODE>>& where_
lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, func, fullIR); lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, func, fullIR);
} }
void void findParameters(ResultSet& foundParameters,
findParameters(ResultSet& foundParameters, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR,
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR, const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
{ {
set<tuple<SgStatement*, string, MODE>> where_to_add; set<tuple<SgStatement*, string, MODE>> where_to_add;
@@ -337,6 +351,7 @@ findParameters(ResultSet& foundParameters,
for (auto& [func, bblocks] : fullIR) for (auto& [func, bblocks] : fullIR)
{ {
for (const auto& block : bblocks) for (const auto& block : bblocks)
{
for (const auto& ir_block : block->getInstructions()) for (const auto& ir_block : block->getInstructions())
{ {
auto instr = ir_block->getInstruction(); auto instr = ir_block->getInstruction();
@@ -349,32 +364,37 @@ findParameters(ResultSet& foundParameters,
call_sites[func_info->second].push_back(instr); call_sites[func_info->second].push_back(instr);
} }
} }
}
SAPFOR::buildDominatorTreeLT(bblocks);
} }
std::set<SgStatement*> alloc_statements; set<SgStatement*> alloc_statements;
for (const auto& [func, bblocks] : fullIR) for (const auto& [func, bblocks] : fullIR)
{
for (const auto& block : bblocks) for (const auto& block : bblocks)
{
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr) for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
{ {
auto op = (*instr)->getInstruction()->getOperator(); auto op = (*instr)->getInstruction()->getOperator();
if (op && op->variant() == ALLOCATE_STMT) { if (op && op->variant() == ALLOCATE_STMT)
alloc_statements.insert(op); alloc_statements.insert(op);
}
} }
}
}
set<SgStatement*> for_statements; set<SgStatement*> for_statements;
// Find all FOR statements in the program // Find all FOR statements in the program
for (const auto& [func, bblocks] : fullIR) for (const auto& [func, bblocks] : fullIR)
{
for (const auto& block : bblocks) for (const auto& block : bblocks)
{
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr) for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
{ {
auto op = (*instr)->getInstruction()->getOperator(); auto op = (*instr)->getInstruction()->getOperator();
if (op && op->variant() == FOR_NODE) if (op && op->variant() == FOR_NODE)
for_statements.insert(op); for_statements.insert(op);
} }
}
}
for (const auto& alloc_statement : alloc_statements) for (const auto& alloc_statement : alloc_statements)
handle_single_allocate(where_to_add, alloc_statement, fullIR); handle_single_allocate(where_to_add, alloc_statement, fullIR);

View File

@@ -1,42 +1,14 @@
#pragma once #pragma once
#include "libSage++.h"
#include <map> #include <map>
#include <string> #include <string>
#include <set> #include <set>
#include <vector> #include <vector>
#include "..\GraphCall\graph_calls.h"
using ResultSet = std::set<std::tuple<std::string, int, std::string>>; using ResultSet = std::set<std::tuple<std::string, int, std::string>>;
enum class MODE void findParameters(ResultSet& foundParameters,
{ std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
BEFORE, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);
AFTER
};
static std::map<FuncInfo*, std::vector<SAPFOR::Instruction*>> call_sites;
template<typename Iterator>
void extract_vars_from_reg(std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* reg,
Iterator instr,
Iterator first_instr);
template<typename Iterator>
void processArgument(std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* arg,
Iterator instr,
Iterator first_instr);
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Instruction* instr,
SAPFOR::BasicBlock* bblock,
FuncInfo* cur_func,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);
void
findParameters(ResultSet& foundParameters,
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);

View File

@@ -1894,9 +1894,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == RENAME_SYMBOLS) else if (curr_regime == RENAME_SYMBOLS)
runRenameSymbols(&project, commonBlocks); runRenameSymbols(&project, commonBlocks);
else if (curr_regime == FIND_PARAMETERS) else if (curr_regime == FIND_PARAMETERS)
{
findParameters(parametersOfProject, fullIR, declaredArrays); findParameters(parametersOfProject, fullIR, declaredArrays);
}
else if (curr_regime == BUILD_IR) else if (curr_regime == BUILD_IR)
{ {
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0)); auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include "../Distribution/Array.h"
enum varType { SCALAR, ARRAY, CONST, ANOTHER }; enum varType { SCALAR, ARRAY, CONST, ANOTHER };
struct CommonVariableUse struct CommonVariableUse

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2422" #define VERSION_SPF "2423"