Skip to content

Commit 1ca7403

Browse files
fghanimjdoerfert
authored andcommitted
[OpenMP][OMPIRBuilder] Add Directives (master and critical) to OMPBuilder.
Add support for Master and Critical directive in the OMPIRBuilder. Both make use of a new common interface for emitting inlined OMP regions called `emitInlinedRegion` which was added in this patch as well. Also this patch modifies clang to use the new directives when `-fopenmp-enable-irbuilder` commandline option is passed. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D72304
1 parent 68cf574 commit 1ca7403

File tree

9 files changed

+756
-67
lines changed

9 files changed

+756
-67
lines changed

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,11 +3130,147 @@ static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
31303130
}
31313131

31323132
void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
3133+
if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) {
3134+
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
3135+
3136+
const CapturedStmt *CS = S.getInnermostCapturedStmt();
3137+
const Stmt *MasterRegionBodyStmt = CS->getCapturedStmt();
3138+
3139+
// TODO: Replace with a generic helper function for finalization
3140+
auto FiniCB = [this](InsertPointTy IP) {
3141+
CGBuilderTy::InsertPointGuard IPG(Builder);
3142+
assert(IP.getBlock()->end() != IP.getPoint() &&
3143+
"OpenMP IR Builder should cause terminated block!");
3144+
3145+
llvm::BasicBlock *IPBB = IP.getBlock();
3146+
llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor();
3147+
assert(DestBB && "Finalization block should have one successor!");
3148+
3149+
// erase and replace with cleanup branch.
3150+
IPBB->getTerminator()->eraseFromParent();
3151+
Builder.SetInsertPoint(IPBB);
3152+
CodeGenFunction::JumpDest Dest = getJumpDestInCurrentScope(DestBB);
3153+
EmitBranchThroughCleanup(Dest);
3154+
};
3155+
3156+
// TODO: Replace with a generic helper function for emitting body
3157+
auto BodyGenCB = [MasterRegionBodyStmt, this](InsertPointTy AllocaIP,
3158+
InsertPointTy CodeGenIP,
3159+
llvm::BasicBlock &FiniBB) {
3160+
// Alloca insertion block should be in the entry block of the containing
3161+
// function So it expects an empty AllocaIP in which case will reuse the
3162+
// old alloca insertion point, or a new AllocaIP in the same block as the
3163+
// old one
3164+
assert((!AllocaIP.isSet() ||
3165+
AllocaInsertPt->getParent() == AllocaIP.getBlock()) &&
3166+
"Insertion point should be in the entry block of containing "
3167+
"function!");
3168+
auto OldAllocaIP = AllocaInsertPt;
3169+
if (AllocaIP.isSet())
3170+
AllocaInsertPt = &*AllocaIP.getPoint();
3171+
auto OldReturnBlock = ReturnBlock;
3172+
ReturnBlock = getJumpDestInCurrentScope(&FiniBB);
3173+
3174+
llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
3175+
if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator())
3176+
CodeGenIPBBTI->eraseFromParent();
3177+
3178+
Builder.SetInsertPoint(CodeGenIPBB);
3179+
3180+
EmitStmt(MasterRegionBodyStmt);
3181+
3182+
if (Builder.saveIP().isSet())
3183+
Builder.CreateBr(&FiniBB);
3184+
3185+
AllocaInsertPt = OldAllocaIP;
3186+
ReturnBlock = OldReturnBlock;
3187+
};
3188+
CGCapturedStmtInfo CGSI(*CS, CR_OpenMP);
3189+
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
3190+
Builder.restoreIP(OMPBuilder->CreateMaster(Builder, BodyGenCB, FiniCB));
3191+
3192+
return;
3193+
}
31333194
OMPLexicalScope Scope(*this, S, OMPD_unknown);
31343195
emitMaster(*this, S);
31353196
}
31363197

