Skip to content

Commit 2a2f42b

Browse files
committed
[OpenACC][CIR] Implement routine 'bind'-with-a-string lowering
The 'bind' clause emits an attribute on the RoutineOp that states which function it should call on the device side. When provided in double-quotes, the function on the device side should be the exact name given. This patch emits the IR to do that. As a part of that, we add a helper function to the OpenACC dialect to do so, as well as a version that adds the ID version (though we don't exercise th at yet). The 'bind' with an ID should do the MANGLED name, but it isn't quite clear what that name SHOULD be yet. Since the signature of a function is included in its mangling, and we're not providing said signature, we have to come up with something. This is left as an exercise for a future patch.
1 parent bb17dfa commit 2a2f42b

File tree

5 files changed

+139
-0
lines changed

5 files changed

+139
-0
lines changed

clang/lib/CIR/CodeGen/CIRGenDeclOpenACC.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,20 @@ class OpenACCRoutineClauseEmitter final
362362
for (const DeviceTypeArgument &arg : clause.getArchitectures())
363363
lastDeviceTypeValues.push_back(decodeDeviceType(arg.getIdentifierInfo()));
364364
}
365+
366+
void VisitBindClause(const OpenACCBindClause &clause) {
367+
if (clause.isStringArgument()) {
368+
mlir::StringAttr value =
369+
builder.getStringAttr(clause.getStringArgument()->getString());
370+
371+
routineOp.addBindStrName(builder.getContext(), lastDeviceTypeValues,
372+
value);
373+
} else {
374+
assert(clause.isIdentifierArgument());
375+
cgm.errorNYI(clause.getSourceRange(),
376+
"Bind with an identifier argument is not yet supported");
377+
}
378+
}
365379
};
366380
} // namespace
367381

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %clang_cc1 -fopenacc -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir %s -o - | FileCheck %s
2+
3+
#pragma acc routine seq bind("BIND1")
4+
void Func1(){}
5+
6+
void Func2(){}
7+
#pragma acc routine(Func2) seq bind("BIND2")
8+
9+
#pragma acc routine seq device_type(nvidia) bind("BIND3")
10+
void Func3(){}
11+
12+
void Func4(){}
13+
#pragma acc routine(Func4) seq device_type(radeon) bind("BIND4")
14+
15+
#pragma acc routine seq device_type(nvidia, host) bind("BIND5_N") device_type(multicore) bind("BIND5_M")
16+
void Func5(){}
17+
18+
void Func6(){}
19+
#pragma acc routine(Func6) seq device_type(radeon) bind("BIND6_R") device_type(multicore, host) bind("BIND6_M")
20+
21+
// CHECK: cir.func{{.*}} @[[F1_NAME:.*Func1[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F1_R_NAME:.*]]]>}
22+
// CHECK: acc.routine @[[F1_R_NAME]] func(@[[F1_NAME]]) bind("BIND1") seq
23+
//
24+
// CHECK: cir.func{{.*}} @[[F2_NAME:.*Func2[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F2_R_NAME:.*]]]>}
25+
//
26+
// CHECK: cir.func{{.*}} @[[F3_NAME:.*Func3[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F3_R_NAME:.*]]]>}
27+
// CHECK: acc.routine @[[F3_R_NAME]] func(@[[F3_NAME]]) bind("BIND3" [#acc.device_type<nvidia>]) seq
28+
//
29+
// CHECK: cir.func{{.*}} @[[F4_NAME:.*Func4[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F4_R_NAME:.*]]]>}
30+
//
31+
// CHECK: cir.func{{.*}} @[[F5_NAME:.*Func5[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F5_R_NAME:.*]]]>}
32+
// CHECK: acc.routine @[[F5_R_NAME]] func(@[[F5_NAME]]) bind("BIND5_N" [#acc.device_type<nvidia>], "BIND5_N" [#acc.device_type<host>], "BIND5_M" [#acc.device_type<multicore>]) seq
33+
//
34+
// CHECK: cir.func{{.*}} @[[F6_NAME:.*Func6[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F6_R_NAME:.*]]]>}
35+
//
36+
// CHECK: acc.routine @[[F2_R_NAME]] func(@[[F2_NAME]]) bind("BIND2") seq
37+
// CHECK: acc.routine @[[F4_R_NAME]] func(@[[F4_NAME]]) bind("BIND4" [#acc.device_type<radeon>]) seq
38+
// CHECK: acc.routine @[[F6_R_NAME]] func(@[[F6_NAME]]) bind("BIND6_R" [#acc.device_type<radeon>], "BIND6_M" [#acc.device_type<multicore>], "BIND6_M" [#acc.device_type<host>]) seq
39+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %clang_cc1 -fopenacc -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir %s -o - | FileCheck %s
2+
3+
#pragma acc routine seq bind("BIND1")
4+
void Func1(){}
5+
6+
void Func2(){}
7+
#pragma acc routine(Func2) seq bind("BIND2")
8+
9+
#pragma acc routine seq device_type(nvidia) bind("BIND3")
10+
void Func3(){}
11+
12+
void Func4(){}
13+
#pragma acc routine(Func4) seq device_type(radeon) bind("BIND4")
14+
15+
#pragma acc routine seq device_type(nvidia, host) bind("BIND5_N") device_type(multicore) bind("BIND5_M")
16+
void Func5(){}
17+
18+
void Func6(){}
19+
#pragma acc routine(Func6) seq device_type(radeon) bind("BIND6_R") device_type(multicore, host) bind("BIND6_M")
20+
21+
// CHECK: cir.func{{.*}} @[[F1_NAME:.*Func1[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F1_R_NAME:.*]]]>}
22+
// CHECK: acc.routine @[[F1_R_NAME]] func(@[[F1_NAME]]) bind("BIND1") seq
23+
//
24+
// CHECK: cir.func{{.*}} @[[F2_NAME:.*Func2[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F2_R_NAME:.*]]]>}
25+
//
26+
// CHECK: cir.func{{.*}} @[[F3_NAME:.*Func3[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F3_R_NAME:.*]]]>}
27+
// CHECK: acc.routine @[[F3_R_NAME]] func(@[[F3_NAME]]) bind("BIND3" [#acc.device_type<nvidia>]) seq
28+
//
29+
// CHECK: cir.func{{.*}} @[[F4_NAME:.*Func4[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F4_R_NAME:.*]]]>}
30+
//
31+
// CHECK: cir.func{{.*}} @[[F5_NAME:.*Func5[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F5_R_NAME:.*]]]>}
32+
// CHECK: acc.routine @[[F5_R_NAME]] func(@[[F5_NAME]]) bind("BIND5_N" [#acc.device_type<nvidia>], "BIND5_N" [#acc.device_type<host>], "BIND5_M" [#acc.device_type<multicore>]) seq
33+
//
34+
// CHECK: cir.func{{.*}} @[[F6_NAME:.*Func6[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F6_R_NAME:.*]]]>}
35+
//
36+
// CHECK: acc.routine @[[F2_R_NAME]] func(@[[F2_NAME]]) bind("BIND2") seq
37+
// CHECK: acc.routine @[[F4_R_NAME]] func(@[[F4_NAME]]) bind("BIND4" [#acc.device_type<radeon>]) seq
38+
// CHECK: acc.routine @[[F6_R_NAME]] func(@[[F6_NAME]]) bind("BIND6_R" [#acc.device_type<radeon>], "BIND6_M" [#acc.device_type<multicore>], "BIND6_M" [#acc.device_type<host>]) seq
39+

mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3344,6 +3344,14 @@ def OpenACC_RoutineOp : OpenACC_Op<"routine", [IsolatedFromAbove]> {
33443344
// Add an entry to the 'gang' attribute with a value for each additional
33453345
// device type.
33463346
void addGang(MLIRContext *, llvm::ArrayRef<DeviceType>, uint64_t);
3347+
// Add an entry to the 'bind' string-name attribute for each additional
3348+
// device_type.
3349+
void addBindStrName(MLIRContext *, llvm::ArrayRef<DeviceType>,
3350+
mlir::StringAttr);
3351+
// Add an entry to the 'bind' ID-name attribute for each additional
3352+
// device_type.
3353+
void addBindIDName(MLIRContext *, llvm::ArrayRef<DeviceType>,
3354+
mlir::SymbolRefAttr);
33473355
}];
33483356

33493357
let assemblyFormat = [{

mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4464,6 +4464,45 @@ void RoutineOp::addGang(MLIRContext *context,
44644464
setGangDimDeviceTypeAttr(mlir::ArrayAttr::get(context, deviceTypes));
44654465
}
44664466

4467+
void RoutineOp::addBindStrName(MLIRContext *context,
4468+
llvm::ArrayRef<DeviceType> effectiveDeviceTypes,
4469+
mlir::StringAttr val) {
4470+
unsigned before = getBindStrNameDeviceTypeAttr()
4471+
? getBindStrNameDeviceTypeAttr().size()
4472+
: 0;
4473+
4474+
setBindStrNameDeviceTypeAttr(addDeviceTypeAffectedOperandHelper(
4475+
context, getBindStrNameDeviceTypeAttr(), effectiveDeviceTypes));
4476+
unsigned after = getBindStrNameDeviceTypeAttr().size();
4477+
4478+
llvm::SmallVector<mlir::Attribute> vals;
4479+
if (getBindStrNameAttr())
4480+
llvm::copy(getBindStrNameAttr(), std::back_inserter(vals));
4481+
for (unsigned i = 0; i < after - before; ++i)
4482+
vals.push_back(val);
4483+
4484+
setBindStrNameAttr(mlir::ArrayAttr::get(context, vals));
4485+
}
4486+
4487+
void RoutineOp::addBindIDName(MLIRContext *context,
4488+
llvm::ArrayRef<DeviceType> effectiveDeviceTypes,
4489+
mlir::SymbolRefAttr val) {
4490+
unsigned before =
4491+
getBindIdNameDeviceTypeAttr() ? getBindIdNameDeviceTypeAttr().size() : 0;
4492+
4493+
setBindIdNameDeviceTypeAttr(addDeviceTypeAffectedOperandHelper(
4494+
context, getBindIdNameDeviceTypeAttr(), effectiveDeviceTypes));
4495+
unsigned after = getBindIdNameDeviceTypeAttr().size();
4496+
4497+
llvm::SmallVector<mlir::Attribute> vals;
4498+
if (getBindIdNameAttr())
4499+
llvm::copy(getBindIdNameAttr(), std::back_inserter(vals));
4500+
for (unsigned i = 0; i < after - before; ++i)
4501+
vals.push_back(val);
4502+
4503+
setBindIdNameAttr(mlir::ArrayAttr::get(context, vals));
4504+
}
4505+
44674506
//===----------------------------------------------------------------------===//
44684507
// InitOp
44694508
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)