411 REFERENCE · Wikibooks
LLVM Compiler/OpenMP Support
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
With the release of Clang 3.8.0, OpenMP 3.1 support is enabled in Clang by default, and the OpenMP runtime is therefore built as a normal part of the Clang build, and distributed with the binary distributions. You do not, therefore, need explicitly to check out this code, or build it out of tree; a normal Clang check out and build will automatically include building these runtime libraries.
https://openmp.llvm.org/
installation
cmake -G Ninja -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=$LLVM_PATH -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt;openmp" -DCLANG_BUILD_EXAMPLES=1 $LLVM_SRC/llvm
ninja install -j8 -l8
OpenMP lowering or Code Geneneration
Hello example
cat omp_hello.c
#include <omp.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
int nthreads, tid;
#pragma omp parallel private(nthreads, tid)
{
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
}
}
clang -fopenmp -S -O3 -emit-llvm omp_hello.c
cat omp_hello.ll
1 ; ModuleID = 'omp_hello.c'
2 source_filename = "omp_hello.c"
3 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
5
6 %struct.ident_t = type { i32, i32, i32, i32, i8* }
7
8 @.str = private unnamed_addr constant [30 x i8] c"Hello World from thread = %d\0A\00", align 1
9 @.str.1 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
10 @0 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i32 0, i32 0) }, align 8
11
12 ; Function Attrs: nounwind uwtable
13 define dso_local i32 @main(i32 %argc, i8** nocapture readnone %argv) local_unnamed_addr #0 {
14 entry:
15 tail call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) #4
16 ret i32 0
17 }
18
19 ; Function Attrs: norecurse nounwind uwtable
20 define internal void @.omp_outlined.(i32* noalias nocapture readnone %.global_tid., i32* noalias nocapture readnone %.bound_tid.) #1 {
21 entry:
22 %call = tail call i32 @omp_get_thread_num() #4
23 %call1 = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([30 x i8], [30 x i8]* @.str, i64 0, i64 0), i32 %call)
24 ret void
25 }
26
27 declare dso_local i32 @omp_get_thread_num() local_unnamed_addr #2
28
29 ; Function Attrs: nofree nounwind
30 declare dso_local i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #3
31
32 declare !callback !2 dso_local void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) local_unnamed_addr
offloading example
#include <stdio.h>
#include <omp.h>
int main(void) {
int isHost = 0;
#pragma omp target map(from: isHost)
{ isHost = omp_is_initial_device(); }
if (isHost < 0) {
printf("Runtime error, isHost=%d\n", isHost);
}
// CHECK: Target region executed on the device
printf("Target region executed on the %s\n", isHost ? "host" : "device");
return isHost;
}
clang -fopenmp -S -O3 -emit-llvm -fopenmp-targets=nvptx64-nvidia-cuda offloading_success.cpp
relevant source files
List
tests: clang/test/OpenMP
Clang CodeGen for OpenMP IR:
clang/lib/CodeGen/CGOpenMPRuntime.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp //This contains code to emit OpenMP nodes as LLVM code.
LLVM OMP IR Builder: llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Runtime support: openmp/runtime/src/kmp_csupport.cpp
How to Debug
First, use -v to show the actual command line used by the clang driver:
clang -v -fopenmp omp_hello.c
clang version 10.0.1 (https://github.com/llvm/llvm-project d24d5c8e308e689dcd83cbafd2e8bd32aa845a15)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/ubuntu/install/llvm_install/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
/home/ubuntu/install/llvm_install/bin/clang-10 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -main-file-name omp_hello.c -mrelocation-model static -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -v -resource-dir /home/ubuntu/install/llvm_install/lib/clang/10.0.1 -internal-isystem /usr/local/include -internal-isystem /home/ubuntu/install/llvm_install/lib/clang/10.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/ubuntu -ferror-limit 19 -fmessage-length 0 -fopenmp -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -faddrsig -o /tmp/omp_hello-c73985.o -x c omp_hello.c
clang -cc1 version 10.0.1 based upon LLVM 10.0.1 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/home/ubuntu/install/llvm_install/lib/clang/10.0.1/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
"/usr/bin/ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7.5.0/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/7.5.0 -L/usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../.. -L/home/ubuntu/install/llvm_install/bin/../lib -L/lib -L/usr/lib /tmp/omp_hello-c73985.o -lomp -lgcc --as-needed -lgcc_s --no-as-needed -lpthread -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/7.5.0/crtend.o /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../x86_64-linux-gnu/crtn.o
Next, use gdb to debug the actual executable with the full command line options
gdb -args /home/ubuntu/install/llvm_install/bin/clang-10 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -main-file-name omp_hello.c -mrelocation-model static -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -v -resource-dir /home/ubuntu/install/llvm_install/lib/clang/10.0.1 -internal-isystem /usr/local/include -internal-isystem /home/ubuntu/install/llvm_install/lib/clang/10.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/ubuntu -ferror-limit 19 -fmessage-length 0 -fopenmp -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -faddrsig -o /tmp/omp_hello-c73985.o -x c omp_hello.c
Warmup run of the compiler within gdb
(gdb) r
Set a breakpoint at 1829 llvm::FunctionCallee CGOpenMPRuntime::createRuntimeFunction(unsigned Function)
b CGOpenMPRuntime.cpp:1829
r # run it
Now can check the backtrace/call stack
Breakpoint 1, clang::CodeGen::CGOpenMPRuntime::createRuntimeFunction (this=0x555565d75fd0, Function=0)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGOpenMPRuntime.cpp:1829
1829 llvm::FunctionCallee CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
(gdb) bt
#0 clang::CodeGen::CGOpenMPRuntime::createRuntimeFunction (this=0x555565d75fd0, Function=0) at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGOpenMPRuntime.cpp:1829
#1 0x000055555af54a62 in clang::CodeGen::CGOpenMPRuntime::<lambda(clang::CodeGen::CodeGenFunction&, clang::CodeGen::PrePostActionTy&)>::operator()(clang::CodeGen::CodeGenFunction &, clang::CodeGen::PrePostActionTy &) const (__closure=0x7fffffff80a0, CGF=...) at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGOpenMPRuntime.cpp:3109
#2 0x000055555af89801 in clang::CodeGen::RegionCodeGenTy::CallbackFn<clang::CodeGen::CGOpenMPRuntime::emitParallelCall(clang::CodeGen::CodeGenFunction&, clang::SourceLocation, llvm::Function*, llvm::ArrayRef<llvm::Value*>, const clang::Expr*)::<lambda(clang::CodeGen::CodeGenFunction&, clang::CodeGen::PrePostActionTy&)> >(intptr_t, clang::CodeGen::CodeGenFunction &, clang::CodeGen::PrePostActionTy &) (CodeGen=140737488322720, CGF=..., Action=...) at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGOpenMPRuntime.h:76
#3 0x000055555af45212 in clang::CodeGen::RegionCodeGenTy::operator() (this=0x7fffffff8080, CGF=...)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGOpenMPRuntime.cpp:787
#4 0x000055555af55072 in clang::CodeGen::CGOpenMPRuntime::emitParallelCall (this=0x555565d75fd0, CGF=..., Loc=..., OutlinedFn=0x555565d0bf78, CapturedVars=..., IfCond=0x0)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGOpenMPRuntime.cpp:3145
#5 0x000055555aabd108 in emitCommonOMPParallelDirective (CGF=..., S=..., InnermostKind=llvm::omp::Directive::OMPD_parallel, CodeGen=..., CodeGenBoundParameters=...)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGStmtOpenMP.cpp:1329
#6 0x000055555aabdbbf in clang::CodeGen::CodeGenFunction::EmitOMPParallelDirective (this=0x7fffffff8880, S=...)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGStmtOpenMP.cpp:1439
#7 0x000055555aa94671 in clang::CodeGen::CodeGenFunction::EmitStmt (this=0x7fffffff8880, S=0x555565e22980, Attrs=...)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGStmt.cpp:193
#8 0x000055555aa95392 in clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope (this=0x7fffffff8880, S=..., GetLast=false, AggSlot=...)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CGStmt.cpp:444
#9 0x000055555ab1ff79 in clang::CodeGen::CodeGenFunction::EmitFunctionBody (this=0x7fffffff8880, Body=0x555565e229b8)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenFunction.cpp:1146
#10 0x000055555ab20be3 in clang::CodeGen::CodeGenFunction::GenerateCode (this=0x7fffffff8880, GD=..., Fn=0x555565d0bd38, FnInfo=...)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenFunction.cpp:1311
#11 0x000055555ab498d0 in clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition (this=0x555565d73210, GD=..., GV=0x555565d0bd38)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenModule.cpp:4474
#12 0x000055555ab42709 in clang::CodeGen::CodeGenModule::EmitGlobalDefinition (this=0x555565d73210, GD=..., GV=0x0)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenModule.cpp:2864
#13 0x000055555ab4123f in clang::CodeGen::CodeGenModule::EmitGlobal (this=0x555565d73210, GD=...) at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenModule.cpp:2567
#14 0x000055555ab4d9a0 in clang::CodeGen::CodeGenModule::EmitTopLevelDecl (this=0x555565d73210, D=0x555565e20f20)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenModule.cpp:5279
#15 0x000055555baa4537 in (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl (this=0x555565d72870, DG=...)
at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/ModuleBuilder.cpp:170
#16 0x000055555ba9de7a in clang::BackendConsumer::HandleTopLevelDecl (this=0x555565d72690, D=...) at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenAction.cpp:214
#17 0x000055555cf95464 in clang::ParseAST (S=..., PrintStats=false, SkipFunctionBodies=false) at /home/ubuntu/source/llvm_src/clang/lib/Parse/ParseAST.cpp:162
#18 0x000055555b1ba873 in clang::ASTFrontendAction::ExecuteAction (this=0x555565d52ac0) at /home/ubuntu/source/llvm_src/clang/lib/Frontend/FrontendAction.cpp:1043
#19 0x000055555ba9bd46 in clang::CodeGenAction::ExecuteAction (this=0x555565d52ac0) at /home/ubuntu/source/llvm_src/clang/lib/CodeGen/CodeGenAction.cpp:1179
#20 0x000055555b1ba1d4 in clang::FrontendAction::Execute (this=0x555565d52ac0) at /home/ubuntu/source/llvm_src/clang/lib/Frontend/FrontendAction.cpp:936
#21 0x000055555b14eb74 in clang::CompilerInstance::ExecuteAction (this=0x555565d4f490, Act=...) at /home/ubuntu/source/llvm_src/clang/lib/Frontend/CompilerInstance.cpp:965
#22 0x000055555b325e07 in clang::ExecuteCompilerInvocation (Clang=0x555565d4f490) at /home/ubuntu/source/llvm_src/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:290
#23 0x0000555557d60900 in cc1_main (Argv=..., Argv0=0x7fffffffe2fb "/home/ubuntu/install/llvm_install/bin/clang-10",
MainAddr=0x555557d541aa <GetExecutablePath[abi:cxx11](char const*, bool)>) at /home/ubuntu/source/llvm_src/clang/tools/driver/cc1_main.cpp:240
#24 0x0000555557d55a4c in ExecuteCC1Tool (ArgV=...) at /home/ubuntu/source/llvm_src/clang/tools/driver/driver.cpp:329
#25 0x0000555557d561ca in main (argc_=54, argv_=0x7fffffffdef8) at /home/ubuntu/source/llvm_src/clang/tools/driver/driver.cpp:403