Add Dominator tree builder and interprocedural analysis

This commit is contained in:
2025-04-15 12:23:32 +03:00
committed by Alexander
parent 81d7d3803b
commit 0d8ba256ae
5 changed files with 289 additions and 55 deletions

View File

@@ -24,7 +24,7 @@ namespace SAPFOR
std::vector<BasicBlock*> next; std::vector<BasicBlock*> next;
std::vector<BasicBlock*> prev; std::vector<BasicBlock*> prev;
BasicBlock* idom{};
//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;
@@ -42,6 +42,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_; }
int removePrev(BasicBlock* removed); int removePrev(BasicBlock* removed);
int removeNext(BasicBlock* removed); int removeNext(BasicBlock* removed);
@@ -69,7 +70,8 @@ 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; }
/* /*
* FOR LIVE ANALYSIS * FOR LIVE ANALYSIS
*/ */
@@ -146,4 +148,4 @@ static inline void deleteCFG(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
byFunc.second.clear(); byFunc.second.clear();
} }
cfg.clear(); cfg.clear();
} }

View File

@@ -0,0 +1,111 @@
#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

@@ -1,10 +1,10 @@
#include <cassert>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#include <set> #include <set>
#include <string>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <tuple> #include <tuple>
@@ -20,14 +20,43 @@
#include "libSage++.h" #include "libSage++.h"
#include "projectParameters.h" #include "projectParameters.h"
#include "domTree.h"
using namespace std; using namespace std;
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt)
{
SgStatement* cur = stmt;
while (cur->variant() != PROC_HEDR && cur->variant() != PROG_HEDR && cur->variant() != FUNC_HEDR)
cur = cur->controlParent();
string funcName = ((SgProcHedrStmt*)cur)->nameWithContains();
int stmtID = stmt->id();
for (const auto& [func, bblocks] : CFGraph)
{
if (func->funcName != funcName)
continue;
for (auto basicBlock : bblocks)
for (auto ins : basicBlock->getInstructions())
if (stmtID == ins->getInstruction()->getOperator()->id())
return make_tuple(func, ins->getInstruction(), basicBlock);
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return { NULL, NULL, NULL };
}
template<typename Iterator> template<typename Iterator>
static void processArgument(set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* arg, Iterator instr, Iterator first_instr) { static void processArgument(set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* arg,
Iterator 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 && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::LOCAL_) else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::LOCAL_)
{ {
@@ -37,9 +66,14 @@ static void processArgument(set<SAPFOR::Argument*>& worklist, SAPFOR::Argument*
} }
template<typename Iterator> template<typename Iterator>
void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* reg, Iterator instr, Iterator first_instr) { static void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
for (; instr >= first_instr; instr--) { SAPFOR::Argument* reg,
if ((*instr)->getInstruction()->getResult() == reg) Iterator instr,
Iterator first_instr)
{
for (; instr >= first_instr; instr--)
{
if ((*instr)->getInstruction()->getResult() == reg)
{ {
processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr); processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr);
processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr); processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr);
@@ -48,14 +82,14 @@ void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* r
} }
} }
static void lookup_for_vars(ResultSet& result_set, static void lookup_for_vars(std::map<SgStatement*, std::string>& where_to_add,
set<SAPFOR::Argument*>& worklist, set<SAPFOR::Argument*>& worklist,
SAPFOR::Instruction* instr, SAPFOR::Instruction* instr,
SAPFOR::BasicBlock* bblock, SAPFOR::BasicBlock* bblock,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR) const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
{ {
std::cout << "Lookup in bblock no." << bblock->getNumber() << std::endl; //DEBUG PRINT std::cout << "Lookup in bblock no." << bblock->getNumber() << std::endl; //DEBUG PRINT
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 = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == instr; return i->getInstruction() == instr;
@@ -63,7 +97,7 @@ static void lookup_for_vars(ResultSet& result_set,
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();
auto arg1 = instr->getArg1(); auto arg1 = instr->getArg1();
auto arg2 = instr->getArg2(); auto arg2 = instr->getArg2();
@@ -75,37 +109,37 @@ static void lookup_for_vars(ResultSet& result_set,
std::cout << "worklist erase: " << result_arg->getValue() << std::endl; //DEBUG PRINT std::cout << "worklist erase: " << result_arg->getValue() << std::endl; //DEBUG PRINT
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
auto f_call_instr = cur_instr; auto f_call_instr = cur_instr;
while ((*f_call_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL) while ((*f_call_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL)
f_call_instr++; f_call_instr++;
if ((*f_call_instr)->getInstruction()->getArg1()->getValue() == "_READ") if ((*f_call_instr)->getInstruction()->getArg1()->getValue() == "_READ")
{ {
auto filename = (*f_call_instr)->getInstruction()->getOperator()->fileName(); auto stmt_before = (*f_call_instr)->getInstruction()->getOperator();
auto line = (*f_call_instr)->getInstruction()->getOperator()->lineNumber(); auto filename = stmt_before->fileName();
auto line = stmt_before->lineNumber();
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", arg1->getValue().c_str(), line, filename); __spf_print(1,"Please specify value of variable %s on line %d of file %s", arg1->getValue().c_str(), line, filename);
result_set.insert(make_tuple(filename, line, arg1->getValue())); where_to_add[stmt_before] = var_name;
std::cout << "worklist erase: " << arg1->getValue() << std::endl; //DEBUG PRINT std::cout << "worklist erase: " << arg1->getValue() << std::endl; //DEBUG PRINT
worklist.erase(arg1); worklist.erase(arg1);
} else } else
{ {
//check if variable is modified in called function //check if variable is modified in called function
} }
} }
} }
const auto& RD = bblock->getRD_In(); const auto& RD = bblock->getRD_In();
map<SAPFOR::BasicBlock*, SAPFOR::Instruction*> group_by_block; map<SAPFOR::BasicBlock*, SAPFOR::Instruction*> group_by_block;
for (auto& arg : worklist) for (auto& arg : worklist)
{ {
if (RD.count(arg)) if (RD.count(arg))
{ {
if (RD.at(arg).size() == 0) if (RD.at(arg).size() == 1 && *RD.at(arg).begin() == SAPFOR::CFG_VAL::UNINIT)
__spf_print(1, "variable %s has no definition", arg->getValue().c_str()); __spf_print(1, "variable %s has no definition", arg->getValue().c_str());
else if (RD.at(arg).size() > 1) else if (RD.at(arg).size() > 1)
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible", arg->getValue().c_str()); __spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible", arg->getValue().c_str());
@@ -114,24 +148,31 @@ static void lookup_for_vars(ResultSet& result_set,
for (const auto& instr_num : RD.at(arg)) for (const auto& instr_num : RD.at(arg))
{ {
auto [instr, bblock] = getInstructionAndBlockByNumber(fullIR, instr_num); auto [instr, bblock] = getInstructionAndBlockByNumber(fullIR, instr_num);
if (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num) if (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num)
group_by_block[bblock] = instr; group_by_block[bblock] = instr;
} }
} }
} }
} }
for (const auto& [bblock, instr] : group_by_block) auto idom = bblock->getIdom();
while (idom != NULL)
{ {
lookup_for_vars(result_set, worklist, instr, bblock, fullIR); if (group_by_block.count(idom))
{
lookup_for_vars(where_to_add, worklist, group_by_block[idom], idom, fullIR);
return;
}
idom = idom->getIdom();
} }
} }
static void handle_single_allocate(ResultSet& result_set, static void handle_single_allocate(std::map<SgStatement*, std::string>& where_to_add,
SAPFOR::Instruction* instr, SgStatement* alloc_statement,
SAPFOR::BasicBlock* bblock,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR) const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
{ {
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 = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
return i->getInstruction() == instr; return i->getInstruction() == instr;
@@ -140,7 +181,7 @@ static void handle_single_allocate(ResultSet& result_set,
// 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++;
} }
@@ -161,11 +202,11 @@ static void handle_single_allocate(ResultSet& result_set,
} }
auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue()); auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue());
for (int j = 0; j < dimensions_num; j++) for (int j = 0; j < dimensions_num; j++)
{ {
auto ref_instr = --param_instr; auto ref_instr = --param_instr;
auto arg = (*ref_instr)->getInstruction()->getArg1(); auto arg = (*ref_instr)->getInstruction()->getArg1();
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG) if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
{ {
@@ -178,33 +219,107 @@ static void handle_single_allocate(ResultSet& result_set,
} }
} }
} }
lookup_for_vars(result_set,worklist, instr, bblock, fullIR); lookup_for_vars(where_to_add,worklist, instr, bblock, fullIR);
} }
ResultSet static void handle_single_loop(std::map<SgStatement*, std::string>& where_to_add,
findParameters(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR, SgStatement* loop_stmt,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
{
auto [func_name, instr, bblock] = stmtToIR(fullIR, loop_stmt);
std::cout << "bblock: " << bblock->getNumber() << " instr: " << instr->getNumber() << std::endl;
auto cur_instr = bblock->getInstructions().end() - 1;
set<SAPFOR::Argument*> worklist;
extract_vars_from_reg(worklist, (*cur_instr)->getInstruction()->getResult(), cur_instr, bblock->getInstructions().begin());
lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, 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) const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
{ {
ResultSet foundParameters; map<SgStatement*, string> where_to_add;
map<string, FuncInfo*> name_to_func;
for (const auto& [func, _] : fullIR)
name_to_func[func->funcName] = func;
map<FuncInfo*, vector<SAPFOR::Instruction*>> call_sites;
for (auto& [func, bblocks] : fullIR)
{
for (const auto& block : bblocks)
{
for (const auto& ir_block : block->getInstructions())
{
auto instr = ir_block->getInstruction();
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
{
auto func_name = instr->getArg1()->getValue();
auto func_info = name_to_func.find(func_name);
if (func_info != name_to_func.end())
call_sites[func_info->second].push_back(instr);
}
}
}
SAPFOR::buildDominatorTreeLT(bblocks);
for (auto block : bblocks)
{
if (block->getIdom() != NULL)
std::cout << "BB: " << block->getNumber() << " IDOM: " << block->getIdom()->getNumber() << std::endl;
}
std::cout << "+++++++++++\n";
}
std::set<SgStatement*> alloc_statements; std::set<SgStatement*> alloc_statements;
for (const auto& elem : declaredArrays) for (const auto& elem : declaredArrays)
{ {
const auto& array = elem.second.first; const auto& array = elem.second.first;
assert(array->GetLocation().first == Distribution::arrayLocation::l_LOCAL); // v0.1
SgSymbol* arraySymb = array->GetDeclSymbol()->GetOriginal(); SgSymbol* arraySymb = array->GetDeclSymbol()->GetOriginal();
SgStatement* decl = declaratedInStmt(arraySymb); SgStatement* decl = declaratedInStmt(arraySymb);
for (auto &stmt : getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT }))
{ for (auto& stmt : getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT }))
alloc_statements.insert(stmt); alloc_statements.insert(stmt);
}
} }
for (const auto& alloc_statement : alloc_statements) for (const auto& alloc_statement : alloc_statements)
{ {
auto [instr, bblock] = getInstructionAndBlockByStatement(fullIR, alloc_statement); handle_single_allocate(where_to_add, alloc_statement, fullIR);
ResultSet result_set; }
handle_single_allocate(result_set, instr, bblock, fullIR);
set<SgStatement*> for_statements;
// Find all FOR statements in the program
for (const auto& [func, bblocks] : fullIR)
for (const auto& block : bblocks)
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
{
auto op = (*instr)->getInstruction()->getOperator();
if (op && op->variant() == FOR_NODE) {
std::cout << block->getNumber() << std::endl;
for_statements.insert(op);
}
}
for (const auto& stmt : for_statements)
{
handle_single_loop(where_to_add, stmt, fullIR);
}
for (const auto& [stmt_before, var_name] : where_to_add)
{
// SgVariableSymb* var_symb = new SgVariableSymb(var_name.c_str());
// SgVarRefExp* var = new SgVarRefExp(var_symb);
// SgValueExp* zero = new SgValueExp(0);
// SgExprListExp* ex = new SgExprListExp();
// ex->setLhs(new SgExpression(ASSGN_OP, var, zero));
// SgStatement* toAdd = new SgStatement(SPF_PARAMETER_OP, NULL, NULL, ex, NULL, NULL);
// stmt_before->insertStmtAfter(*toAdd, *stmt_before->controlParent());
foundParameters.insert(make_tuple(stmt_before->fileName(), stmt_before->lineNumber(), var_name));
} }
return foundParameters;
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "libSage++.h"
#include <map> #include <map>
#include <string> #include <string>
#include <set> #include <set>
@@ -7,18 +8,25 @@
using ResultSet = std::set<std::tuple<std::string, int, std::string>>; using ResultSet = std::set<std::tuple<std::string, int, std::string>>;
template<typename Iterator> template<typename Iterator>
void extract_vars_from_reg(std::set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* reg, Iterator instr, Iterator first_instr); static void extract_vars_from_reg(std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* reg,
Iterator instr,
Iterator first_instr);
template<typename Iterator> template<typename Iterator>
static void processArgument(std::set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* arg, Iterator instr, Iterator first_instr); static void processArgument(std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Argument* arg,
Iterator instr,
Iterator first_instr);
static void lookup_for_vars(ResultSet& result_set, static void lookup_for_vars(std::map<SgStatement*, std::string>& where_to_add,
std::set<SAPFOR::Argument*>& worklist, std::set<SAPFOR::Argument*>& worklist,
SAPFOR::Instruction* instr, SAPFOR::Instruction* instr,
SAPFOR::BasicBlock* bblock, SAPFOR::BasicBlock* bblock,
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR); const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);
ResultSet void
findParameters(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR, 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); const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);

View File

@@ -1895,9 +1895,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
runRenameSymbols(&project, commonBlocks); runRenameSymbols(&project, commonBlocks);
else if (curr_regime == FIND_PARAMETERS) else if (curr_regime == FIND_PARAMETERS)
{ {
performRDSubst(fullIR, commonBlocks, &project); findParameters(parametersOfProject, fullIR, declaredArrays);
parametersOfProject = findParameters(fullIR, declaredArrays);
performRDSubst(fullIR, commonBlocks, &project);
} }
else if (curr_regime == BUILD_IR) else if (curr_regime == BUILD_IR)
{ {