Skip to content

Commit 4f6bbcf

Browse files
committed
CodeGen: Handle VLAs. We use a new bundlle {SHRD,FP,P}.VLA that will have the
expressions (const expr. included) closes llvm#17
1 parent 94b28fa commit 4f6bbcf

File tree

5 files changed

+120
-28
lines changed

5 files changed

+120
-28
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

-2
Original file line numberDiff line numberDiff line change
@@ -9510,7 +9510,5 @@ def err_oss_expected_var_name: Error<
95109510
"expected variable name">;
95119511
def err_oss_non_pod_not_supported: Error<
95129512
"Non-POD structs are not supported">;
9513-
def err_oss_vla_not_supported: Error<
9514-
"VLAs are not supported">;
95159513

95169514
} // end of sema component.

clang/lib/CodeGen/CGOmpSsRuntime.cpp

+78-21
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,35 @@ class OSSDependVisitor
6262

6363
void FillBaseExprDimsAndType(const Expr *E) {
6464
BaseElementTy = E->getType();
65-
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
66-
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
65+
if (BaseElementTy->isArrayType()) {
66+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
67+
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
68+
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(BaseElementTy)){
69+
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
70+
} else {
71+
llvm_unreachable("Unhandled array type");
72+
}
6773
}
6874
QualType TmpTy = E->getType();
6975
// Add Dimensions
70-
if (TmpTy->isPointerType()) {
71-
// T *
72-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
73-
} else if (!TmpTy->isArrayType()) {
74-
// T
76+
if (TmpTy->isPointerType() || !TmpTy->isArrayType()) {
77+
// T * || T
7578
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
7679
}
77-
while (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)){
80+
while (TmpTy->isArrayType()) {
7881
// T []
79-
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
80-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
81-
TmpTy = BaseArrayTy->getElementType();
82+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)) {
83+
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
84+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
85+
TmpTy = BaseArrayTy->getElementType();
86+
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(TmpTy)) {
87+
llvm::Value *DimExpr = CGF.EmitScalarExpr(BaseArrayTy->getSizeExpr());
88+
DimExpr = CGF.Builder.CreateSExt(DimExpr, OSSArgTy);
89+
Dims.push_back(DimExpr);
90+
TmpTy = BaseArrayTy->getElementType();
91+
} else {
92+
llvm_unreachable("Unhandled array type");
93+
}
8294
}
8395
}
8496

@@ -105,18 +117,23 @@ class OSSDependVisitor
105117
}
106118

107119
void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
108-
BaseElementTy = E->getType();
109120
// Get Base Type
110-
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
111-
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
121+
BaseElementTy = E->getType();
122+
if (BaseElementTy->isArrayType()) {
123+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
124+
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
125+
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(BaseElementTy)){
126+
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
127+
} else {
128+
llvm_unreachable("Unhandled array type");
129+
}
112130
}
113131
// Get the inner expr
114132
const Expr *Expr = E;
115133
while (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(Expr->IgnoreParenImpCasts())) {
116134
Expr = ASE->getBase();
117135
// Add indexes
118-
llvm::Value *Idx = ConstantEmitter(CGF).emitAbstract(ASE->getIdx(),
119-
ASE->getIdx()->getType());
136+
llvm::Value *Idx = CGF.EmitScalarExpr(ASE->getIdx());
120137
Idx = CGF.Builder.CreateSExt(Idx, OSSArgTy);
121138
llvm::Value *IdxEnd = CGF.Builder.CreateAdd(Idx, llvm::ConstantInt::getSigned(OSSArgTy, 1));
122139
Starts.push_back(Idx);
@@ -134,11 +151,20 @@ class OSSDependVisitor
134151
// T (*)[]
135152
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
136153
TmpTy = cast<PointerType>(TmpTy)->getPointeeType();
137-
while (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)){
154+
while (TmpTy->isArrayType()) {
138155
// T []
139-
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
140-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
141-
TmpTy = BaseArrayTy->getElementType();
156+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)) {
157+
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
158+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
159+
TmpTy = BaseArrayTy->getElementType();
160+
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(TmpTy)) {
161+
llvm::Value *DimExpr = CGF.EmitScalarExpr(BaseArrayTy->getSizeExpr());
162+
DimExpr = CGF.Builder.CreateSExt(DimExpr, OSSArgTy);
163+
Dims.push_back(DimExpr);
164+
TmpTy = BaseArrayTy->getElementType();
165+
} else {
166+
llvm_unreachable("Unhandled array type");
167+
}
142168
}
143169
} else {
144170
// T *
@@ -182,8 +208,39 @@ class OSSDependVisitor
182208

183209
static void EmitDSA(StringRef Name, CodeGenFunction &CGF, const Expr *E,
184210
SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo) {
211+
// C long -> LLVM long
212+
llvm::Type *OSSArgTy = CGF.ConvertType(CGF.getContext().LongTy);
213+
214+
std::string Basename = Name;
215+
216+
SmallVector<llvm::Value*, 4> DsaData;
217+
SmallVector<llvm::Value*, 4> TmpDsaData; // save all dimensions always. if vla add all of them
185218
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
186-
TaskInfo.emplace_back(Name, CGF.EmitDeclRefLValue(DRE).getPointer());
219+
DsaData.push_back(CGF.EmitDeclRefLValue(DRE).getPointer());
220+
QualType TmpTy = DRE->getType();
221+
bool FirstTime = true;
222+
while (TmpTy->isArrayType()) {
223+
if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(TmpTy)) {
224+
// New type of bundle for vlas
225+
if (FirstTime) {
226+
FirstTime = false;
227+
Basename += ".VLA";
228+
}
229+
llvm::Value *DimExpr = CGF.EmitScalarExpr(BaseArrayTy->getSizeExpr());
230+
DimExpr = CGF.Builder.CreateSExt(DimExpr, OSSArgTy);
231+
DsaData.push_back(DimExpr);
232+
TmpTy = BaseArrayTy->getElementType();
233+
} else if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)) {
234+
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
235+
TmpDsaData.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
236+
TmpTy = BaseArrayTy->getElementType();
237+
} else {
238+
llvm_unreachable("Unhandled array type");
239+
}
240+
}
241+
if (!FirstTime) // We have seen a vla, save dimensions
242+
DsaData.append(TmpDsaData.begin(), TmpDsaData.end());
243+
TaskInfo.emplace_back(Basename, DsaData);
187244
}
188245
else {
189246
llvm_unreachable("Unhandled expression");

clang/lib/Sema/SemaOmpSs.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -800,10 +800,6 @@ getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
800800
S.Diag(ELoc, diag::err_oss_non_pod_not_supported) << ERange;
801801
return nullptr;
802802
}
803-
if (Type->isVariableArrayType()) {
804-
S.Diag(ELoc, diag::err_oss_vla_not_supported) << ERange;
805-
return nullptr;
806-
}
807803
return getCanonicalDecl(VD);
808804
}
809805

