mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 13:50:11 +00:00
[OpenMP] Always apply target declarations to canonical definitions
This patch changes the handling of OpenMP to add the device attributes to the canonical definitions when we encounter a non-canonical definition. Previously, the following code would not work because it would find the non-canonical definition first which would then not be used anywhere else. ``` int x; extern int x; ``` This patch now adds the attribute to both of them. This allows us to perform the following operation if, for example, there were an implementation of `stderr` on the device. ``` #include <stdio.h> // List of libc symbols supported on the device. extern FILE *stderr; ``` Unfortunately I cannot think of an equivalent solution to HIP / CUDA device declarations as those are done with simple attributes. Attributes themselves cannot be used to affect a definition once its canonical definition has already been seen. Some help on that front would be appreciated. Fixes https://github.com/llvm/llvm-project/issues/63355 Reviewed By: ABataev Differential Revision: https://reviews.llvm.org/D153369
This commit is contained in:
parent
3254623d73
commit
1d699bf266
@ -151,14 +151,16 @@ void OMPDeclareTargetDeclAttr::printPrettyPragma(
|
||||
|
||||
std::optional<OMPDeclareTargetDeclAttr *>
|
||||
OMPDeclareTargetDeclAttr::getActiveAttr(const ValueDecl *VD) {
|
||||
if (!VD->hasAttrs())
|
||||
if (llvm::all_of(VD->redecls(), [](const Decl *D) { return !D->hasAttrs(); }))
|
||||
return std::nullopt;
|
||||
unsigned Level = 0;
|
||||
OMPDeclareTargetDeclAttr *FoundAttr = nullptr;
|
||||
for (auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) {
|
||||
if (Level <= Attr->getLevel()) {
|
||||
Level = Attr->getLevel();
|
||||
FoundAttr = Attr;
|
||||
for (const Decl *D : VD->redecls()) {
|
||||
for (auto *Attr : D->specific_attrs<OMPDeclareTargetDeclAttr>()) {
|
||||
if (Level <= Attr->getLevel()) {
|
||||
Level = Attr->getLevel();
|
||||
FoundAttr = Attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FoundAttr)
|
||||
|
@ -27,11 +27,13 @@
|
||||
// CHECK-DAG: Bake
|
||||
// CHECK-NOT: @{{hhh|ggg|fff|eee}} =
|
||||
// CHECK-DAG: @flag = protected global i8 undef,
|
||||
// CHECK-DAG: @dx = {{protected | }}global i32 0,
|
||||
// CHECK-DAG: @dy = {{protected | }}global i32 0,
|
||||
// CHECK-DAG: @aaa = external global i32,
|
||||
// CHECK-DAG: @bbb ={{ protected | }}global i32 0,
|
||||
// CHECK-DAG: @bbb = {{protected | }}global i32 0,
|
||||
// CHECK-DAG: weak constant %struct.__tgt_offload_entry { ptr @bbb,
|
||||
// CHECK-DAG: @ccc = external global i32,
|
||||
// CHECK-DAG: @ddd ={{ protected | }}global i32 0,
|
||||
// CHECK-DAG: @ddd = {{protected | }}global i32 0,
|
||||
// CHECK-DAG: @hhh_decl_tgt_ref_ptr = weak global ptr null
|
||||
// CHECK-DAG: @ggg_decl_tgt_ref_ptr = weak global ptr null
|
||||
// CHECK-DAG: @fff_decl_tgt_ref_ptr = weak global ptr null
|
||||
@ -51,10 +53,21 @@
|
||||
// CHECK-DAG: define {{.*}}i32 @{{.*}}{{foo|bar|baz2|baz3|FA|f_method}}{{.*}}()
|
||||
// CHECK-DAG: define {{.*}}void @{{.*}}TemplateClass{{.*}}(ptr {{[^,]*}} %{{.*}})
|
||||
// CHECK-DAG: define {{.*}}i32 @{{.*}}TemplateClass{{.*}}f_method{{.*}}(ptr {{[^,]*}} %{{.*}})
|
||||
// CHECK-DAG: define {{.*}}void @__omp_offloading_{{.*}}_globals_l[[@LINE+78]]_ctor()
|
||||
// CHECK-DAG: define {{.*}}void @__omp_offloading_{{.*}}_globals_l[[@LINE+89]]_ctor()
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
int dx = 0;
|
||||
extern int dx;
|
||||
#pragma omp declare target to(dx)
|
||||
|
||||
int dy = 0;
|
||||
#pragma omp begin declare target
|
||||
|
||||
extern int dy;
|
||||
#pragma omp end declare target
|
||||
|
||||
#pragma omp declare target
|
||||
bool flag [[clang::loader_uninitialized]];
|
||||
extern int bbb;
|
||||
|
Loading…
Reference in New Issue
Block a user