Skip to content

Commit 9456673

Browse files
committed
Merge branch 'sotoc-new-variable-handling' into 'aurora_offloading_prototype'
New (and hopefully correct) Variable Handling for Sotoc Closes llvm#51 See merge request NEC-RWTH-Projects/clang!30
2 parents b0d9820 + e9aba95 commit 9456673

File tree

10 files changed

+429
-352
lines changed

10 files changed

+429
-352
lines changed

clang/tools/sotoc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(USE_CLANG_LIBS clangFrontend
2828
set(SOTOC_SOURCES src/main.cpp
2929
src/TargetCode.cpp
3030
src/TargetCodeFragment.cpp
31+
src/TargetRegionVariable.cpp
3132
src/Visitors.cpp
3233
src/DeclResolver.cpp
3334
src/OmpPragma.cpp)

clang/tools/sotoc/src/OmpPragma.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class OmpPragma {
3737

3838
public:
3939
OmpPragma(TargetCodeRegion *TCR)
40-
: PP(TCR->getPP()), Clauses(*TCR->getOMPClauses()),
40+
: PP(TCR->getPP()), Clauses(TCR->getOMPClauses()),
4141
Kind(TCR->getTargetCodeKind()){};
4242
OmpPragma(clang::OMPExecutableDirective *Directive, clang::PrintingPolicy PP)
4343
: PP(PP), Clauses(Directive->clauses()),

clang/tools/sotoc/src/TargetCode.cpp

Lines changed: 79 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -108,112 +108,104 @@ void TargetCode::generateFunctionPrologue(TargetCodeRegion *TCR,
108108
std::string elemType;
109109
bool first = true;
110110
Out << "void " << generateFunctionName(TCR) << "(";
111-
for (auto i = TCR->getCapturedVarsBegin(), e = TCR->getCapturedVarsEnd();
112-
i != e; ++i) {
113-
std::string VarName = (*i)->getDeclName().getAsString();
114-
auto C = TCR->GetReferredOMPClause(*i);
111+
112+
for (auto &Var : TCR->capturedVars()) {
115113
if (!first) {
116114
Out << ", ";
117115
}
118116
first = false;
119117

120-
// check for constant or variable length arrays, because of
121-
// AST representation and naive getType
122-
if (auto t = clang::dyn_cast_or_null<clang::ArrayType>(
123-
(*i)->getType().getTypePtr())) {
124-
DEBUGP("Generating code for array type");
125-
int dim = 0;
126-
127-
std::vector<int> VariableDimensions;
128-
handleArrays(&t, DimString, dim, VariableDimensions, TCR, elemType,
129-
VarName);
130-
131-
for (int d : VariableDimensions) {
132-
Out << "unsigned long long __sotoc_vla_dim" << d << "_" << VarName
118+
if (Var.isArray()) {
119+
for (const unsigned int &d : Var.variabledSizedArrayDimensions()) {
120+
Out << "unsigned long long __sotoc_vla_dim" << d << "_" << Var.name()
133121
<< ", ";
134122
}
123+
}
124+
// Because arrays are passed by reference and (for our purposes) their type
125+
// is 'void', the rest of their handling ist the same as for scalars.
126+
if (Var.isArray()) {
127+
Out << "void ";
128+
} else {
129+
Out << Var.typeName() << " ";
130+
}
135131

136-
// set type to void* to avoid warnings from the compiler
137-
Out << "void *__sotoc_var_";
138-
nDim.push_back(dim); // push total number of dimensions
132+
if (Var.passedByPointer()) {
133+
Out << "*__sotoc_var_";
134+
}
135+
Out << Var.name();
136+
}
137+
138+
for (auto *ClauseVar : TCR->ompClausesParams()) {
139+
if (!first) {
140+
Out << ", ";
139141
} else {
140-
Out << (*i)->getType().getAsString() << " ";
141-
if (!(*i)->getType().getTypePtr()->isPointerType()) {
142-
if (C) {
143-
// Parameters which are not first private (e.g., explicit mapped vars)
144-
// are passed by reference, all others by value.
145-
if (C->getClauseKind() !=
146-
clang::OpenMPClauseKind::OMPC_firstprivate &&
147-
C->getClauseKind() !=
148-
clang::OpenMPClauseKind::OMPC_private &&
149-
C->getClauseKind() !=
150-
clang::OpenMPClauseKind::OMPC_depend) {
151-
Out << "*__sotoc_var_";
152-
}
153-
}
142+
first = false;
143+
}
144+
145+
// TODO: this is the same code as in TargetRegionVariable.cpp, so we might
146+
// want to deduplicated this.
147+
auto *ClauseVarType = ClauseVar->getType().getTypePtr();
148+
if (auto *AT = llvm::dyn_cast<clang::ArrayType>(ClauseVarType)) {
149+
while (auto *NAT = llvm::dyn_cast<clang::ArrayType>(AT->getElementType().getTypePtr())) {
150+
AT = NAT;
154151
}
152+
Out << AT->getElementType().getAsString() << " *";
153+
} else {
154+
Out << ClauseVar->getType().getAsString() << " ";
155155
}
156-
Out << VarName;
156+
Out << ClauseVar->getName();
157157
}
158+
158159
Out << ")\n{\n";
159160

160161
// bring captured scalars into scope
161-
for (auto I = TCR->getCapturedVarsBegin(), E = TCR->getCapturedVarsEnd();
162-
I != E; ++I) {
163-
auto C = TCR->GetReferredOMPClause(*I);
164-
// again check for constant and variable-length arrays
165-
if (auto t = clang::dyn_cast_or_null<clang::ArrayType>(
166-
(*I)->getType().getTypePtr())) {
167-
auto VarName = (*I)->getDeclName().getAsString();
168-
169-
do {
170-
t = clang::dyn_cast_or_null<clang::ArrayType>(
171-
t->getElementType().getTypePtr());
172-
} while (t != NULL);
173-
174-
Out << " " << elemType << " (*" << VarName << ")";
175-
176-
// Get number of Dimensions(nDim) and write sizes(DimString)
177-
for (int i = 1; i < nDim.front(); i++) {
178-
DimString.pop_front();
179-
Out << "[" << DimString.front() << "]";
180-
}
181-
DimString.pop_front(); // remove last size
182-
nDim.pop_front(); // remove number of dimensions of last variable
183-
184-
Out << " = __sotoc_var_" << VarName << ";\n";
185-
186-
auto LowerBound = TCR->CapturedLowerBounds.find(*I);
187-
if (LowerBound != TCR->CapturedLowerBounds.end()) {
188-
Out << VarName << " = " << VarName << " - (";
189-
LowerBound->second->printPretty(Out, NULL, TCR->getPP());
190-
Out << ");\n";
191-
}
192-
193-
} else {
194-
if (!(*I)->getType().getTypePtr()->isPointerType()) {
195-
if (C) {
196-
// Parameters which are not first private (e.g., explicit mapped vars)
197-
// are passed by reference, all others by value.
198-
if (C->getClauseKind() !=
199-
clang::OpenMPClauseKind::OMPC_firstprivate &&
200-
C->getClauseKind() !=
201-
clang::OpenMPClauseKind::OMPC_private &&
202-
C->getClauseKind() !=
203-
clang::OpenMPClauseKind::OMPC_depend) {
204-
auto VarName = (*I)->getDeclName().getAsString();
205-
Out << " " << (*I)->getType().getAsString() << " " << VarName
206-
<< " = "
207-
<< "*__sotoc_var_" << VarName << ";\n";
162+
for (auto &Var : TCR->capturedVars()) {
163+
// Ignore everything not passed by reference here
164+
if (Var.passedByPointer()) {
165+
// Handle multi-dimensional arrays
166+
if (Var.isArray()) {
167+
// Declare the arrays as a pointer. This way we can assign it a pointer
168+
// However, this also means we have to ignore the first array
169+
// dimension.
170+
Out << " " << Var.typeName() << " (*" << Var.name() << ")";
171+
172+
// For every array dimension other then the first: declare them by
173+
// adding the array brackets ('[', ']') to the declaration. Also add
174+
// the size of this dimension if we have it.
175+
bool first = true;
176+
for (auto &dimensionSize: Var.arrayDimensionSizes()) {
177+
//We need to discard the first element
178+
if (first) {
179+
first = false;
180+
continue;
208181
}
182+
Out << "[" << dimensionSize << "]";
183+
}
184+
// After we have declare the array, we also need to assign it.
185+
// We may also have to adjust the array bounds if we only get a slice
186+
// of the array (in the first dimesion. All other dimensions should
187+
// not require adjustment as their slicing is ignored)
188+
Out << " = __sotoc_var_" << Var.name() << ";\n";
189+
// Move the bounds if we have a slice
190+
auto LowerBound = Var.arrayLowerBound();
191+
if (LowerBound.hasValue()) {
192+
Out << " " << Var.name() << " = " << Var.name() << " - ";
193+
LowerBound.getValue()->printPretty(Out, NULL, TCR->getPP());
194+
Out << ";\n";
209195
}
196+
} else {
197+
// Handle all other types passed by reference
198+
Out << Var.typeName() << " " << Var.name() << " = "
199+
<< "*__sotoc_var_" << Var.name() << ";\n";
210200
}
211201
}
212202
}
213-
Out << "\n";
214203

215204
// Generate local declarations.
216-
Out << TCR->PrintLocalVarsFromClauses();
205+
for (auto *privateVar: TCR->privateVars()) {
206+
Out << " " << privateVar->getType().getAsString() << " "
207+
<< privateVar->getName() << ";\n";
208+
}
217209

218210
// The runtime can decide to only create one team.
219211
// Therfore, replace target teams constructs.
@@ -235,31 +227,9 @@ void TargetCode::generateFunctionEpilogue(TargetCodeRegion *TCR,
235227

236228
Out << "\n";
237229
// copy values from scalars from scoped vars back into pointers
238-
for (auto I = TCR->getCapturedVarsBegin(), E = TCR->getCapturedVarsEnd();
239-
I != E; ++I) {
240-
auto C = TCR->GetReferredOMPClause(*I);
241-
242-
// if array then already pointer
243-
if (auto t = clang::dyn_cast_or_null<clang::ArrayType>(
244-
(*I)->getType().getTypePtr())) {
245-
auto VarName = (*I)->getDeclName().getAsString();
246-
Out << "\n __sotoc_var_" << VarName << " = " << VarName << ";";
247-
} else {
248-
if (!(*I)->getType().getTypePtr()->isPointerType()) {
249-
if (C) {
250-
// Parameters which are not first private (e.g., explicit mapped vars)
251-
// are passed by reference, all others by value.
252-
if (C->getClauseKind() !=
253-
clang::OpenMPClauseKind::OMPC_firstprivate &&
254-
C->getClauseKind() !=
255-
clang::OpenMPClauseKind::OMPC_private &&
256-
C->getClauseKind() !=
257-
clang::OpenMPClauseKind::OMPC_depend) {
258-
auto VarName = (*I)->getDeclName().getAsString();
259-
Out << "\n *__sotoc_var_" << VarName << " = " << VarName << ";";
260-
}
261-
}
262-
}
230+
for (auto &Var : TCR->capturedVars()) {
231+
if (Var.passedByPointer() && !Var.isArray()) {
232+
Out << "\n *__sotoc_var_" << Var.name() << " = " << Var.name() << ";";
263233
}
264234
}
265235

@@ -283,48 +253,3 @@ std::string TargetCode::generateFunctionName(TargetCodeRegion *TCR) {
283253
<< LineNum;
284254
return FunctionName;
285255
}
286-
287-
void TargetCode::handleArrays(const clang::ArrayType **t,
288-
std::list<std::string> &DimString, int &dim,
289-
std::vector<int> &VariableDims,
290-
TargetCodeRegion *TCR, std::string &elemType,
291-
const std::string &ArrayName) {
292-
auto OrigT = *t;
293-
294-
if (!t) {
295-
return;
296-
} else {
297-
// We just remember the last element type
298-
elemType = OrigT->getElementType().getAsString();
299-
DEBUGP("The last QualType of the array is: " + elemType);
300-
}
301-
302-
if (auto t1 = clang::dyn_cast_or_null<clang::ConstantArrayType>(OrigT)) {
303-
DEBUGP("ArrayType is CAT");
304-
DimString.push_back(t1->getSize().toString(10, false));
305-
++dim;
306-
307-
} else if (auto t1 =
308-
clang::dyn_cast_or_null<clang::VariableArrayType>(OrigT)) {
309-
DEBUGP("ArrayType VAT");
310-
std::string PrettyStr = "";
311-
llvm::raw_string_ostream PrettyOS(PrettyStr);
312-
PrettyOS << "__sotoc_vla_dim" << dim << "_" << ArrayName;
313-
DimString.push_back(PrettyOS.str());
314-
VariableDims.push_back(dim);
315-
++dim;
316-
317-
} else {
318-
DEBUGP("No more array dimensions");
319-
// Restore t if we dont have an array type anymore
320-
*t = OrigT;
321-
return;
322-
}
323-
324-
(*t) = clang::dyn_cast_or_null<clang::ArrayType>(
325-
OrigT->getElementType().getTypePtr());
326-
if (*t) {
327-
// Recursively handle all dimensions
328-
handleArrays(t, DimString, dim, VariableDims, TCR, elemType, ArrayName);
329-
}
330-
}

clang/tools/sotoc/src/TargetCode.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,4 @@ class TargetCode {
7474
void generateFunctionEpilogue(TargetCodeRegion *TCR, llvm::raw_ostream &Out);
7575
/// Generate a function name for a target region.
7676
std::string generateFunctionName(TargetCodeRegion *TCR);
77-
78-
/// This function recursively handles constant and variable-length array types
79-
/// and any mixed forms. Incomplete array types are not supported at the
80-
/// moment.
81-
/// \param t The (n-dimensional) array
82-
/// \param DimString A list of string which returns one entry per dimension
83-
/// \param dim The dimension count
84-
/// \param TCR The target code region
85-
/// \param returns the last element type (i.e., the type of the array)
86-
void handleArrays(const clang::ArrayType **t,
87-
std::list<std::string> &DimString, int &dim,
88-
std::vector<int> &VariableDimensions, TargetCodeRegion *TCR,
89-
std::string &elemType, const std::string &ArrayName);
9077
};

0 commit comments

Comments
 (0)