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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
#include "code_gen/rose_attributes.h"
namespace omega {
CodeInsertionAttribute* getOrCreateCodeInsertionAttribute(SgNode* node) {
CodeInsertionAttribute* attr;
if(node->attributeExists("code_insertion"))
return static_cast<CodeInsertionAttribute*>(node->getAttribute("code_insertion"));
attr = new CodeInsertionAttribute();
node->setAttribute("code_insertion", attr);
return attr;
}
void postProcessRoseCodeInsertion(SgProject* proj) {
//generatePDF(*proj);
CodeInsertionVisitor visitor = CodeInsertionVisitor();
visitor.initialize();
visitor.traverseInputFiles(proj);
visitor.insertCode();
}
// Swap a code insertion from one node (sn) to another (dn)
// -- note that this function does not currently remove the insertion from the sn node
void moveCodeInsertion(SgNode* sn, CodeInsertion* ci, SgNode* dn) {
CodeInsertionAttribute* new_attr;
// TODO in the near future: replace the above statement with 'new_attr = getOrCreateCodeInsertionAttribute(...)'
CodeInsertionAttribute* old_attr = static_cast<CodeInsertionAttribute*>(sn->getAttribute("code_insertion"));
if(dn->attributeExists("code_insertion")) {
new_attr = static_cast<CodeInsertionAttribute*>(dn->getAttribute("code_insertion"));
}
else {
new_attr = new CodeInsertionAttribute();
dn->setAttribute("code_insertion", new_attr);
}
new_attr->add(ci);
}
// A function that copies a specific attribute from one node to another
// this function exists to get around a ROSE limitation that does not
// copy attributes
void copyAttribute(std::string attr_name, SgNode* s, SgNode* d) {
if(s->attributeExists(attr_name)) {
d->setAttribute(attr_name,s->getAttribute(attr_name));
}
}
// TODO: find all existng attributes and iterate over them instead of doing them
// individually
void copyAttributes(SgNode* s, SgNode* d) {
copyAttribute("code_insertion", s, d);
//...any other attributes...
}
void CodeInsertionVisitor::initialize() {
this->loop_level = 0;
this->ci_marks = std::vector<CodeInsertionMark*>();
}
void CodeInsertionVisitor::markStmt(SgStatement* stmt, CodeInsertion* ci) {
// this check prevents multiple copies of stmts
// -- may be changed in the future
if(!ci->marked) {
CodeInsertionMark* pos = new CodeInsertionMark();
pos->stmt = stmt;
pos->ci = ci;
this->ci_marks.push_back(pos);
ci->marked = true;
}
}
// increase loop_level as the visitor descends
void CodeInsertionVisitor::preOrderVisit(SgNode* n) {
if (isSgForStatement(n)) {
this->loop_level++;
}
}
void CodeInsertionVisitor::postOrderVisit(SgNode* n) {
if(isSgForStatement(n)) {
this->loop_level--;
}
if(isSgStatement(n)) {
if(n->attributeExists("code_insertion")) {
CodeInsertionAttribute *attr = static_cast<CodeInsertionAttribute*>(n->getAttribute("code_insertion"));
for(CodeInsertionPtrListItr itr = attr->begin(); itr != attr->end(); ++itr) {
CodeInsertion *insertion = *itr;
// check loop level -- if it is equivelent, mark statement for insertion
// -- else, move attribute up to parent
if(insertion->loop_level != this->loop_level) {
moveCodeInsertion(n, insertion, n->get_parent());
}
else {
this->markStmt(isSgStatement(n), insertion);
}
}
}
}
}
// final stage of algorithm that inserts marked statements
void CodeInsertionVisitor::insertCode() {
for(std::vector<CodeInsertionMark*>::iterator itr = this->ci_marks.begin(); itr != this->ci_marks.end(); ++itr) {
CodeInsertionMark* mark = *itr;
SgScopeStatement* scope = static_cast<SgScopeStatement*>(mark->stmt->get_parent());
SageInterface::insertStatementBefore(mark->stmt, mark->ci->getStatement(scope));
}
}
SgStatement* PragmaInsertion::getStatement(SgScopeStatement* scopeStmt) {
SgStatement* stmt = SageBuilder::buildPragmaDeclaration(this->name);
return stmt;
}
//SgStatement* MMPrefetchInsertion::getStatement(SgScopeStatement* scopeStmt) {
// const SgName& name = SgName("_mm_prefetch");
// SgType* rtype = SageBuilder::buildVoidType();
// SgExpression* arr_arg = SageBuilder::buildVarRefExp(this->arrName);
// SgExpression* hint_arg = SageBuilder::buildShortVal(this->cacheHint);
// SgExprListExp* args = SageBuilder::buildExprListExp(arr_arg,hint_arg);
// SgStatement* stmt = SageBuilder::buildFunctionCallStmt(name, rtype, args, scopeStmt);
// return stmt;
//}
SgStatement* MMPrefetchInsertion::getStatement(SgScopeStatement* scopeStmt) {
const SgName fname = SgName("_mm_prefetch");
SgType* rtype = SageBuilder::buildVoidType();
SgExpression* arr_arg = this->buildArrArg(scopeStmt);
SgExpression* hint_arg = SageBuilder::buildShortVal(this->cacheHint);
SgExprListExp* args = SageBuilder::buildExprListExp(arr_arg, hint_arg);
return SageBuilder::buildFunctionCallStmt(fname, rtype, args, scopeStmt);
}
SgExpression* MMPrefetchInsertion::buildArrArg(SgScopeStatement* scopeStmt) {
// if there are no index arguments given, just return a variable reference
if(this->indexCount == 0) {
const SgName aname = SgName(this->arrName);
return SageBuilder::buildVarRefExp(aname, scopeStmt);
}
std::vector<SgExpression*> argList = std::vector<SgExpression*>();
// foreach dimension
for(int i = 0; i < this->indexCount; i++) {
argList.push_back(this->makeIndexExp(i, scopeStmt));
}
return SageBuilder::buildExprListExp(argList);
}
SgExpression* MMPrefetchInsertion::makeIndexExp(int dim, SgScopeStatement* scopeStmt) {
//(i + offset) or (offset) or (i)
std::string* indexer = this->indecies.at(dim);
int offset = this->offsets.at(dim);
if(indexer == NULL) {
return SageBuilder::buildIntVal(offset);
}
else {
const SgName name = SgName(*indexer);
SgVarRefExp* iref = SageBuilder::buildVarRefExp(name, scopeStmt);
if(offset == 0) {
return iref;
}
else {
return SageBuilder::buildAddOp(iref, SageBuilder::buildIntVal(offset));
}
}
}
void MMPrefetchInsertion::initialize(const std::string& arrName, int hint) {
this->arrName = std::string(arrName);
this->cacheHint = hint;
this->indecies = std::vector<std::string*>();
this->offsets = std::vector<int>();
this->indexCount = 0;
}
void MMPrefetchInsertion::addDim(int offset) {
this->offsets.push_back(offset);
this->indecies.push_back(NULL);
this->indexCount++;
}
void MMPrefetchInsertion::addDim(int offset, const std::string& indexer) {
this->offsets.push_back(offset);
this->indecies.push_back(new std::string(indexer));
this->indexCount++;
}
}
|