dynamic parameters #61
@@ -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
|
||||||
|
|||||||
@@ -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__);
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
35
src/CFGraph/IR_domTree.h
Normal 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);
|
||||||
|
}
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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 };
|
||||||
@@ -64,26 +79,23 @@ tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> IRByNumber(const map
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@@ -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();
|
||||||
@@ -236,9 +251,10 @@ 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_)
|
||||||
@@ -254,14 +270,14 @@ 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;
|
||||||
@@ -271,7 +287,6 @@ void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& wh
|
|||||||
(*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;
|
||||||
@@ -298,7 +313,8 @@ void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& wh
|
|||||||
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);
|
||||||
@@ -309,12 +325,11 @@ void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& wh
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -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,
|
||||||
{
|
|
||||||
BEFORE,
|
|
||||||
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,
|
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);
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION_SPF "2422"
|
#define VERSION_SPF "2423"
|
||||||
|
|||||||
Reference in New Issue
Block a user