31373198
void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
3199+
if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) {
3200+
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
3201+
3202+
const CapturedStmt *CS = S.getInnermostCapturedStmt();
3203+
const Stmt *CriticalRegionBodyStmt = CS->getCapturedStmt();
3204+
const Expr *Hint = nullptr;
3205+
if (const auto *HintClause = S.getSingleClause<OMPHintClause>())
3206+
Hint = HintClause->getHint();
3207+
3208+
// TODO: This is slightly different from what's currently being done in
3209+
// clang. Fix the Int32Ty to IntPtrTy (pointer width size) when everything
3210+
// about typing is final.
3211+
llvm::Value *HintInst = nullptr;
3212+
if (Hint)
3213+
HintInst =
3214+
Builder.CreateIntCast(EmitScalarExpr(Hint), CGM.Int32Ty, false);
3215+
3216+
// TODO: Replace with a generic helper function for finalization
3217+
auto FiniCB = [this](InsertPointTy IP) {
3218+
CGBuilderTy::InsertPointGuard IPG(Builder);
3219+
assert(IP.getBlock()->end() != IP.getPoint() &&
3220+
"OpenMP IR Builder should cause terminated block!");
3221+
llvm::BasicBlock *IPBB = IP.getBlock();
3222+
llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor();
3223+
assert(DestBB && "Finalization block should have one successor!");
3224+
3225+
// erase and replace with cleanup branch.
3226+
IPBB->getTerminator()->eraseFromParent();
3227+
Builder.SetInsertPoint(IPBB);
3228+
CodeGenFunction::JumpDest Dest = getJumpDestInCurrentScope(DestBB);
3229+
EmitBranchThroughCleanup(Dest);
3230+
};
3231+
3232+
// TODO: Replace with a generic helper function for emitting body
3233+
auto BodyGenCB = [CriticalRegionBodyStmt, this](InsertPointTy AllocaIP,
3234+
InsertPointTy CodeGenIP,
3235+
llvm::BasicBlock &FiniBB) {
3236+
// Alloca insertion block should be in the entry block of the containing
3237+
// function So it expects an empty AllocaIP in which case will reuse the
3238+
// old alloca insertion point, or a new AllocaIP in the same block as the
3239+
// old one
3240+
assert((!AllocaIP.isSet() ||
3241+
AllocaInsertPt->getParent() == AllocaIP.getBlock()) &&
3242+
"Insertion point should be in the entry block of containing "
3243+
"function!");
3244+
auto OldAllocaIP = AllocaInsertPt;
3245+
if (AllocaIP.isSet())
3246+
AllocaInsertPt = &*AllocaIP.getPoint();
3247+
auto OldReturnBlock = ReturnBlock;
3248+
ReturnBlock = getJumpDestInCurrentScope(&FiniBB);
3249+
3250+
llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
3251+
if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator())
3252+
CodeGenIPBBTI->eraseFromParent();
3253+
3254+
Builder.SetInsertPoint(CodeGenIPBB);
3255+
3256+
EmitStmt(CriticalRegionBodyStmt);
3257+
3258+
if (Builder.saveIP().isSet())
3259+
Builder.CreateBr(&FiniBB);
3260+
3261+
AllocaInsertPt = OldAllocaIP;
3262+
ReturnBlock = OldReturnBlock;
3263+
};
3264+
3265+
CGCapturedStmtInfo CGSI(*CS, CR_OpenMP);
3266+
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
3267+
Builder.restoreIP(OMPBuilder->CreateCritical(
3268+
Builder, BodyGenCB, FiniCB, S.getDirectiveName().getAsString(),
3269+
HintInst));
3270+
3271+
return;
3272+
}
3273+
31383274
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
31393275
Action.Enter(CGF);
31403276
CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());

clang/test/OpenMP/critical_codegen.cpp

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
1+
// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=ALL,NORMAL
22
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
3-
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
3+
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=ALL,NORMAL
44
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
5+
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=ALL,IRBUILDER
6+
// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
7+
// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=ALL,IRBUILDER
58

69
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s
710
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
@@ -12,74 +15,79 @@
1215
#ifndef HEADER
1316
#define HEADER
1417

15-
// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
16-
// CHECK: [[UNNAMED_LOCK:@.+]] = common global [8 x i32] zeroinitializer
17-
// CHECK: [[THE_NAME_LOCK:@.+]] = common global [8 x i32] zeroinitializer
18-
// CHECK: [[THE_NAME_LOCK1:@.+]] = common global [8 x i32] zeroinitializer
18+
// ALL: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
19+
// ALL: [[UNNAMED_LOCK:@.+]] = common global [8 x i32] zeroinitializer
20+
// ALL: [[THE_NAME_LOCK:@.+]] = common global [8 x i32] zeroinitializer
21+
// ALL: [[THE_NAME_LOCK1:@.+]] = common global [8 x i32] zeroinitializer
1922

20-
// CHECK: define {{.*}}void [[FOO:@.+]]()
23+
// ALL: define {{.*}}void [[FOO:@.+]]()
2124

2225
void foo() {}
2326

