Skip to content

Commit 5e2bf01

Browse files
erichkeanegithub-actions[bot]
authored andcommitted
Automerge: [OpenACC][CIR] 'bind' lowering with identifier (#171749)
The bind clause specifies the name of the function to call on the device, and takes either a string or identifier(per the standard): "If the name is specified as an identifier, it is callled as if the name were specified in the language being compiled. If the name is specified as a string, the string is used for the procedure name unmodified". The latter (as a string) is already implemented, this patch implements the former. Unfortunately, no existing implementation of this in C++ seems to exist. Other languages, the 'name' of a function is sufficient to identify it (in this case 'bind' can refer to undeclared functions), so it is possible to figure out what the name should be. In C++ with overloading (without a discriminator, ala-fortran), a name only names an infinite overload set. SO, in order to implement this, I've decided that the 'called as' (bound) function must have the same signature as the one marked by the 'routine'. This is trivially sensible in non-member functions, however requires a bit more thought for member(and thus lambda-call-operators) functions. In this case, we 'promote' the type of the function to a 'free' function by turning the implicit 'this' to an explicit 'this'. I believe this is the most sensible and reasonable way to implement this, and really the only way to make something usable.
2 parents be1c7cf + 1dbff71 commit 5e2bf01

File tree

5 files changed

+243
-17
lines changed

5 files changed

+243
-17
lines changed

clang/lib/CIR/CodeGen/CIRGenDeclOpenACC.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,13 +306,15 @@ class OpenACCRoutineClauseEmitter final
306306
CIRGenModule &cgm;
307307
CIRGen::CIRGenBuilderTy &builder;
308308
mlir::acc::RoutineOp routineOp;
309+
const clang::FunctionDecl *funcDecl;
309310
llvm::SmallVector<mlir::acc::DeviceType> lastDeviceTypeValues;
310311

311312
public:
312313
OpenACCRoutineClauseEmitter(CIRGenModule &cgm,
313314
CIRGen::CIRGenBuilderTy &builder,
314-
mlir::acc::RoutineOp routineOp)
315-
: cgm(cgm), builder(builder), routineOp(routineOp) {}
315+
mlir::acc::RoutineOp routineOp,
316+
const clang::FunctionDecl *funcDecl)
317+
: cgm(cgm), builder(builder), routineOp(routineOp), funcDecl(funcDecl) {}
316318

317319
void emitClauses(ArrayRef<const OpenACCClause *> clauses) {
318320
this->VisitClauseList(clauses);
@@ -372,8 +374,12 @@ class OpenACCRoutineClauseEmitter final
372374
value);
373375
} else {
374376
assert(clause.isIdentifierArgument());
375-
cgm.errorNYI(clause.getSourceRange(),
376-
"Bind with an identifier argument is not yet supported");
377+
std::string bindName = cgm.getOpenACCBindMangledName(
378+
clause.getIdentifierArgument(), funcDecl);
379+
380+
routineOp.addBindIDName(
381+
builder.getContext(), lastDeviceTypeValues,
382+
mlir::SymbolRefAttr::get(builder.getContext(), bindName));
377383
}
378384
}
379385
};
@@ -416,6 +422,6 @@ void CIRGenModule::emitOpenACCRoutineDecl(
416422
mlir::acc::getRoutineInfoAttrName(),
417423
mlir::acc::RoutineInfoAttr::get(func.getContext(), funcRoutines));
418424

419-
OpenACCRoutineClauseEmitter emitter{*this, builder, routineOp};
425+
OpenACCRoutineClauseEmitter emitter{*this, builder, routineOp, funcDecl};
420426
emitter.emitClauses(clauses);
421427
}

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,71 @@ static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd,
17211721
return std::string(out.str());
17221722
}
17231723

