Skip to content

Commit 9c89fc2

Browse files
committed
multidimensional array initialization and improvements
1 parent bfd0fdf commit 9c89fc2

File tree

1 file changed

+81
-40
lines changed

1 file changed

+81
-40
lines changed

lib/Transform/Clang/RemoveFirstPrivate.cpp

Lines changed: 81 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,20 @@ using namespace tsar;
5050
#undef DEBUG_TYPE
5151
#define DEBUG_TYPE "clang-rfp"
5252

53-
static bool isNameOfArray(std::string type) {
54-
if (type.find('[') != std::string::npos || type.find('*') != std::string::npos) {
55-
return true;
53+
static int getDimensionsNum(QualType qt) {
54+
int res = 0;
55+
if (qt -> isPointerType()) { // todo: multidimensional dynamyc-sized arrays
56+
return 1;
57+
}
58+
while(1) {
59+
if (qt -> isArrayType()) {
60+
auto at = qt->getAsArrayTypeUnsafe();
61+
qt = at -> getElementType();
62+
res++;
63+
} else {
64+
return res;
65+
}
5666
}
57-
return false;
58-
}
59-
60-
static void replaceSqrBrWithAsterisk(std::string &str) {
61-
size_t openingSqrBracket = str.find("[");
62-
size_t closingSqrBracket = str.find("]");
63-
str.erase(openingSqrBracket, closingSqrBracket - openingSqrBracket + 1);
64-
str += "*";
6567
}
6668

6769
namespace {
@@ -78,12 +80,13 @@ class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable {
7880
void getAnalysisUsage(AnalysisUsage &AU) const override;
7981
};
8082

81-
struct vars { // contains information about variables in
82-
std::string var1Type; // removefirstprivate clause
83-
std::string var2Type;
84-
std::string var1Name;
85-
std::string var2Name;
83+
struct vars { // contains information about variables in
84+
bool rvalIsArray = false; // removefirstprivate clause
85+
std::string lvalName;
86+
std::string rvalName;
8687
std::string count = "";
88+
int dimensionsNum;
89+
std::vector<int> dimensions;
8790
};
8891
}
8992

@@ -130,28 +133,43 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
130133
ast = RecursiveASTVisitor::TraverseStmt(S);
131134
isInPragma = false;
132135

133-
std::string txtStr, beforeFor, forBody, type1, type2;
136+
std::string txtStr, beforeFor, forBody, lval, rval, indeces;
134137
std::vector<std::string> inits;
135138
while (varStack.size()) {
136-
if (isNameOfArray(varStack.top().var1Type)) {
139+
for (std::vector<int>::iterator it = varStack.top().dimensions.begin();
140+
it != varStack.top().dimensions.end();
141+
it ++) {
142+
}
143+
if (varStack.top().dimensionsNum) { // lvalue is array
137144
if (varStack.top().count.empty()) {
138145
varStack.pop();
139146
continue; // count is mandatory for arrays, skip initialization if no count found
140147
}
141-
if (type1.find('[') != std::string::npos) {
142-
replaceSqrBrWithAsterisk(type1);
148+
forBody = std::string();
149+
indeces = std::string();
150+
lval = varStack.top().lvalName;
151+
rval = varStack.top().rvalName;
152+
txtStr = std::string();
153+
for (std::vector<int>::iterator it = varStack.top().dimensions.begin();
154+
it != varStack.top().dimensions.end();
155+
it ++) {
156+
int intCounter = it - varStack.top().dimensions.begin();
157+
std::string strCounter = "i" + std::to_string(intCounter);
158+
indeces += "[" + strCounter + "]";
159+
txtStr += "for (int " + strCounter + "; " + strCounter + " < " +
160+
std::to_string(*it) + "; " + strCounter + "++) {\n";
143161
}
144-
if (type2.find('[') != std::string::npos) {
145-
replaceSqrBrWithAsterisk(type2);
162+
if (varStack.top().rvalIsArray) {
163+
rval += indeces;
146164
}
147-
if (isNameOfArray(varStack.top().var2Type)) { // arr1 = arr2
148-
forBody = varStack.top().var1Name + "[i] = " + varStack.top().var2Name + "[i];\n";
149-
} else { // arr1 = val
150-
forBody = varStack.top().var1Name + "[i] = " + varStack.top().var2Name + ";\n";
165+
lval += indeces;
166+
forBody = lval + " = " + rval + ";\n";
167+
txtStr += forBody;
168+
for (int i = 0; i < varStack.top().dimensionsNum; i++) {
169+
txtStr += "}\n";
151170
}
152-
txtStr = "for (int i = 0; i < " + varStack.top().count + "; i++) {\n" + forBody + "\n}\n";
153171
} else { // Initialize non-array variable
154-
txtStr = varStack.top().var1Name + " = " + varStack.top().var2Name + ";\n";
172+
txtStr = varStack.top().lvalName + " = " + varStack.top().rvalName + ";\n";
155173
}
156174
inits.push_back(txtStr);
157175
varStack.pop();
@@ -188,26 +206,34 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
188206
bool TraverseDeclRefExpr(clang::DeclRefExpr *Ex) {
189207
std::string varName;
190208
if (isInPragma) {
209+
if (waitingForDimensions && curDimensionNum == varStack.top().dimensionsNum) {
210+
waitingForDimensions = false;
211+
curDimensionNum = 0;
212+
213+
}
191214
if (auto *Var{dyn_cast<VarDecl>(Ex->getDecl())}) {
192215
varName = Var -> getName();
193216
}
194-
if (waitingForVar) {
217+
if (waitingForVar) { // get lvalue
195218
ValueDecl *vd = Ex -> getDecl();
196219
QualType qt = vd -> getType();
197220
std::string typeStr = qt.getCanonicalType().getAsString();
198-
199221
vars tmp;
200-
tmp.var1Type = typeStr;
201-
tmp.var1Name = varName;
202-
varStack.push(tmp);
203-
204-
} else {
205222

223+
tmp.lvalName = varName;
224+
tmp.dimensionsNum = getDimensionsNum(qt);
225+
varStack.push(tmp);
226+
} else { // get rvalue
206227
ValueDecl *vd = Ex -> getDecl();
207228
QualType qt = vd -> getType();
229+
if (qt -> isArrayType() || qt -> isPointerType()) {
230+
varStack.top().rvalIsArray = true;
231+
}
208232
std::string typeStr = qt.getCanonicalType().getAsString();
209-
varStack.top().var2Type = typeStr;
210-
varStack.top().var2Name = varName;
233+
varStack.top().rvalName = varName;
234+
if (varStack.top().dimensionsNum > 0) {
235+
waitingForDimensions = true;
236+
}
211237

212238
}
213239
waitingForVar = !waitingForVar;
@@ -216,9 +242,21 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
216242
}
217243

218244
bool TraverseIntegerLiteral(IntegerLiteral *IL) {
219-
if (isInPragma && waitingForVar) {
220-
if (varStack.size()) {
221-
varStack.top().count = std::to_string(IL -> getValue().getLimitedValue());
245+
246+
if (isInPragma) {
247+
int val = IL -> getValue().getLimitedValue();
248+
if (waitingForDimensions) {
249+
if (varStack.size()) {
250+
varStack.top().dimensions.push_back(val);
251+
curDimensionNum++;
252+
varStack.top().count = std::to_string(val);
253+
}
254+
} else if (!waitingForVar) { // get rvalue
255+
varStack.top().rvalName = std::to_string(val);
256+
waitingForVar = !waitingForVar;
257+
if (varStack.top().dimensionsNum > 0) {
258+
waitingForDimensions = true;
259+
}
222260
}
223261
}
224262
return RecursiveASTVisitor::TraverseIntegerLiteral(IL);
@@ -239,6 +277,9 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
239277

240278
bool isInPragma = false;
241279
bool waitingForVar = true;
280+
bool waitingForDimensions = false;
281+
int curDimensionNum = 0;
282+
242283
std::vector<Stmt*> mScopes;
243284

244285
TransformationContext *mTfmCtx;

0 commit comments

Comments
 (0)