24-
// CHECK-LABEL: @main
27+
// ALL-LABEL: @main
2528
// TERM_DEBUG-LABEL: @main
2629
int main() {
27-
// CHECK: [[A_ADDR:%.+]] = alloca i8
30+
// ALL: [[A_ADDR:%.+]] = alloca i8
2831
char a;
2932

30-
// CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
31-
// CHECK: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[UNNAMED_LOCK]])
32-
// CHECK-NEXT: store i8 2, i8* [[A_ADDR]]
33-
// CHECK-NEXT: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[UNNAMED_LOCK]])
33+
// ALL: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
34+
// ALL: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[UNNAMED_LOCK]])
35+
// ALL-NEXT: store i8 2, i8* [[A_ADDR]]
36+
// ALL-NEXT: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[UNNAMED_LOCK]])
3437
#pragma omp critical
3538
a = 2;
36-
// CHECK: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
37-
// CHECK-NEXT: invoke {{.*}}void [[FOO]]()
38-
// CHECK: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
39+
// IRBUILDER: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
40+
// ALL: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
41+
// IRBUILDER-NEXT: call {{.*}}void [[FOO]]()
42+
// NORMAL-NEXT: invoke {{.*}}void [[FOO]]()
43+
// ALL: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
3944
#pragma omp critical(the_name)
4045
foo();
41-
// CHECK: call {{.*}}void @__kmpc_critical_with_hint([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]], i{{64|32}} 23)
42-
// CHECK-NEXT: invoke {{.*}}void [[FOO]]()
43-
// CHECK: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]])
46+
// IRBUILDER: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
47+
// ALL: call {{.*}}void @__kmpc_critical_with_hint([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]], i{{64|32}} 23)
48+
// IRBUILDER-NEXT: call {{.*}}void [[FOO]]()
49+
// NORMAL-NEXT: invoke {{.*}}void [[FOO]]()
50+
// ALL: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]])
4451
#pragma omp critical(the_name1) hint(23)
4552
foo();
46-
// CHECK: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
47-
// CHECK: br label
48-
// CHECK-NOT: call {{.*}}void @__kmpc_end_critical(
49-
// CHECK: br label
50-
// CHECK-NOT: call {{.*}}void @__kmpc_end_critical(
51-
// CHECK: br label
53+
// IRBUILDER: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
54+
// ALL: call {{.*}}void @__kmpc_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
55+
// ALL: br label
56+
// ALL-NOT: call {{.*}}void @__kmpc_end_critical(
57+
// ALL: br label
58+
// ALL-NOT: call {{.*}}void @__kmpc_end_critical(
59+
// NORMAL: br label
5260
if (a)
5361
#pragma omp critical(the_name)
5462
while (1)
5563
;
56-
// CHECK: call {{.*}}void [[FOO]]()
64+
// ALL: call {{.*}}void [[FOO]]()
5765
foo();
58-
// CHECK-NOT: call void @__kmpc_critical
59-
// CHECK-NOT: call void @__kmpc_end_critical
66+
// ALL-NOT: call void @__kmpc_critical
67+
// ALL-NOT: call void @__kmpc_end_critical
6068
return a;
6169
}
6270

6371
struct S {
6472
int a;
6573
};
66-
// CHECK-LABEL: critical_ref
74+
// ALL-LABEL: critical_ref
6775
void critical_ref(S &s) {
68-
// CHECK: [[S_ADDR:%.+]] = alloca %struct.S*,
69-
// CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
70-
// CHECK: [[S_A_REF:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[S_REF]], i32 0, i32 0
76+
// ALL: [[S_ADDR:%.+]] = alloca %struct.S*,
77+
// ALL: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
78+
// ALL: [[S_A_REF:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[S_REF]], i32 0, i32 0
7179
++s.a;
72-
// CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
73-
// CHECK: store %struct.S* [[S_REF]], %struct.S** [[S_ADDR:%.+]],
74-
// CHECK: call void @__kmpc_critical(
80+
// NORMAL: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
81+
// NORMAL: store %struct.S* [[S_REF]], %struct.S** [[S_ADDR:%.+]],
82+
// ALL: call void @__kmpc_critical(
7583
#pragma omp critical
76-
// CHECK: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
77-
// CHECK: [[S_A_REF:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[S_REF]], i32 0, i32 0
84+
// ALL: [[S_REF:%.+]] = load %struct.S*, %struct.S** [[S_ADDR]],
85+
// ALL: [[S_A_REF:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[S_REF]], i32 0, i32 0
7886
++s.a;
79-
// CHECK: call void @__kmpc_end_critical(
87+
// ALL: call void @__kmpc_end_critical(
8088
}
8189

