[OPENMP] Emit template instatiation|specialization functions for

devices.

If the function is an instantiation|specialization of the template and
is used in the device code, the definitions of such functions should be
emitted for the device.

llvm-svn: 331261
This commit is contained in:
Alexey Bataev 2018-05-01 14:09:46 +00:00
parent 788dc70c78
commit fb38828cb2
2 changed files with 18 additions and 5 deletions

View File

@ -907,6 +907,14 @@ isDeclareTargetDeclaration(const ValueDecl *VD) {
if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>()) if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>())
return Attr->getMapType(); return Attr->getMapType();
} }
if (const auto *V = dyn_cast<VarDecl>(VD)) {
if (const VarDecl *TD = V->getTemplateInstantiationPattern())
return isDeclareTargetDeclaration(TD);
} else if (const auto *FD = dyn_cast<FunctionDecl>(VD)) {
if (const auto *TD = FD->getTemplateInstantiationPattern())
return isDeclareTargetDeclaration(TD);
}
return llvm::None; return llvm::None;
} }
@ -7795,7 +7803,8 @@ bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
scanForTargetRegionsFunctions(FD->getBody(), CGM.getMangledName(GD)); scanForTargetRegionsFunctions(FD->getBody(), CGM.getMangledName(GD));
// Do not to emit function if it is not marked as declare target. // Do not to emit function if it is not marked as declare target.
return !isDeclareTargetDeclaration(FD); return !isDeclareTargetDeclaration(FD) &&
AlreadyEmittedTargetFunctions.count(FD->getCanonicalDecl()) == 0;
} }
bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) { bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {

View File

@ -18,7 +18,7 @@
// CHECK-DAG: @d = global i32 0, // CHECK-DAG: @d = global i32 0,
// CHECK-DAG: @c = external global i32, // CHECK-DAG: @c = external global i32,
// CHECK-DAG: define {{.*}}i32 @{{.*}}{{foo|bar|baz2|baz3}}{{.*}}() // CHECK-DAG: define {{.*}}i32 @{{.*}}{{foo|bar|baz2|baz3|FA}}{{.*}}()
#ifndef HEADER #ifndef HEADER
#define HEADER #define HEADER
@ -31,6 +31,11 @@ int baz2();
int baz4() { return 5; } int baz4() { return 5; }
template <typename T>
T FA() {
return T();
}
#pragma omp declare target #pragma omp declare target
struct S { struct S {
int a; int a;
@ -54,19 +59,18 @@ int maini1() {
{ {
S s(a); S s(a);
static long aaa = 23; static long aaa = 23;
a = foo() + bar() + b + c + d + aa + aaa; a = foo() + bar() + b + c + d + aa + aaa + FA<int>();
} }
return baz4(); return baz4();
} }
int baz3(); int baz3() { return 2 + baz2(); }
int baz2() { int baz2() {
// CHECK-DAG: define void @__omp_offloading_{{.*}}baz2{{.*}}_l[[@LINE+1]](i64 {{.*}}) // CHECK-DAG: define void @__omp_offloading_{{.*}}baz2{{.*}}_l[[@LINE+1]](i64 {{.*}})
#pragma omp target #pragma omp target
++c; ++c;
return 2 + baz3(); return 2 + baz3();
} }
int baz3() { return 2 + baz2(); }
// CHECK-NOT: define {{.*}}{{baz1|baz4|maini1}} // CHECK-NOT: define {{.*}}{{baz1|baz4|maini1}}
#endif // HEADER #endif // HEADER