Skip to content

Commit 812f3a4

Browse files
committed
Rework ArraySubscript to emit last array dimension instead of 1. Move some duplicated code into funcitions
Closes llvm#23
1 parent 1d9e13b commit 812f3a4

File tree

3 files changed

+59
-94
lines changed

3 files changed

+59
-94
lines changed

clang/lib/CodeGen/CGOmpSsRuntime.cpp

Lines changed: 53 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,21 @@ class OSSDependVisitor
6060
// Utilities
6161
//===--------------------------------------------------------------------===//
6262

63-
void FillBaseExprDimsAndType(const Expr *E) {
64-
BaseElementTy = E->getType();
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);
63+
QualType GetInnermostElementType(const QualType &Q) {
64+
if (Q->isArrayType()) {
65+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(Q)) {
66+
return CGF.getContext().getBaseElementType(Q);
67+
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(Q)) {
68+
return CGF.getContext().getBaseElementType(Q);
7069
} else {
7170
llvm_unreachable("Unhandled array type");
7271
}
7372
}
73+
return Q;
74+
}
75+
76+
void FillBaseExprDimsAndType(const Expr *E) {
77+
BaseElementTy = GetInnermostElementType(E->getType());
7478
QualType TmpTy = E->getType();
7579
// Add Dimensions
7680
if (TmpTy->isPointerType() || !TmpTy->isArrayType()) {
@@ -94,6 +98,34 @@ class OSSDependVisitor
9498
}
9599
}
96100

101+
// This is used in the innermost Expr * in ArraySubscripts and OSSArraySection
102+
void FillDimsFromInnermostExpr(const Expr *E) {
103+
// Go through the expression which may be a DeclRefExpr or MemberExpr
104+
E = E->IgnoreParenImpCasts();
105+
QualType TmpTy = E->getType();
106+
// Add Dimensions
107+
if (TmpTy->isPointerType()) {
108+
// T *
109+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
110+
TmpTy = TmpTy->getPointeeType();
111+
}
112+
while (TmpTy->isArrayType()) {
113+
// T []
114+
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)) {
115+
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
116+
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
117+
TmpTy = BaseArrayTy->getElementType();
118+
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(TmpTy)) {
119+
auto VlaSize = CGF.getVLAElements1D(BaseArrayTy);
120+
llvm::Value *DimExpr = CGF.Builder.CreateSExt(VlaSize.NumElts, OSSArgTy);
121+
Dims.push_back(DimExpr);
122+
TmpTy = BaseArrayTy->getElementType();
123+
} else {
124+
llvm_unreachable("Unhandled array type");
125+
}
126+
}
127+
}
128+
97129
//===--------------------------------------------------------------------===//
98130
// Visitor Methods
99131
//===--------------------------------------------------------------------===//
@@ -119,18 +151,9 @@ class OSSDependVisitor
119151
void VisitOSSArraySectionExpr(const OSSArraySectionExpr *E) {
120152
// Get Base Type
121153
// An array section is considered a built-in type
122-
BaseElementTy = OSSArraySectionExpr::getBaseOriginalType(
123-
E->getBase()->IgnoreParenImpCasts())
124-
.getCanonicalType();
125-
if (BaseElementTy->isArrayType()) {
126-
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
127-
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
128-
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(BaseElementTy)){
129-
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
130-
} else {
131-
llvm_unreachable("Unhandled array type");
132-
}
133-
}
154+
BaseElementTy = GetInnermostElementType(
155+
OSSArraySectionExpr::getBaseOriginalType(
156+
E->getBase()));
134157
// Get the inner expr
135158
const Expr *TmpE = E;
136159
// First come OSSArraySection
@@ -143,7 +166,7 @@ class OSSDependVisitor
143166
if (LowerB)
144167
Idx = CGF.EmitScalarExpr(LowerB);
145168
else
146-
// OpenMP 5.0 2.1.5 When the lower-bound is absent it defaults to 0.
169+
// OpenMP 5.0 2.1.5 When the lower-bound is absent it defaults to 0.
147170
Idx = llvm::ConstantInt::getSigned(OSSArgTy, 0);
148171
Idx = CGF.Builder.CreateSExt(Idx, OSSArgTy);
149172

@@ -190,93 +213,35 @@ class OSSDependVisitor
190213
llvm::Value *IdxEnd = CGF.Builder.CreateAdd(Idx, llvm::ConstantInt::getSigned(OSSArgTy, 1));
191214
Starts.push_back(Idx);
192215
Ends.push_back(IdxEnd);
216+
// Stop in the innermost ArrayToPointerDecay
193217
if (TmpE->IgnoreParenImpCasts()->getType()->isPointerType())
194218
break;
195219
}
196220

