WIP: merge with master
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#define _LEAK_
|
||||
#include "../Utils/leak_detector.h"
|
||||
#include "leak_detector.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -8,9 +8,9 @@
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "SgUtils.h"
|
||||
#include "CommonBlock.h"
|
||||
#include "graph_calls.h"
|
||||
|
||||
#include "dvm.h"
|
||||
#include "IR.h"
|
||||
@@ -1167,6 +1167,16 @@ map<FuncInfo*, vector<BBlock*>> buildCFG(const map<string, CommonBlock*>& common
|
||||
if (settings.withRD)
|
||||
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)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "IR_domTree.h"
|
||||
|
||||
namespace SAPFOR
|
||||
{
|
||||
@@ -28,7 +29,7 @@ namespace SAPFOR
|
||||
|
||||
std::vector<BasicBlock*> next;
|
||||
std::vector<BasicBlock*> prev;
|
||||
|
||||
BasicBlock* directDominator = NULL;
|
||||
//reaching definition
|
||||
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
|
||||
|
||||
@@ -38,6 +39,7 @@ namespace SAPFOR
|
||||
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;
|
||||
bool removeLive(SAPFOR::Argument* to_remove, bool in);
|
||||
|
||||
public:
|
||||
BasicBlock() { num = lastNumBlock++; }
|
||||
BasicBlock(IR_Block* item);
|
||||
@@ -47,6 +49,7 @@ namespace SAPFOR
|
||||
void addInstruction(IR_Block* item, bool pushFront = false);
|
||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||
void setDom(BasicBlock* dom) { directDominator = dom; }
|
||||
|
||||
int removePrev(BasicBlock* removed);
|
||||
int removeNext(BasicBlock* removed);
|
||||
@@ -74,7 +77,11 @@ namespace SAPFOR
|
||||
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
|
||||
const std::vector<BasicBlock*>& getNext() const { return next; }
|
||||
const std::vector<BasicBlock*>& getPrev() const { return prev; }
|
||||
|
||||
BasicBlock* getDom() const
|
||||
{
|
||||
return directDominator;
|
||||
}
|
||||
|
||||
/*
|
||||
* FOR LIVE ANALYSIS
|
||||
*/
|
||||
@@ -110,13 +117,15 @@ namespace SAPFOR
|
||||
bool withDVM = false;
|
||||
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
|
||||
bool withCallFrom = true;
|
||||
bool withDominators = true;
|
||||
|
||||
explicit CFG_Settings(int) { }
|
||||
|
||||
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),
|
||||
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom)
|
||||
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom), withDominators(withDominators)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
@@ -151,4 +160,4 @@ static inline void deleteCFG(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
|
||||
byFunc.second.clear();
|
||||
}
|
||||
cfg.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
#include "../RD_subst.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include<vector>
|
||||
#include<set>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include<vector>
|
||||
#include<set>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
#include "leak_detector.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "../ExpressionTransform/expr_transform.h"
|
||||
#include "SgUtils.h"
|
||||
#include "CommonBlock.h"
|
||||
#include "graph_calls.h"
|
||||
#include "expr_transform.h"
|
||||
|
||||
#include "dvm.h"
|
||||
#include "IR.h"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "CFGraph.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
#include "CommonBlock.h"
|
||||
|
||||
namespace SAPFOR
|
||||
{
|
||||
@@ -347,4 +347,4 @@ std::vector<SAPFOR::IR_Block*> buildIR(SgStatement* function, const FuncInfo* fu
|
||||
SAPFOR::Instruction* getInstructionByNumber(const std::vector<SAPFOR::IR_Block*>& blocks, int num);
|
||||
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByNumber(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, int num);
|
||||
std::pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*> getInstructionAndBlockByStatement(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt);
|
||||
int getParamIndex(SAPFOR::Argument* func_param, int max_index);
|
||||
int getParamIndex(SAPFOR::Argument* func_param, int max_index);
|
||||
@@ -225,54 +225,52 @@ static BBlock* findImmediateDominatorsDfsHelper(BBlock* block, BBlock* currentBl
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool checkoDom(vector<BBlock*> a, vector<BBlock*> b, BBlock* c) {
|
||||
if (a.size() != b.size() + 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto i : a)
|
||||
{
|
||||
if (i != c && find(b.begin(), b.end(), i) == b.end()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static map<BBlock*, BBlock*> findImmediateDominators1(const map<BBlock*, vector<BBlock*>>& dominators, BBlock* entry)
|
||||
{
|
||||
map<BBlock*, BBlock*> iDom;
|
||||
|
||||
for (const auto& pair : dominators)
|
||||
{
|
||||
for (const auto& pair : dominators) {
|
||||
BBlock* b = pair.first;
|
||||
|
||||
if (b == entry)
|
||||
continue;
|
||||
if (b == entry) continue;
|
||||
|
||||
const auto& doms = pair.second;
|
||||
|
||||
BBlock* candidate = NULL;
|
||||
for (auto& d : doms)
|
||||
{
|
||||
if (d == b)
|
||||
continue;
|
||||
// candidates = all dominators of b except itself
|
||||
bool found = false;
|
||||
for (auto& d : doms) {
|
||||
if (d == b) continue;
|
||||
|
||||
bool isImmediate = true;
|
||||
for (auto& other : doms)
|
||||
{
|
||||
if (other == b || other == d)
|
||||
continue;
|
||||
|
||||
const auto& domsOfOther = dominators.at(other);
|
||||
if (std::find(domsOfOther.begin(), domsOfOther.end(), d) != domsOfOther.end())
|
||||
{
|
||||
isImmediate = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isImmediate)
|
||||
{
|
||||
candidate = d;
|
||||
if (checkoDom(doms, dominators.at(d), b)) {
|
||||
iDom[b] = d;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (candidate)
|
||||
iDom[b] = candidate;
|
||||
if (!found) {
|
||||
cout << "ERRORERRORERROR " << b->getNumber() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return iDom;
|
||||
}
|
||||
|
||||
|
||||
static map<BBlock*, BBlock*> findImmediateDominators(map<BBlock*, vector<BBlock*>>& dominators, BBlock* fistBlock)
|
||||
{
|
||||
map<BBlock*, BBlock*> iDominators;
|
||||
@@ -483,6 +481,8 @@ static void renameFiFunctionArgsVar(BBlock* block, map<string, stack<BArgument*>
|
||||
auto size = block->getInstructions().size();
|
||||
auto& instructions = block->getInstructions();
|
||||
|
||||
//cout << "try to insert Phi to block - " << block->getNumber() << endl;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto irBlock = instructions[i];
|
||||
@@ -491,6 +491,7 @@ static void renameFiFunctionArgsVar(BBlock* block, map<string, stack<BArgument*>
|
||||
instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL &&
|
||||
instruction->getArg2() != NULL)
|
||||
{
|
||||
//cout << "Insert Phi to block - " << block->getNumber() << endl;
|
||||
Instruction* paramInstruction;
|
||||
|
||||
if (stack[instruction->getResult()->getValue()].size() > 0)
|
||||
@@ -527,12 +528,14 @@ static vector<BBlock*> findBlocksWithValue(map<BBlock*, BBlock*>& iDominators, B
|
||||
|
||||
static void renameIR(BBlock* block, map<BBlock*, BBlock*>& iDominators, map<string, int>& counter, map<string, stack<BArgument*>>& stack) {
|
||||
|
||||
//cout << "renameIR for block " << block->getNumber() << endl;
|
||||
|
||||
renameFiFunctionResultVar(block, counter, stack);
|
||||
renameInstructionVars(block, counter, stack);
|
||||
|
||||
for (auto& successor : block->getNext())
|
||||
renameFiFunctionArgsVar(successor, stack);
|
||||
|
||||
|
||||
for (auto& child : findBlocksWithValue(iDominators, block))
|
||||
renameIR(child, iDominators, counter, stack);
|
||||
|
||||
@@ -558,22 +561,37 @@ static void renameIR(BBlock* block, map<BBlock*, BBlock*>& iDominators, map<stri
|
||||
}
|
||||
}
|
||||
|
||||
bool isEqual1(const char* cstr, const std::string& str) {
|
||||
return str == cstr;
|
||||
}
|
||||
|
||||
void buildIRSSAForm(const map<FuncInfo*, vector<BBlock*>>& fullIR,
|
||||
map<FuncInfo*, vector<BBlock*>>& result) {
|
||||
|
||||
for (auto& [funcinfo, funcIRConst]: fullIR) {
|
||||
if (isEqual1("csol.for", funcinfo->fileName) || isEqual1("reblns.for", funcinfo->fileName) || isEqual1("adjont.for", funcinfo->fileName)
|
||||
|| isEqual1("beginf.for", funcinfo->fileName) || isEqual1("dsnp1.for", funcinfo->fileName) || isEqual1("dsnpnm.for", funcinfo->fileName)
|
||||
|| isEqual1("decod3.for", funcinfo->fileName))
|
||||
continue;
|
||||
|
||||
cout << "Testing " << funcinfo->funcName << endl;
|
||||
|
||||
vector<BBlock*> funcIR;
|
||||
|
||||
/* for (auto& i : funcIRConst) {
|
||||
printBlock(i);
|
||||
}*/
|
||||
|
||||
for (auto& i : funcIRConst)
|
||||
funcIR.push_back(new BBlock(*i));
|
||||
|
||||
restoreConnections(funcIRConst, funcIR);
|
||||
|
||||
for (auto& i : funcIR) {
|
||||
//printBlock(i);
|
||||
}
|
||||
/*for (auto& i : funcIR) {
|
||||
printBlock(i);
|
||||
}*/
|
||||
for (auto& [func, bblocks] : result)
|
||||
SAPFOR::buildDominatorTree(bblocks);
|
||||
auto dominators = findDominators(funcIR);
|
||||
|
||||
/*cout << endl << endl << endl << "DOMINATORS" << endl << endl << endl;
|
||||
@@ -640,11 +658,17 @@ void buildIRSSAForm(const map<FuncInfo*, vector<BBlock*>>& fullIR,
|
||||
varStack[var->getValue()] = tmp;
|
||||
}
|
||||
|
||||
/*for (auto& i : funcIR) {
|
||||
printBlock(i);
|
||||
}*/
|
||||
|
||||
renameIR(funcIR[0], iDominators, count, varStack);
|
||||
|
||||
for (auto& i : funcIR) {
|
||||
//printBlock(i);
|
||||
}
|
||||
//cout << endl << endl << "___________________" << endl << endl;
|
||||
|
||||
/*for (auto& i : funcIR) {
|
||||
printBlock(i);
|
||||
}*/
|
||||
//cout << endl << endl << endl << endl << endl;
|
||||
//for (auto i : funcIRConst) {
|
||||
// printBlock(i);
|
||||
|
||||
102
src/CFGraph/IR_domTree.cpp
Normal file
102
src/CFGraph/IR_domTree.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "dvm.h"
|
||||
#include "IR_domTree.h"
|
||||
|
||||
namespace SAPFOR {
|
||||
void DominatorFinder::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 DominatorFinder::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 DominatorFinder::Eval(int v) {
|
||||
if (ancestor[v] == -1)
|
||||
return v;
|
||||
|
||||
Compress(v);
|
||||
return label[v];
|
||||
}
|
||||
|
||||
void DominatorFinder::Link(int v, int w) {
|
||||
ancestor[w] = v;
|
||||
}
|
||||
|
||||
DominatorFinder::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()) {
|
||||
if (dfs_num[v] == -1)
|
||||
continue;
|
||||
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]->setDom(vertices[u]);
|
||||
else
|
||||
vertices[v]->setDom(vertices[parent[w]]);
|
||||
}
|
||||
bucket[parent[w]].clear();
|
||||
}
|
||||
|
||||
for (int i = 1; i < n; ++i) {
|
||||
int w = vertex[i];
|
||||
|
||||
if (vertices[w]->getDom() != vertices[vertex[semi[w]]])
|
||||
vertices[w]->setDom(vertices[w]->getDom()->getDom());
|
||||
}
|
||||
|
||||
entry->setDom(nullptr);
|
||||
}
|
||||
|
||||
void buildDominatorTree(std::vector<BasicBlock*>& blocks) {
|
||||
DominatorFinder finder(blocks);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -8,10 +8,10 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "../ExpressionTransform/expr_transform.h"
|
||||
#include "SgUtils.h"
|
||||
#include "CommonBlock.h"
|
||||
#include "graph_calls.h"
|
||||
#include "expr_transform.h"
|
||||
|
||||
#define PRINT_PROF_INFO 0
|
||||
#define DEBUG_CHECKS 0
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
#include<unordered_map>
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/CommonBlock.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "SgUtils.h"
|
||||
#include "CommonBlock.h"
|
||||
#include "graph_calls.h"
|
||||
|
||||
#include "CFGraph.h"
|
||||
#include "IR.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "SgUtils.h"
|
||||
#include "CFGraph.h"
|
||||
|
||||
namespace LIVE_VARIABLES
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "../Utils/errors.h"
|
||||
#include "errors.h"
|
||||
#include "private_variables_analysis.h"
|
||||
#include "../GraphLoop/graph_loops.h"
|
||||
#include "graph_loops.h"
|
||||
#include "../LoopAnalyzer/loop_analyzer.h"
|
||||
#include "../SageAnalysisTool/depGraph.h"
|
||||
#include "../DirectiveProcessing/directive_parser.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../GraphLoop/graph_loops.h"
|
||||
#include "SgUtils.h"
|
||||
#include "graph_loops.h"
|
||||
#include "CFGraph.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
Reference in New Issue
Block a user