82-
// CHECK-LABEL: parallel_critical
90+
// ALL-LABEL: parallel_critical
8391
// TERM_DEBUG-LABEL: parallel_critical
8492
void parallel_critical() {
8593
#pragma omp parallel

clang/test/OpenMP/master_codegen.cpp

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
1+
// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=ALL,NORMAL
22
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
3-
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
3+
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=ALL,NORMAL
44
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
5+
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=ALL,IRBUILDER
6+
// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
7+
// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=ALL,IRBUILDER
58

69
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s
710
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
@@ -12,45 +15,47 @@
1215
#ifndef HEADER
1316
#define HEADER
1417

15-
// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
18+
// ALL: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
1619

17-
// CHECK: define {{.*}}void [[FOO:@.+]]()
20+
// ALL: define {{.*}}void [[FOO:@.+]]()
1821

1922
void foo() {}
2023

21-
// CHECK-LABEL: @main
24+
// ALL-LABEL: @main
2225
// TERM_DEBUG-LABEL: @main
2326
int main() {
24-
// CHECK: [[A_ADDR:%.+]] = alloca i8
27+
// ALL: [[A_ADDR:%.+]] = alloca i8
2528
char a;
2629

27-
// CHECK: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
28-
// CHECK: [[RES:%.+]] = call {{.*}}i32 @__kmpc_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
29-
// CHECK-NEXT: [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0
30-
// CHECK-NEXT: br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
31-
// CHECK: [[THEN]]
32-
// CHECK-NEXT: store i8 2, i8* [[A_ADDR]]
33-
// CHECK-NEXT: call {{.*}}void @__kmpc_end_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
34-
// CHECK-NEXT: br label {{%?}}[[EXIT]]
35-
// CHECK: [[EXIT]]
30+
// ALL: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
31+
// ALL: [[RES:%.+]] = call {{.*}}i32 @__kmpc_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
32+
// ALL-NEXT: [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0
33+
// ALL-NEXT: br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
34+
// ALL: [[THEN]]
35+
// ALL-NEXT: store i8 2, i8* [[A_ADDR]]
36+
// ALL-NEXT: call {{.*}}void @__kmpc_end_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
37+
// ALL-NEXT: br label {{%?}}[[EXIT]]
38+
// ALL: [[EXIT]]
3639
#pragma omp master
3740
a = 2;
38-
// CHECK: [[RES:%.+]] = call {{.*}}i32 @__kmpc_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
39-
// CHECK-NEXT: [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0
40-
// CHECK-NEXT: br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
41-
// CHECK: [[THEN]]
42-
// CHECK-NEXT: invoke {{.*}}void [[FOO]]()
43-
// CHECK: call {{.*}}void @__kmpc_end_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
44-
// CHECK-NEXT: br label {{%?}}[[EXIT]]
45-
// CHECK: [[EXIT]]
41+
// IRBUILDER: [[GTID:%.+]] = call {{.*}}i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
42+
// ALL: [[RES:%.+]] = call {{.*}}i32 @__kmpc_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
43+
// ALL-NEXT: [[IS_MASTER:%.+]] = icmp ne i32 [[RES]], 0
44+
// ALL-NEXT: br i1 [[IS_MASTER]], label {{%?}}[[THEN:.+]], label {{%?}}[[EXIT:.+]]
45+
// ALL: [[THEN]]
46+
// IRBUILDER-NEXT: call {{.*}}void [[FOO]]()
47+
// NORMAL-NEXT: invoke {{.*}}void [[FOO]]()
48+
// ALL: call {{.*}}void @__kmpc_end_master([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
49+
// ALL-NEXT: br label {{%?}}[[EXIT]]
50+
// ALL: [[EXIT]]
4651
#pragma omp master
4752
foo();
48-
// CHECK-NOT: call i32 @__kmpc_master
49-
// CHECK-NOT: call void @__kmpc_end_master
53+
// ALL-NOT: call i32 @__kmpc_master
54+
// ALL-NOT: call void @__kmpc_end_master
5055
return a;
5156
}
5257

53-
// CHECK-LABEL: parallel_master
58+
// ALL-LABEL: parallel_master
5459
// TERM_DEBUG-LABEL: parallel_master
5560
void parallel_master() {
5661
#pragma omp parallel

llvm/include/llvm/Frontend/OpenMP/OMPConstants.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
namespace llvm {
2121
class Type;
2222
class Module;
23+
class ArrayType;
2324
class StructType;
2425
class PointerType;
2526
class FunctionType;
@@ -85,6 +86,9 @@ StringRef getOpenMPDirectiveName(Directive D);
8586
namespace types {
8687

8788
#define OMP_TYPE(VarName, InitValue) extern Type *VarName;
89+
#define OMP_ARRAY_TYPE(VarName, ElemTy, ArraySize) \
90+
extern ArrayType *VarName##Ty; \
91+
extern PointerType *VarName##PtrTy;
8892
#define OMP_FUNCTION_TYPE(VarName, IsVarArg, ReturnType, ...) \
8993
extern FunctionType *VarName; \
9094
extern PointerType *VarName##Ptr;

0 commit comments

Comments
 (0)