-
Notifications
You must be signed in to change notification settings - Fork 0
/
project.cpp
133 lines (107 loc) · 4.07 KB
/
project.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/******************************************************************************
* GRIDGEN: Grid Generating Compiler
* By: Andy Stone ([email protected])
* (C) Copyright 2011 Colorado State University
*****************************************************************************/
#include "project.hpp"
#include "analyses.hpp"
#include "utils.hpp"
#include <iostream>
#include <string>
using namespace std;
Project::Project(int argc, char **argv, bool analyze) {
// Load project through ROSE frontend
mProj = frontend(argc, argv);
if(mProj == NULL) {
cerr << "Rose unable to read project." << endl;
exit(1);
}
generatePDF(*mProj);
// Extract information about files in project and their paths
typedef Rose_STL_Container<std::string> containerT;
containerT files = mProj->getAbsolutePathFileNames();
for(containerT::iterator i = files.begin();
i != files.end(); i++)
{
int pos = i->find_last_of('/');
string path = i->substr(0, pos);
string file = i->substr(pos+1);
mFiles.push_back(FileInfo(path, file));
}
// conduct an analysis of the code if specified
if(analyze) { this->analyze(); }
}
void Project::analyze() {
// Gather calls to library and construct environment
CallsAnalysis callAnl;
CallsVectorT calls = callAnl.analyze(mProj);
gEnv.buildFromCalls(calls);
gEnv.print(cout);
//Instrument calls with comments
replaceApply(calls);
}
void Project::generate() {
// Use ROSE to output the resulting program
mProj->unparse();
// Move output files into their correct directories
typedef vector<FileInfo>::iterator iterT;
for(iterT i = mFiles.begin(); i != mFiles.end(); i++) {
// move rose_<filename>.<ext>
string cmd = "mv rose_" + i->mFileName + " " + i->mPath;
system(cmd.c_str());
// move <filename>_postprocesed.<ext>
cmd = "mv " + i->postProcessedFileName() + " " + i->mPath;
system(cmd.c_str());
}
}
void Project::replaceApply(const CallsVectorT &calls) {
// Iterate through calls, find apply statements
for(CallsConstIteratorT i = calls.begin(); i != calls.end(); i++) {
if((*i)->operation() == CALL__DATA_APPLY) {
replaceApply(dynamic_cast<Call__data_apply*>(*i));
}
}
}
void Project::replaceApply(Call__data_apply *call) {
ostringstream ss;
// Place new code in a string
startLoops(call, ss);
ss << indt
<< call->funcDef()->unparseToString();
//printNodeAndChildren(cout, call->funcDef()->get_traversalSuccessorByIndex(0));
endLoops(call, ss);
//data_apply%vals(x, y, lbid) = func(neighs)
// Remove old code
replaceCall(call->location(), ss.str());
}
void Project::startLoops(Call__data_apply *call, ostringstream &ss) {
ss << pushIndt;
ss << indt << "do __gg_idx_lbid = lbound("
<< call->lhs().ident() << "\%vals,3), "
<< "ubound(" << call->lhs().ident() << "\%vals,3)" << pushIndt;
ss << indt << "do __gg_idx_y = 1, "
<< call->lhs().ident() << "\%dist\%blockSize(2)" << pushIndt;
ss << indt << "do __gg_idx_x = 1, "
<< call->lhs().ident() << "\%dist\%blockSize(1)" << pushIndt;
}
void Project::endLoops(Call__data_apply *call, ostringstream &ss) {
ss << popIndt << indt << "end do";
ss << popIndt << indt << "end do";
ss << popIndt << indt << "end do";
ss << popIndt << endl;
}
void Project::placeAboveCall(SgFunctionCallExp *node, const string &s) {
SageInterface::addTextForUnparser(node, s, AstUnparseAttribute::e_after);
}
void Project::replaceCall(SgFunctionCallExp *node, const string &s) {
SgNode *parent = node->get_parent();
while(parent->variantT() != V_SgExprStatement) {
parent = parent->get_parent();
}
SgExprStatement *parentExp = isSgExprStatement(parent);
SgNullStatement *newStmt = new SgNullStatement(parent->get_file_info());
// Insert new code
SageInterface::addTextForUnparser(newStmt, s, AstUnparseAttribute::e_after);
// Remove old code
SageInterface::replaceStatement(parentExp, newStmt);
}