1724+
static FunctionDecl *
1725+
createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName,
1726+
const FunctionDecl *protoFunc) {
1727+
// If this is a C no-prototype function, we can take the 'easy' way out and
1728+
// just create a function with no arguments/functions, etc.
1729+
if (!protoFunc->hasPrototype())
1730+
return FunctionDecl::Create(
1731+
ctx, /*DC=*/ctx.getTranslationUnitDecl(),
1732+
/*StartLoc=*/SourceLocation{}, /*NLoc=*/SourceLocation{}, bindName,
1733+
protoFunc->getType(), /*TInfo=*/nullptr, StorageClass::SC_None);
1734+
1735+
QualType funcTy = protoFunc->getType();
1736+
auto *fpt = cast<FunctionProtoType>(protoFunc->getType());
1737+
1738+
// If this is a member function, add an explicit 'this' to the function type.
1739+
if (auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
1740+
methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
1741+
llvm::SmallVector<QualType> paramTypes{fpt->getParamTypes()};
1742+
paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
1743+
1744+
funcTy = ctx.getFunctionType(fpt->getReturnType(), paramTypes,
1745+
fpt->getExtProtoInfo());
1746+
fpt = cast<FunctionProtoType>(funcTy);
1747+
}
1748+
1749+
auto *tempFunc =
1750+
FunctionDecl::Create(ctx, /*DC=*/ctx.getTranslationUnitDecl(),
1751+
/*StartLoc=*/SourceLocation{},
1752+
/*NLoc=*/SourceLocation{}, bindName, funcTy,
1753+
/*TInfo=*/nullptr, StorageClass::SC_None);
1754+
1755+
SmallVector<ParmVarDecl *> params;
1756+
params.reserve(fpt->getNumParams());
1757+
1758+
// Add all of the parameters.
1759+
for (unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
1760+
ParmVarDecl *parm = ParmVarDecl::Create(
1761+
ctx, tempFunc, /*StartLoc=*/SourceLocation{},
1762+
/*IdLoc=*/SourceLocation{},
1763+
/*Id=*/nullptr, fpt->getParamType(i), /*TInfo=*/nullptr,
1764+
StorageClass::SC_None, /*DefArg=*/nullptr);
1765+
parm->setScopeInfo(0, i);
1766+
params.push_back(parm);
1767+
}
1768+
1769+
tempFunc->setParams(params);
1770+
1771+
return tempFunc;
1772+
}
1773+
1774+
std::string
1775+
CIRGenModule::getOpenACCBindMangledName(const IdentifierInfo *bindName,
1776+
const FunctionDecl *attachedFunction) {
1777+
FunctionDecl *tempFunc = createOpenACCBindTempFunction(
1778+
getASTContext(), bindName, attachedFunction);
1779+
1780+
std::string ret = getMangledNameImpl(*this, GlobalDecl(tempFunc), tempFunc);
1781+
1782+
// This does nothing (it is a do-nothing function), since this is a
1783+
// slab-allocator, but leave a call in to immediately destroy this in case we
1784+
// ever come up with a way of getting allocations back.
1785+
getASTContext().Deallocate(tempFunc);
1786+
return ret;
1787+
}
1788+
17241789
StringRef CIRGenModule::getMangledName(GlobalDecl gd) {
17251790
GlobalDecl canonicalGd = gd.getCanonicalDecl();
17261791

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,15 @@ class CIRGenModule : public CIRGenTypeCache {
507507
mlir::Value emitMemberPointerConstant(const UnaryOperator *e);
508508

509509
llvm::StringRef getMangledName(clang::GlobalDecl gd);
510+
// This function is to support the OpenACC 'bind' clause, which names an
511+
// alternate name for the function to be called by. This function mangles
512+
// `attachedFunction` as-if its name was actually `bindName` (that is, with
513+
// the same signature). It has some additional complications, as the 'bind'
514+
// target is always going to be a global function, so member functions need an
515+
// explicit instead of implicit 'this' parameter, and thus gets mangled
516+
// differently.
517+
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName,
518+
const FunctionDecl *attachedFunction);
510519

511520
void emitTentativeDefinition(const VarDecl *d);
512521

clang/test/CIR/CodeGenOpenACC/routine-bind.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 -fopenacc -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir %s -o - | FileCheck %s
2+
// FIXME: We should run this against Windows mangling as well at one point.
23

34
#pragma acc routine seq bind("BIND1")
45
void Func1(){}
@@ -18,6 +19,28 @@ void Func5(){}
1819
void Func6(){}
1920
#pragma acc routine(Func6) seq device_type(radeon) bind("BIND6_R") device_type(multicore, host) bind("BIND6_M")
2021

22+
#pragma acc routine seq bind(BIND7)
23+
void Func7(int i){}
24+
25+
void Func8(float f){}
26+
#pragma acc routine(Func8) seq bind(BIND8)
27+
28+
#pragma acc routine seq device_type(nvidia) bind(BIND9)
29+
void Func9(int i, float f, short s){}
30+
31+
struct S{};
32+
struct U{};
33+
struct V{};
34+
35+
void Func10(struct S s){}
36+
#pragma acc routine(Func10) seq device_type(radeon) bind(BIND10)
37+
38+
#pragma acc routine seq device_type(nvidia, host) bind(BIND11_NVH) device_type(multicore) bind(BIND11_MC)
39+
void Func11(struct U* u, struct V v, int i){}
40+
41+
int Func12(struct U u, struct V v, int i){ return 0; }
42+
#pragma acc routine(Func12) seq device_type(radeon) bind(BIND12_R) device_type(multicore, host) bind(BIND12_MCH)
43+
2144
// CHECK: cir.func{{.*}} @[[F1_NAME:.*Func1[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F1_R_NAME:.*]]]>}
2245
// CHECK: acc.routine @[[F1_R_NAME]] func(@[[F1_NAME]]) bind("BIND1") seq
2346
//
@@ -33,7 +56,25 @@ void Func6(){}
3356
//
3457
// CHECK: cir.func{{.*}} @[[F6_NAME:.*Func6[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F6_R_NAME:.*]]]>}
3558
//
59+
// CHECK: cir.func{{.*}} @[[F7_NAME:.*Func7[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F7_R_NAME:.*]]]>}
60+
// CHECK: acc.routine @[[F7_R_NAME]] func(@[[F7_NAME]]) bind(@BIND7) seq
61+
//
62+
// CHECK: cir.func{{.*}} @[[F8_NAME:.*Func8[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F8_R_NAME:.*]]]>}
63+
//
64+
// CHECK: cir.func{{.*}} @[[F9_NAME:.*Func9[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F9_R_NAME:.*]]]>}
65+
// CHECK: acc.routine @[[F9_R_NAME]] func(@[[F9_NAME]]) bind(@BIND9 [#acc.device_type<nvidia>]) seq
66+
//
67+
// CHECK: cir.func{{.*}} @[[F10_NAME:.*Func10[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F10_R_NAME:.*]]]>}
68+
//
69+
// CHECK: cir.func{{.*}} @[[F11_NAME:.*Func11[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F11_R_NAME:.*]]]>}
70+
// CHECK: acc.routine @[[F11_R_NAME]] func(@[[F11_NAME]]) bind(@BIND11_NVH [#acc.device_type<nvidia>], @BIND11_NVH [#acc.device_type<host>], @BIND11_MC [#acc.device_type<multicore>])
71+
//
72+
// CHECK: cir.func{{.*}} @[[F12_NAME:.*Func12[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F12_R_NAME:.*]]]>}
73+
//
3674
// CHECK: acc.routine @[[F2_R_NAME]] func(@[[F2_NAME]]) bind("BIND2") seq
3775
// CHECK: acc.routine @[[F4_R_NAME]] func(@[[F4_NAME]]) bind("BIND4" [#acc.device_type<radeon>]) seq
3876
// 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
3977

78+
// CHECK: acc.routine @[[F8_R_NAME]] func(@[[F8_NAME]]) bind(@BIND8) seq
79+
// CHECK: acc.routine @[[F10_R_NAME]] func(@[[F10_NAME]]) bind(@BIND10 [#acc.device_type<radeon>]) seq
80+
// CHECK: acc.routine @[[F12_R_NAME]] func(@[[F12_NAME]]) bind(@BIND12_R [#acc.device_type<radeon>], @BIND12_MCH [#acc.device_type<multicore>], @BIND12_MCH [#acc.device_type<host>]) seq
Lines changed: 117 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 -fopenacc -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir %s -o - | FileCheck %s
2+
// FIXME: We should run this against Windows mangling as well at one point.
23

34
#pragma acc routine seq bind("BIND1")
45
void Func1(){}
@@ -18,22 +19,126 @@ void Func5(){}
1819
void Func6(){}
1920
#pragma acc routine(Func6) seq device_type(radeon) bind("BIND6_R") device_type(multicore, host) bind("BIND6_M")
2021

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
22+
#pragma acc routine seq bind(BIND7)
23+
void Func7(int){}
24+
25+
void Func8(float){}
26+
#pragma acc routine(Func8) seq bind(BIND8)
27+
28+
#pragma acc routine seq device_type(nvidia) bind(BIND9)
29+
void Func9(int, float, short){}
30+
31+
struct S{};
32+
struct U{};
33+
struct V{};
34+
35+
void Func10(S){}
36+
#pragma acc routine(Func10) seq device_type(radeon) bind(BIND10)
37+
38+
#pragma acc routine seq device_type(nvidia, host) bind(BIND11_NVH) device_type(multicore) bind(BIND11_MC)
39+
void Func11(U*, V&, int){}
40+
41+
int Func12(U, V, int){ return 0; }
42+
#pragma acc routine(Func12) seq device_type(radeon) bind(BIND12_R) device_type(multicore, host) bind(BIND12_MCH)
43+
44+
struct HasFuncs {
45+
#pragma acc routine seq bind(MEM)
46+
int MemFunc(int, double, HasFuncs&, S){ return 0; }
47+
#pragma acc routine seq bind(MEM)
48+
int ConstMemFunc(int, double, HasFuncs&, S) const { return 0; }
49+
#pragma acc routine seq bind(MEM)
50+
int VolatileMemFunc(int, double, HasFuncs&, S) const volatile { return 0; }
51+
#pragma acc routine seq bind(MEM)
52+
int RefMemFunc(int, double, HasFuncs&, S) const && { return 0; }
53+
#pragma acc routine seq bind(STATICMEM)
54+
int StaticMemFunc(int, double, HasFuncs&, U*){ return 0; }
55+
};
56+
57+
void hasLambdas() {
58+
HasFuncs hf;
59+
hf.MemFunc(1, 1.0, hf, S{});
60+
hf.ConstMemFunc(1, 1.0, hf, S{});
61+
static_cast<const volatile HasFuncs>(hf).VolatileMemFunc(1, 1.0, hf, S{});
62+
HasFuncs{}.RefMemFunc(1, 1.0, hf, S{});
63+
U u;
64+
hf.StaticMemFunc(1, 1.0, hf, &u);
65+
int i, j, k, l;
66+
#pragma acc routine seq bind(LAMBDA1)
67+
auto Lambda = [](int, float, double){};
68+
#pragma acc routine seq bind(LAMBDA2)
69+
auto Lambda2 = [i, F =&j, k, &l](int, float, double){};
70+
71+
Lambda(1, 2, 3);
72+
Lambda2(1, 2, 3);
73+
}
74+
75+
// CHECK: cir.func{{.*}} @_Z5Func1v({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F1_R_NAME:.*]]]>}
76+
// CHECK: acc.routine @[[F1_R_NAME]] func(@_Z5Func1v) bind("BIND1") seq
2377
//
24-
// CHECK: cir.func{{.*}} @[[F2_NAME:.*Func2[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F2_R_NAME:.*]]]>}
78+
// CHECK: cir.func{{.*}} @_Z5Func2v({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F2_R_NAME:.*]]]>}
2579
//
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
80+
// CHECK: cir.func{{.*}} @_Z5Func3v({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F3_R_NAME:.*]]]>}
81+
// CHECK: acc.routine @[[F3_R_NAME]] func(@_Z5Func3v) bind("BIND3" [#acc.device_type<nvidia>]) seq
2882
//
29-
// CHECK: cir.func{{.*}} @[[F4_NAME:.*Func4[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F4_R_NAME:.*]]]>}
83+
// CHECK: cir.func{{.*}} @_Z5Func4v({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F4_R_NAME:.*]]]>}
3084
//
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
85+
// CHECK: cir.func{{.*}} @_Z5Func5v({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F5_R_NAME:.*]]]>}
86+
// CHECK: acc.routine @[[F5_R_NAME]] func(@_Z5Func5v) bind("BIND5_N" [#acc.device_type<nvidia>], "BIND5_N" [#acc.device_type<host>], "BIND5_M" [#acc.device_type<multicore>]) seq
3387
//
34-
// CHECK: cir.func{{.*}} @[[F6_NAME:.*Func6[^\(]*]]({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F6_R_NAME:.*]]]>}
88+
// CHECK: cir.func{{.*}} @_Z5Func6v({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F6_R_NAME:.*]]]>}
3589
//
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
90+
// CHECK: cir.func{{.*}} @_Z5Func7i({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F7_R_NAME:.*]]]>}
91+
// CHECK: acc.routine @[[F7_R_NAME]] func(@_Z5Func7i) bind(@_Z5BIND7i) seq
92+
//
93+
// CHECK: cir.func{{.*}} @_Z5Func8f({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F8_R_NAME:.*]]]>}
94+
//
95+
// CHECK: cir.func{{.*}} @_Z5Func9ifs({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F9_R_NAME:.*]]]>}
96+
// CHECK: acc.routine @[[F9_R_NAME]] func(@_Z5Func9ifs) bind(@_Z5BIND9ifs [#acc.device_type<nvidia>]) seq
97+
98+
// CHECK: cir.func{{.*}} @_Z6Func101S({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F10_R_NAME:.*]]]>}
99+
//
100+
// CHECK: cir.func{{.*}} @_Z6Func11P1UR1Vi({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F11_R_NAME:.*]]]>}
101+
// CHECK: acc.routine @[[F11_R_NAME]] func(@_Z6Func11P1UR1Vi) bind(@_Z10BIND11_NVHP1UR1Vi [#acc.device_type<nvidia>], @_Z10BIND11_NVHP1UR1Vi [#acc.device_type<host>], @_Z9BIND11_MCP1UR1Vi [#acc.device_type<multicore>]) seq
102+
//
103+
// CHECK: cir.func{{.*}} @_Z6Func121U1Vi({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[F12_R_NAME:.*]]]>}
104+
//
105+
// CHECK: cir.func{{.*}} @_ZN8HasFuncs7MemFuncEidRS_1S({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[MEMFUNC_R_NAME:.*]]]>}
106+
//
107+
// CHECK: cir.func{{.*}} @_ZNK8HasFuncs12ConstMemFuncEidRS_1S({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[CONSTMEMFUNC_R_NAME:.*]]]>}
108+
//
109+
// CHECK: cir.func{{.*}} @_ZNVK8HasFuncs15VolatileMemFuncEidRS_1S({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[VOLATILEMEMFUNC_R_NAME:.*]]]>}
110+
//
111+
// CHECK: cir.func{{.*}} @_ZNKO8HasFuncs10RefMemFuncEidRS_1S({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[REFMEMFUNC_R_NAME:.*]]]>}
112+
//
113+
// CHECK: cir.func{{.*}} @_ZN8HasFuncs13StaticMemFuncEidRS_P1U({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[STATICFUNC_R_NAME:.*]]]>}
114+
//
115+
// CHECK: cir.func{{.*}} lambda{{.*}} @_ZZ10hasLambdasvENK3$_0clEifd({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[LAMBDA1_R_NAME:.*]]]>}
116+
//
117+
// CHECK: cir.func{{.*}} lambda{{.*}} @_ZZ10hasLambdasvENK3$_1clEifd({{.*}}){{.*}} attributes {acc.routine_info = #acc.routine_info<[@[[LAMBDA2_R_NAME:.*]]]>}
118+
//
119+
// CHECK: acc.routine @[[MEMFUNC_R_NAME]] func(@_ZN8HasFuncs7MemFuncEidRS_1S) bind(@_Z3MEMP8HasFuncsidRS_1S) seq
120+
// CHECK: acc.routine @[[CONSTMEMFUNC_R_NAME]] func(@_ZNK8HasFuncs12ConstMemFuncEidRS_1S) bind(@_Z3MEMPK8HasFuncsidRS_1S) seq
121+
// CHECK: acc.routine @[[VOLATILEMEMFUNC_R_NAME]] func(@_ZNVK8HasFuncs15VolatileMemFuncEidRS_1S) bind(@_Z3MEMPVK8HasFuncsidRS_1S) seq
122+
// CHECK: acc.routine @[[REFMEMFUNC_R_NAME]] func(@_ZNKO8HasFuncs10RefMemFuncEidRS_1S) bind(@_Z3MEMPK8HasFuncsidRS_1S) seq
123+
// CHECK: acc.routine @[[STATICFUNC_R_NAME]] func(@_ZN8HasFuncs13StaticMemFuncEidRS_P1U) bind(@_Z9STATICMEMP8HasFuncsidRS_P1U) seq
124+
//
125+
// These two LOOK weird because the first argument to each of these is the
126+
// implicit 'this', so they look like they have the lambda mangling (and
127+
// demanglers don't handle lambdas well).
128+
// CHECK: acc.routine @[[LAMBDA1_R_NAME]] func(@_ZZ10hasLambdasvENK3$_0clEifd) bind(@_Z7LAMBDA1PKZ10hasLambdasvE3$_0ifd) seq
129+
// Manual demangle:
130+
// Func name: _Z7LAMBDA1 -> LAMBDA1
131+
// Args: P -> Pointer
132+
// K -> Const
133+
// Z10hasLambdasv-> hasLambdas(void)::
134+
// E3$_0 -> anonymous type #0
135+
// ifd -> taking args int, float, double.
136+
// // CHECK: acc.routine @[[LAMBDA2_R_NAME]] func(@_ZZ10hasLambdasvENK3$_1clEifd) bind(@_Z7LAMBDA2PKZ10hasLambdasvE3$_1ifd) seq
137+
138+
// CHECK: acc.routine @[[F2_R_NAME]] func(@_Z5Func2v) bind("BIND2") seq
139+
// CHECK: acc.routine @[[F4_R_NAME]] func(@_Z5Func4v) bind("BIND4" [#acc.device_type<radeon>]) seq
140+
// CHECK: acc.routine @[[F6_R_NAME]] func(@_Z5Func6v) bind("BIND6_R" [#acc.device_type<radeon>], "BIND6_M" [#acc.device_type<multicore>], "BIND6_M" [#acc.device_type<host>]) seq
141+
// CHECK: acc.routine @[[F8_R_NAME]] func(@_Z5Func8f) bind(@_Z5BIND8f) seq
142+
// CHECK: acc.routine @[[F10_R_NAME]] func(@_Z6Func101S) bind(@_Z6BIND101S [#acc.device_type<radeon>]) seq
143+
// CHECK: acc.routine @[[F12_R_NAME]] func(@_Z6Func121U1Vi) bind(@_Z8BIND12_R1U1Vi [#acc.device_type<radeon>], @_Z10BIND12_MCH1U1Vi [#acc.device_type<multicore>], @_Z10BIND12_MCH1U1Vi [#acc.device_type<host>]) seq
39144

0 commit comments

Comments
 (0)