197221
Ptr = CGF.EmitScalarExpr(TmpE);
198-
199-
TmpE = TmpE->IgnoreParenImpCasts();
200-
201-
QualType TmpTy = TmpE->getType();
202-
// Add Dimensions
203-
if (TmpTy->isPointerType()) {
204-
// T *
205-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
206-
} else {
207-
while (TmpTy->isArrayType()) {
208-
// T []
209-
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)) {
210-
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
211-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
212-
TmpTy = BaseArrayTy->getElementType();
213-
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(TmpTy)) {
214-
auto VlaSize = CGF.getVLAElements1D(BaseArrayTy);
215-
llvm::Value *DimExpr = CGF.Builder.CreateSExt(VlaSize.NumElts, OSSArgTy);
216-
Dims.push_back(DimExpr);
217-
TmpTy = BaseArrayTy->getElementType();
218-
} else {
219-
llvm_unreachable("Unhandled array type");
220-
}
221-
}
222-
}
222+
FillDimsFromInnermostExpr(TmpE);
223223
}
224224

225225
void VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
226226
// Get Base Type
227-
BaseElementTy = E->getType();
228-
if (BaseElementTy->isArrayType()) {
229-
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(BaseElementTy)){
230-
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
231-
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(BaseElementTy)){
232-
BaseElementTy = CGF.getContext().getBaseElementType(BaseElementTy);
233-
} else {
234-
llvm_unreachable("Unhandled array type");
235-
}
236-
}
227+
BaseElementTy = GetInnermostElementType(E->getType());
237228
// Get the inner expr
238-
const Expr *Expr = E;
239-
while (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(Expr->IgnoreParenImpCasts())) {
240-
Expr = ASE->getBase();
229+
const Expr *TmpE = E;
230+
while (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(TmpE->IgnoreParenImpCasts())) {
231+
TmpE = ASE->getBase();
241232
// Add indexes
242233
llvm::Value *Idx = CGF.EmitScalarExpr(ASE->getIdx());
243234
Idx = CGF.Builder.CreateSExt(Idx, OSSArgTy);
244235
llvm::Value *IdxEnd = CGF.Builder.CreateAdd(Idx, llvm::ConstantInt::getSigned(OSSArgTy, 1));
245236
Starts.push_back(Idx);
246237
Ends.push_back(IdxEnd);
247-
if (Expr->IgnoreParenImpCasts()->getType()->isPointerType())
238+
// Stop in the innermost ArrayToPointerDecay
239+
if (TmpE->IgnoreParenImpCasts()->getType()->isPointerType())
248240
break;
249241
}
250242

251-
Ptr = CGF.EmitScalarExpr(Expr);
252-
253-
if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
254-
QualType TmpTy = CE->getType();
255-
// Add Dimensions
256-
if (TmpTy->isPointerType()) {
257-
// T (*)[]
258-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
259-
TmpTy = cast<PointerType>(TmpTy)->getPointeeType();
260-
while (TmpTy->isArrayType()) {
261-
// T []
262-
if (const ConstantArrayType *BaseArrayTy = CGF.getContext().getAsConstantArrayType(TmpTy)) {
263-
uint64_t DimSize = BaseArrayTy->getSize().getSExtValue();
264-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, DimSize));
265-
TmpTy = BaseArrayTy->getElementType();
266-
} else if (const VariableArrayType *BaseArrayTy = CGF.getContext().getAsVariableArrayType(TmpTy)) {
267-
auto VlaSize = CGF.getVLAElements1D(BaseArrayTy);
268-
llvm::Value *DimExpr = CGF.Builder.CreateSExt(VlaSize.NumElts, OSSArgTy);
269-
Dims.push_back(DimExpr);
270-
TmpTy = BaseArrayTy->getElementType();
271-
} else {
272-
llvm_unreachable("Unhandled array type");
273-
}
274-
}
275-
} else {
276-
// T *
277-
Dims.push_back(llvm::ConstantInt::getSigned(OSSArgTy, 1));
278-
}
279-
}
243+
Ptr = CGF.EmitScalarExpr(TmpE);
244+
FillDimsFromInnermostExpr(TmpE);
280245
}
281246