clang/test/OmpSs/IR/task_vla.c

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %clang_cc1 -verify -fompss-2 -ferror-limit 100 %s -S -emit-llvm -o - | FileCheck %s
2+
// expected-no-diagnostics
3+
4+
void foo(int n) {
5+
int i;
6+
int array[n][7][n+1][7];
7+
#pragma oss task depend(in: array[i][i+1], *array)
8+
{}
9+
int (*p_array)[n+1][7][n+1][7];
10+
#pragma oss task depend(in: p_array[0])
11+
{}
12+
}
13+
14+
// CHECK: %7 = load i32, i32* %n.addr, align 4
15+
// CHECK-NEXT: %8 = sext i32 %7 to i64
16+
// CHECK-NEXT: %9 = load i32, i32* %n.addr, align 4
17+
// CHECK-NEXT: %add1 = add nsw i32 %9, 1
18+
// CHECK-NEXT: %10 = sext i32 %add1 to i64
19+
// CHECK-NEXT: %11 = load i32, i32* %i, align 4
20+
// CHECK-NEXT: %add2 = add nsw i32 %11, 1
21+
// CHECK-NEXT: %12 = sext i32 %add2 to i64
22+
// CHECK-NEXT: %13 = add i64 %12, 1
23+
// CHECK-NEXT: %14 = load i32, i32* %i, align 4
24+
// CHECK-NEXT: %15 = sext i32 %14 to i64
25+
// CHECK-NEXT: %16 = add i64 %15, 1
26+
// CHECK-NEXT: %17 = load i32, i32* %n.addr, align 4
27+
// CHECK-NEXT: %add3 = add nsw i32 %17, 1
28+
// CHECK-NEXT: %18 = sext i32 %add3 to i64
29+
// CHECK-NEXT: %19 = load i32, i32* %n.addr, align 4
30+
// CHECK-NEXT: %add4 = add nsw i32 %19, 1
31+
// CHECK-NEXT: %20 = sext i32 %add4 to i64
32+
// CHECK-NEXT: %21 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED.VLA"([7 x i32]* %vla, i64 %8, i64 7, i64 %10, i64 7), "QUAL.OSS.FIRSTPRIVATE"(i32* %i), "QUAL.OSS.DEP.IN"([7 x i32]* %vla, i64 28, i64 0, i64 28, i64 %18, i64 0, i64 %18, i64 7, i64 %12, i64 %13, i64 1, i64 %15, i64 %16), "QUAL.OSS.DEP.IN"([7 x i32]* %vla, i64 28, i64 0, i64 28, i64 %20, i64 0, i64 %20, i64 7, i64 0, i64 7) ]
33+
34+
// CHECK: %26 = load [7 x i32]*, [7 x i32]** %p_array, align 8
35+
// CHECK-NEXT: %27 = load i32, i32* %n.addr, align 4
36+
// CHECK-NEXT: %add7 = add nsw i32 %27, 1
37+
// CHECK-NEXT: %28 = sext i32 %add7 to i64
38+
// CHECK-NEXT: %29 = load i32, i32* %n.addr, align 4
39+
// CHECK-NEXT: %add8 = add nsw i32 %29, 1
40+
// CHECK-NEXT: %30 = sext i32 %add8 to i64
41+
// CHECK-NEXT: %31 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"([7 x i32]** %p_array), "QUAL.OSS.DEP.IN"([7 x i32]* %26, i64 28, i64 0, i64 28, i64 %30, i64 0, i64 %30, i64 7, i64 0, i64 7, i64 %28, i64 0, i64 %28, i64 1, i64 0, i64 1) ]

clang/test/OmpSs/Sema/task_non_pods_vlas.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
1616
int e[argc];
1717
D d;
1818
F f;
19-
#pragma oss task shared(a, b, c, d, e, f) // expected-error {{Non-POD structs are not supported}} expected-error {{VLAs are not supported}}
19+
#pragma oss task shared(a, b, c, d, e, f) // expected-error {{Non-POD structs are not supported}}
2020
{ a = *b = c[0] = e[0] = d.x = f.x; }
2121
}
2222

0 commit comments

Comments
 (0)