Before we tracked the size of the teams reduction buffer in order to allocate it at runtime per kernel launch. This patch splits the number into two parts, the size of the reduction data (=all reduction variables) and the (maximal) length of the buffer. This will allow us to allocate less if we need less, e.g., if we have less teams than the maximal length. It also allows us to move code from clangs codegen into the runtime as we now know how large the reduction data is.
301 lines
14 KiB
LLVM
301 lines
14 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals
|
|
; RUN: opt -S -passes=openmp-opt < %s | FileCheck %s
|
|
; RUN: opt -passes=openmp-opt -pass-remarks=openmp-opt -pass-remarks-missed=openmp-opt -disable-output < %s 2>&1 | FileCheck %s -check-prefix=CHECK-REMARKS
|
|
; RUN: opt -openmp-opt-disable-deglobalization -S -passes=openmp-opt < %s | FileCheck %s --check-prefix=CHECK-DISABLED
|
|
target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64"
|
|
target triple = "nvptx64"
|
|
|
|
@S = external local_unnamed_addr global ptr
|
|
%struct.KernelEnvironmentTy = type { %struct.ConfigurationEnvironmentTy, ptr, ptr }
|
|
%struct.ConfigurationEnvironmentTy = type { i8, i8, i8, i32, i32, i32, i32, i32, i32 }
|
|
@kernel_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 1, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null }
|
|
|
|
|
|
; UTC_ARGS: --disable
|
|
; CHECK-REMARKS: remark: remove_globalization.c:4:2: Could not move globalized variable to the stack. Variable is potentially captured in call. Mark parameter as `__attribute__((noescape))` to override.
|
|
; CHECK-REMARKS: remark: remove_globalization.c:2:2: Moving globalized variable to the stack.
|
|
; CHECK-REMARKS: remark: remove_globalization.c:4:2: Moving globalized variable to the stack.
|
|
; CHECK-REMARKS: remark: remove_globalization.c:10:2: Moving globalized variable to the stack.
|
|
; CHECK-REMARKS: remark: remove_globalization.c:6:2: Moving globalized variable to the stack.
|
|
; UTC_ARGS: --enable
|
|
|
|
; Make it a weak definition so we will apply custom state machine rewriting but can't use the body in the reasoning.
|
|
;.
|
|
; CHECK: @[[S:[a-zA-Z0-9_$"\\.-]+]] = external local_unnamed_addr global ptr
|
|
; CHECK: @[[KERNEL_KERNEL_ENVIRONMENT:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr constant [[STRUCT_KERNELENVIRONMENTTY:%.*]] { [[STRUCT_CONFIGURATIONENVIRONMENTTY:%.*]] { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null }
|
|
;.
|
|
; CHECK-DISABLED: @[[S:[a-zA-Z0-9_$"\\.-]+]] = external local_unnamed_addr global ptr
|
|
; CHECK-DISABLED: @[[KERNEL_KERNEL_ENVIRONMENT:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr constant [[STRUCT_KERNELENVIRONMENTTY:%.*]] { [[STRUCT_CONFIGURATIONENVIRONMENTTY:%.*]] { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null }
|
|
;.
|
|
define weak i32 @__kmpc_target_init(ptr %0, ptr) {
|
|
; CHECK-LABEL: define {{[^@]+}}@__kmpc_target_init
|
|
; CHECK-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) {
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
; CHECK-DISABLED-LABEL: define {{[^@]+}}@__kmpc_target_init
|
|
; CHECK-DISABLED-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) {
|
|
; CHECK-DISABLED-NEXT: ret i32 0
|
|
;
|
|
ret i32 0
|
|
}
|
|
declare void @__kmpc_target_deinit()
|
|
|
|
define void @kernel(ptr %dyn) "kernel" {
|
|
; CHECK-LABEL: define {{[^@]+}}@kernel
|
|
; CHECK-SAME: (ptr [[DYN:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @kernel_kernel_environment, ptr [[DYN]])
|
|
; CHECK-NEXT: call void @foo() #[[ATTR1:[0-9]+]]
|
|
; CHECK-NEXT: call void @bar() #[[ATTR1]]
|
|
; CHECK-NEXT: call void @convert_and_move_alloca() #[[ATTR1]]
|
|
; CHECK-NEXT: call void @unknown_no_openmp() #[[ATTR4:[0-9]+]]
|
|
; CHECK-NEXT: call void @__kmpc_target_deinit()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK-DISABLED-LABEL: define {{[^@]+}}@kernel
|
|
; CHECK-DISABLED-SAME: (ptr [[DYN:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-DISABLED-NEXT: entry:
|
|
; CHECK-DISABLED-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr @kernel_kernel_environment, ptr [[DYN]])
|
|
; CHECK-DISABLED-NEXT: call void @foo() #[[ATTR1:[0-9]+]]
|
|
; CHECK-DISABLED-NEXT: call void @bar() #[[ATTR1]]
|
|
; CHECK-DISABLED-NEXT: call void @convert_and_move_alloca() #[[ATTR1]]
|
|
; CHECK-DISABLED-NEXT: call void @unknown_no_openmp() #[[ATTR4:[0-9]+]]
|
|
; CHECK-DISABLED-NEXT: call void @__kmpc_target_deinit()
|
|
; CHECK-DISABLED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = call i32 @__kmpc_target_init(ptr @kernel_kernel_environment, ptr %dyn)
|
|
call void @foo()
|
|
call void @bar()
|
|
call void @convert_and_move_alloca()
|
|
call void @unknown_no_openmp()
|
|
call void @__kmpc_target_deinit()
|
|
ret void
|
|
}
|
|
|
|
define internal void @foo() {
|
|
; CHECK-LABEL: define {{[^@]+}}@foo
|
|
; CHECK-SAME: () #[[ATTR1]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK-DISABLED-LABEL: define {{[^@]+}}@foo
|
|
; CHECK-DISABLED-SAME: () #[[ATTR1]] {
|
|
; CHECK-DISABLED-NEXT: entry:
|
|
; CHECK-DISABLED-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 4
|
|
; CHECK-DISABLED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = call align 4 ptr @__kmpc_alloc_shared(i64 4), !dbg !12
|
|
call void @use(ptr %0)
|
|
call void @__kmpc_free_shared(ptr %0, i64 4)
|
|
ret void
|
|
}
|
|
|
|
define internal void @bar() {
|
|
; CHECK-LABEL: define {{[^@]+}}@bar
|
|
; CHECK-SAME: () #[[ATTR1]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 4
|
|
; CHECK-NEXT: call void @share(ptr nofree [[DOTH2S]]) #[[ATTR5:[0-9]+]], !dbg [[DBG8:![0-9]+]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK-DISABLED-LABEL: define {{[^@]+}}@bar
|
|
; CHECK-DISABLED-SAME: () #[[ATTR1]] {
|
|
; CHECK-DISABLED-NEXT: entry:
|
|
; CHECK-DISABLED-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 4
|
|
; CHECK-DISABLED-NEXT: call void @share(ptr nofree [[DOTH2S]]) #[[ATTR5:[0-9]+]], !dbg [[DBG8:![0-9]+]]
|
|
; CHECK-DISABLED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = call align 4 ptr @__kmpc_alloc_shared(i64 4), !dbg !13
|
|
call void @share(ptr %0), !dbg !13
|
|
call void @__kmpc_free_shared(ptr %0, i64 4)
|
|
ret void
|
|
}
|
|
|
|
define internal void @use(ptr %x) {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
define internal void @share(ptr %x) {
|
|
; CHECK-LABEL: define {{[^@]+}}@share
|
|
; CHECK-SAME: (ptr nofree [[X:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store ptr [[X]], ptr @S, align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK-DISABLED-LABEL: define {{[^@]+}}@share
|
|
; CHECK-DISABLED-SAME: (ptr nofree [[X:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
; CHECK-DISABLED-NEXT: entry:
|
|
; CHECK-DISABLED-NEXT: store ptr [[X]], ptr @S, align 8
|
|
; CHECK-DISABLED-NEXT: ret void
|
|
;
|
|
entry:
|
|
store ptr %x, ptr @S
|
|
ret void
|
|
}
|
|
|
|
define void @unused() {
|
|
; CHECK-LABEL: define {{[^@]+}}@unused() {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK-DISABLED-LABEL: define {{[^@]+}}@unused() {
|
|
; CHECK-DISABLED-NEXT: entry:
|
|
; CHECK-DISABLED-NEXT: [[TMP0:%.*]] = call align 4 ptr @__kmpc_alloc_shared(i64 4) #[[ATTR6:[0-9]+]], !dbg [[DBG11:![0-9]+]]
|
|
; CHECK-DISABLED-NEXT: call void @__kmpc_free_shared(ptr [[TMP0]], i64 4) #[[ATTR6]]
|
|
; CHECK-DISABLED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = call align 4 ptr @__kmpc_alloc_shared(i64 4), !dbg !14
|
|
call void @use(ptr %0)
|
|
call void @__kmpc_free_shared(ptr %0, i64 4)
|
|
ret void
|
|
}
|
|
|
|
define internal void @convert_and_move_alloca() {
|
|
; CHECK-LABEL: define {{[^@]+}}@convert_and_move_alloca
|
|
; CHECK-SAME: () #[[ATTR1]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 4
|
|
; CHECK-NEXT: [[IV_PTR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: br label [[INITLOOP:%.*]]
|
|
; CHECK: initloop:
|
|
; CHECK-NEXT: store i32 0, ptr [[IV_PTR]], align 4
|
|
; CHECK-NEXT: br label [[LOOPBODY:%.*]]
|
|
; CHECK: loopbody:
|
|
; CHECK-NEXT: [[IV:%.*]] = load i32, ptr [[IV_PTR]], align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IV]], 10
|
|
; CHECK-NEXT: br i1 [[TMP0]], label [[EXIT:%.*]], label [[LOOPINC:%.*]]
|
|
; CHECK: loopinc:
|
|
; CHECK-NEXT: [[INC:%.*]] = add i32 [[IV]], 1
|
|
; CHECK-NEXT: store i32 [[INC]], ptr [[IV_PTR]], align 4
|
|
; CHECK-NEXT: br label [[LOOPBODY]]
|
|
; CHECK: exit:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK-DISABLED-LABEL: define {{[^@]+}}@convert_and_move_alloca
|
|
; CHECK-DISABLED-SAME: () #[[ATTR1]] {
|
|
; CHECK-DISABLED-NEXT: entry:
|
|
; CHECK-DISABLED-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 4
|
|
; CHECK-DISABLED-NEXT: [[IV_PTR:%.*]] = alloca i32, align 4
|
|
; CHECK-DISABLED-NEXT: br label [[INITLOOP:%.*]]
|
|
; CHECK-DISABLED: initloop:
|
|
; CHECK-DISABLED-NEXT: store i32 0, ptr [[IV_PTR]], align 4
|
|
; CHECK-DISABLED-NEXT: br label [[LOOPBODY:%.*]]
|
|
; CHECK-DISABLED: loopbody:
|
|
; CHECK-DISABLED-NEXT: [[IV:%.*]] = load i32, ptr [[IV_PTR]], align 4
|
|
; CHECK-DISABLED-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IV]], 10
|
|
; CHECK-DISABLED-NEXT: br i1 [[TMP0]], label [[EXIT:%.*]], label [[LOOPINC:%.*]]
|
|
; CHECK-DISABLED: loopinc:
|
|
; CHECK-DISABLED-NEXT: [[INC:%.*]] = add i32 [[IV]], 1
|
|
; CHECK-DISABLED-NEXT: store i32 [[INC]], ptr [[IV_PTR]], align 4
|
|
; CHECK-DISABLED-NEXT: br label [[LOOPBODY]]
|
|
; CHECK-DISABLED: exit:
|
|
; CHECK-DISABLED-NEXT: ret void
|
|
;
|
|
entry:
|
|
%iv_ptr = alloca i32, align 4
|
|
%ub_ptr = alloca i32, align 4
|
|
store i32 10, ptr %ub_ptr
|
|
br label %initloop
|
|
|
|
initloop:
|
|
store i32 0, ptr %iv_ptr
|
|
%ub = load i32, ptr %ub_ptr
|
|
br label %loopbody
|
|
|
|
loopbody:
|
|
%0 = call align 4 ptr @__kmpc_alloc_shared(i64 4), !dbg !16
|
|
call void @use(ptr %0)
|
|
call void @__kmpc_free_shared(ptr %0, i64 4)
|
|
%iv = load i32, ptr %iv_ptr
|
|
%1 = icmp eq i32 %iv, %ub
|
|
br i1 %1, label %exit, label %loopinc
|
|
|
|
loopinc:
|
|
%inc = add i32 %iv, 1
|
|
store i32 %inc, ptr %iv_ptr
|
|
br label %loopbody
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
; CHECK: declare noalias ptr @__kmpc_alloc_shared(i64)
|
|
declare ptr @__kmpc_alloc_shared(i64)
|
|
|
|
; CHECK: declare void @__kmpc_free_shared(ptr allocptr nocapture, i64)
|
|
declare void @__kmpc_free_shared(ptr, i64)
|
|
|
|
declare void @unknown_no_openmp() "llvm.assume"="omp_no_openmp"
|
|
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3, !4, !6, !7}
|
|
!nvvm.annotations = !{!5}
|
|
|
|
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
|
|
!1 = !DIFile(filename: "remove_globalization.c", directory: "/tmp/remove_globalization.c")
|
|
!2 = !{}
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!4 = !{i32 1, !"wchar_size", i32 4}
|
|
!5 = !{ptr @kernel, !"kernel", i32 1}
|
|
!6 = !{i32 7, !"openmp", i32 50}
|
|
!7 = !{i32 7, !"openmp-device", i32 50}
|
|
!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
!9 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
!10 = distinct !DISubprogram(name: "unused", scope: !1, file: !1, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
!11 = !DISubroutineType(types: !2)
|
|
!12 = !DILocation(line: 2, column: 2, scope: !8)
|
|
!13 = !DILocation(line: 4, column: 2, scope: !9)
|
|
!14 = !DILocation(line: 6, column: 2, scope: !9)
|
|
!15 = !DILocation(line: 8, column: 2, scope: !9)
|
|
!16 = !DILocation(line: 10, column: 2, scope: !9)
|
|
;.
|
|
; CHECK: attributes #[[ATTR0]] = { "kernel" }
|
|
; CHECK: attributes #[[ATTR1]] = { nosync nounwind }
|
|
; CHECK: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(write) }
|
|
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nosync nounwind allocsize(0) }
|
|
; CHECK: attributes #[[ATTR4]] = { "llvm.assume"="omp_no_openmp" }
|
|
; CHECK: attributes #[[ATTR5]] = { nosync nounwind memory(write) }
|
|
;.
|
|
; CHECK-DISABLED: attributes #[[ATTR0]] = { "kernel" }
|
|
; CHECK-DISABLED: attributes #[[ATTR1]] = { nosync nounwind }
|
|
; CHECK-DISABLED: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(write) }
|
|
; CHECK-DISABLED: attributes #[[ATTR3:[0-9]+]] = { nosync nounwind allocsize(0) }
|
|
; CHECK-DISABLED: attributes #[[ATTR4]] = { "llvm.assume"="omp_no_openmp" }
|
|
; CHECK-DISABLED: attributes #[[ATTR5]] = { nosync nounwind memory(write) }
|
|
; CHECK-DISABLED: attributes #[[ATTR6]] = { nounwind }
|
|
;.
|
|
; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
|
|
; CHECK: [[META1:![0-9]+]] = !DIFile(filename: "remove_globalization.c", directory: "/tmp/remove_globalization.c")
|
|
; CHECK: [[META2:![0-9]+]] = !{}
|
|
; CHECK: [[META3:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
|
|
; CHECK: [[META4:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
|
|
; CHECK: [[META5:![0-9]+]] = !{i32 7, !"openmp", i32 50}
|
|
; CHECK: [[META6:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
|
|
; CHECK: [[META7:![0-9]+]] = !{ptr @kernel, !"kernel", i32 1}
|
|
; CHECK: [[DBG8]] = !DILocation(line: 4, column: 2, scope: !9)
|
|
; CHECK: [[META9:![0-9]+]] = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
; CHECK: [[META10:![0-9]+]] = !DISubroutineType(types: !2)
|
|
;.
|
|
; CHECK-DISABLED: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
|
|
; CHECK-DISABLED: [[META1:![0-9]+]] = !DIFile(filename: "remove_globalization.c", directory: "/tmp/remove_globalization.c")
|
|
; CHECK-DISABLED: [[META2:![0-9]+]] = !{}
|
|
; CHECK-DISABLED: [[META3:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
|
|
; CHECK-DISABLED: [[META4:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
|
|
; CHECK-DISABLED: [[META5:![0-9]+]] = !{i32 7, !"openmp", i32 50}
|
|
; CHECK-DISABLED: [[META6:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
|
|
; CHECK-DISABLED: [[META7:![0-9]+]] = !{ptr @kernel, !"kernel", i32 1}
|
|
; CHECK-DISABLED: [[DBG8]] = !DILocation(line: 4, column: 2, scope: !9)
|
|
; CHECK-DISABLED: [[META9:![0-9]+]] = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
; CHECK-DISABLED: [[META10:![0-9]+]] = !DISubroutineType(types: !2)
|
|
; CHECK-DISABLED: [[DBG11]] = !DILocation(line: 6, column: 2, scope: !9)
|
|
;.
|
|
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
|
; CHECK-REMARKS: {{.*}}
|