282247
void VisitMemberExpr(const MemberExpr *E) {

clang/test/OmpSs/IR/task_depend1.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void foo(void) {
1010
}
1111

1212
// CHECK: %arraydecay = getelementptr inbounds [5 x i32], [5 x i32]* %ai, i64 0, i64 0
13-
// CHECK-NEXT: %0 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"(i32* %i), "QUAL.OSS.SHARED"([5 x i32]* %ai), "QUAL.OSS.FIRSTPRIVATE"(i32** %pi), "QUAL.OSS.DEP.IN"(i32* %i, i64 4, i64 0, i64 4), "QUAL.OSS.DEP.IN"(i32** %pi, i64 8, i64 0, i64 8), "QUAL.OSS.DEP.IN"(i32* %arraydecay, i64 4, i64 12, i64 16) ]
13+
// CHECK-NEXT: %0 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"(i32* %i), "QUAL.OSS.SHARED"([5 x i32]* %ai), "QUAL.OSS.FIRSTPRIVATE"(i32** %pi), "QUAL.OSS.DEP.IN"(i32* %i, i64 4, i64 0, i64 4), "QUAL.OSS.DEP.IN"(i32** %pi, i64 8, i64 0, i64 8), "QUAL.OSS.DEP.IN"(i32* %arraydecay, i64 20, i64 12, i64 16) ]
1414
// CHECK-NEXT: %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* %ai, i64 0, i64 2
1515
// CHECK-NEXT: %1 = load i32, i32* %arrayidx, align 8
1616
// CHECK-NEXT: %2 = load i32*, i32** %pi, align 8
@@ -31,7 +31,7 @@ void foo1(void) {
3131
{ foo1_var = *foo1_ptr = foo1_array[3] = foo1_s.x; }
3232
}
3333

34-
// CHECK: %1 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"(i32* @foo1_var), "QUAL.OSS.SHARED"([5 x i32]* @foo1_array), "QUAL.OSS.SHARED"(%struct.Foo1_struct* @foo1_s), "QUAL.OSS.FIRSTPRIVATE"(i32** @foo1_ptr), "QUAL.OSS.DEP.IN"(i32* @foo1_var, i64 4, i64 0, i64 4), "QUAL.OSS.DEP.IN"(i32* %0, i64 4, i64 0, i64 4), "QUAL.OSS.DEP.IN"(i32* getelementptr inbounds ([5 x i32], [5 x i32]* @foo1_array, i64 0, i64 0), i64 4, i64 12, i64 16), "QUAL.OSS.DEP.IN"(i32* getelementptr inbounds ([5 x i32], [5 x i32]* @foo1_array, i64 0, i64 0), i64 4, i64 -8, i64 -4), "QUAL.OSS.DEP.IN"(i32* getelementptr inbounds (%struct.Foo1_struct, %struct.Foo1_struct* @foo1_s, i32 0, i32 0), i64 4, i64 0, i64 4) ]
34+
// CHECK: %1 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"(i32* @foo1_var), "QUAL.OSS.SHARED"([5 x i32]* @foo1_array), "QUAL.OSS.SHARED"(%struct.Foo1_struct* @foo1_s), "QUAL.OSS.FIRSTPRIVATE"(i32** @foo1_ptr), "QUAL.OSS.DEP.IN"(i32* @foo1_var, i64 4, i64 0, i64 4), "QUAL.OSS.DEP.IN"(i32* %0, i64 4, i64 0, i64 4), "QUAL.OSS.DEP.IN"(i32* getelementptr inbounds ([5 x i32], [5 x i32]* @foo1_array, i64 0, i64 0), i64 20, i64 12, i64 16), "QUAL.OSS.DEP.IN"(i32* getelementptr inbounds ([5 x i32], [5 x i32]* @foo1_array, i64 0, i64 0), i64 20, i64 -8, i64 -4), "QUAL.OSS.DEP.IN"(i32* getelementptr inbounds (%struct.Foo1_struct, %struct.Foo1_struct* @foo1_s, i32 0, i32 0), i64 4, i64 0, i64 4) ]
3535
// CHECK-NEXT: %2 = load i32, i32* getelementptr inbounds (%struct.Foo1_struct, %struct.Foo1_struct* @foo1_s, i32 0, i32 0), align 4
3636
// CHECK-NEXT: store i32 %2, i32* getelementptr inbounds ([5 x i32], [5 x i32]* @foo1_array, i64 0, i64 3), align 4
3737
// CHECK-NEXT: %3 = load i32*, i32** @foo1_ptr, align 8

clang/test/OmpSs/IR/task_depend2.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ void foo1() {
3030
// CHECK: %arraydecay = getelementptr inbounds [5 x [6 x i32]], [5 x [6 x i32]]* %b, i64 0, i64 0
3131
// CHECK-NEXT: %arraydecay1 = getelementptr inbounds [5 x [6 x i32]], [5 x [6 x i32]]* %b, i64 0, i64 0
3232
// CHECK-NEXT: %arraydecay2 = getelementptr inbounds [5 x [6 x i32]], [5 x [6 x i32]]* %b, i64 0, i64 0
33-
// CHECK-NEXT: %5 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"([5 x [6 x i32]]* %b), "QUAL.OSS.DEP.IN"([5 x [6 x i32]]* %b, i64 24, i64 0, i64 24, i64 5, i64 0, i64 5), "QUAL.OSS.DEP.IN"([6 x i32]* %arraydecay, i64 24, i64 0, i64 24), "QUAL.OSS.DEP.IN"([6 x i32]* %arraydecay1, i64 24, i64 0, i64 24, i64 1, i64 1, i64 2), "QUAL.OSS.DEP.IN"([6 x i32]* %arraydecay2, i64 24, i64 8, i64 12, i64 1, i64 1, i64 2) ]
33+
// CHECK-NEXT: %5 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"([5 x [6 x i32]]* %b), "QUAL.OSS.DEP.IN"([5 x [6 x i32]]* %b, i64 24, i64 0, i64 24, i64 5, i64 0, i64 5), "QUAL.OSS.DEP.IN"([6 x i32]* %arraydecay, i64 24, i64 0, i64 24), "QUAL.OSS.DEP.IN"([6 x i32]* %arraydecay1, i64 24, i64 0, i64 24, i64 5, i64 1, i64 2), "QUAL.OSS.DEP.IN"([6 x i32]* %arraydecay2, i64 24, i64 8, i64 12, i64 5, i64 1, i64 2) ]
3434
// CHECK-NEXT: call void @llvm.directive.region.exit(token %5)
3535

3636
// CHECK: %arraydecay3 = getelementptr inbounds [5 x [6 x [7 x i32]]], [5 x [6 x [7 x i32]]]* %d, i64 0, i64 0
37-
// CHECK-NEXT: %10 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"([5 x [6 x [7 x i32]]]* %d), "QUAL.OSS.DEP.IN"([5 x [6 x [7 x i32]]]* %d, i64 28, i64 0, i64 28, i64 6, i64 0, i64 6, i64 5, i64 0, i64 5), "QUAL.OSS.DEP.IN"([6 x [7 x i32]]* %arraydecay3, i64 28, i64 12, i64 16, i64 6, i64 2, i64 3, i64 1, i64 1, i64 2) ]
37+
// CHECK-NEXT: %10 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"([5 x [6 x [7 x i32]]]* %d), "QUAL.OSS.DEP.IN"([5 x [6 x [7 x i32]]]* %d, i64 28, i64 0, i64 28, i64 6, i64 0, i64 6, i64 5, i64 0, i64 5), "QUAL.OSS.DEP.IN"([6 x [7 x i32]]* %arraydecay3, i64 28, i64 12, i64 16, i64 6, i64 2, i64 3, i64 5, i64 1, i64 2) ]
3838
// CHECK-NEXT: call void @llvm.directive.region.exit(token %10)
3939

4040
// CHECK: %arraydecay4 = getelementptr inbounds [5 x i32], [5 x i32]* %e, i64 0, i64 0
41-
// CHECK-NEXT: %11 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"([5 x i32]* %e), "QUAL.OSS.DEP.IN"([5 x i32]* %e, i64 20, i64 0, i64 20), "QUAL.OSS.DEP.IN"(i32* %arraydecay4, i64 4, i64 4, i64 8) ]
41+
// CHECK-NEXT: %11 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"([5 x i32]* %e), "QUAL.OSS.DEP.IN"([5 x i32]* %e, i64 20, i64 0, i64 20), "QUAL.OSS.DEP.IN"(i32* %arraydecay4, i64 20, i64 4, i64 8) ]
4242
// CHECK-NEXT: call void @llvm.directive.region.exit(token %11)
4343

4444
void foo2() {
@@ -71,7 +71,7 @@ void foo2() {
7171
// CHECK: %x1 = getelementptr inbounds %struct.B, %struct.B* %b, i32 0, i32 0
7272
// CHECK-NEXT: %x2 = getelementptr inbounds %struct.B, %struct.B* %b, i32 0, i32 0
7373
// CHECK-NEXT: %arraydecay = getelementptr inbounds [10 x i32], [10 x i32]* %x2, i64 0, i64 0
74-
// CHECK-NEXT: %1 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"(%struct.B* %b), "QUAL.OSS.DEP.IN"([10 x i32]* %x1, i64 40, i64 0, i64 40), "QUAL.OSS.DEP.IN"(i32* %arraydecay, i64 4, i64 0, i64 4) ]
74+
// CHECK-NEXT: %1 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.SHARED"(%struct.B* %b), "QUAL.OSS.DEP.IN"([10 x i32]* %x1, i64 40, i64 0, i64 40), "QUAL.OSS.DEP.IN"(i32* %arraydecay, i64 40, i64 0, i64 4) ]
7575
// CHECK-NEXT: call void @llvm.directive.region.exit(token %1)
7676

7777
// CHECK: %x3 = getelementptr inbounds %struct.C, %struct.C* %c, i32 0, i32 0

0 commit comments

Comments
 (0)