Skip to content

Commit

Permalink
Adding function debug information (#628)
Browse files Browse the repository at this point in the history
Added debug support to LLVM code generation pipeline. Currently,
only basic support was added:

1. Debug information about functions (name)
2. Debug information about module

**What has been changed and added**

1. A new class `DebugBuilder` was created. It is used as a wrapper
around LLVM's `DIBuilder` and holds important information such as
`LLVMContext`, debug file and compile unit. It also wraps `DIBuilder`'s
functionality into a more suitable API.

2. A temporary `Location` struct has been added. It encapsulates the
location of the source AST construct and reflects `ModToken` on LLVM
code generation level. It is only used if the location of the source NMODL
function is known.

3. LLVM visitor know takes an extra `add_debug_information` flag and
handles debug information creation. Fore readability, `IRBuilder` was
renamed to `ir_builder`.

4. JIT runner is now able to listen for GDB, perf (build LLVM with
`-DLLVM_USE_PERF=ON`) and VTune (build LLVM with
`-DLLVM_USE_INTEL_JITEVENTS=ON`) events.

5. Necessary cmake changes were added to optionally support JIT event
listeners (`-DNMODL_HAVE_JIT_EVENT_LISTENERS`).

**How to generate debug information**

Debug information is attached to every function, procedure or artificially
created kernel (and corresponding wrappers). Debug information is enable
by default, so to turn it off use ` --disable-debug-info` flag. For example,
the given NMODL
```nmodl
1   FUNCTION func(x) {
2     func = x
3   }
4
5   PROCEDURE proc() {}
```
is transformed (running `./bin/nmodl <filename>.mod llvm --ir`) into
```llvm
define double @func(double %x1) !dbg !4 {
  ; ...
}

define i32 @proc() !dbg !6 {
  ; ...
}

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3}

!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "NMODL-LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "foo", directory: ".")
!2 = !{}
!3 = !{i32 2, !"Debug Version", i32 3}
!4 = distinct !DISubprogram(name: "func", linkageName: "func", scope: null, file: !1, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
!5 = !DISubroutineType(types: !2)
!6 = distinct !DISubprogram(name: "proc", linkageName: "proc", scope: null, file: !1, line: 5, type: !5, scopeLine: 5, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
```

fixes #592 #612 

Co-authored-by: Pramod Kumbhar <pramod.s.kumbhar@gmail.com>
  • Loading branch information
georgemitenkov and pramodk committed May 10, 2021
1 parent 93732e0 commit 150943c
Show file tree
Hide file tree
Showing 13 changed files with 339 additions and 110 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
option(NMODL_ENABLE_PYTHON_BINDINGS "Enable pybind11 based python bindings" OFF)
option(NMODL_ENABLE_LEGACY_UNITS "Use original faraday, R, etc. instead of 2019 nist constants" OFF)
option(NMODL_ENABLE_LLVM "Enable LLVM based code generation" ON)
option(NMODL_ENABLE_JIT_EVENT_LISTENERS "Enable JITEventListener for Perf and Vtune" OFF)

if(NMODL_ENABLE_LEGACY_UNITS)
add_definitions(-DUSE_LEGACY_UNITS)
Expand Down Expand Up @@ -267,6 +268,7 @@ if(cmake_generator_tolower MATCHES "makefile")
message(STATUS " VERSION | ${LLVM_PACKAGE_VERSION}")
message(STATUS " INCLUDE | ${LLVM_INCLUDE_DIRS}")
message(STATUS " CMAKE | ${LLVM_CMAKE_DIR}")
message(STATUS " JIT LISTENERS | ${NMODL_ENABLE_JIT_EVENT_LISTENERS}")
endif()
if(NMODL_CLANG_FORMAT)
message(STATUS "Clang Format | ${ClangFormat_EXECUTABLE}")
Expand Down
3 changes: 2 additions & 1 deletion ci/bb5-pr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ function build_with() {
-DPYTHON_EXECUTABLE=$(which python3) \
-DNMODL_FORMATTING:BOOL=ON \
-DClangFormat_EXECUTABLE=$clang_format_exe \
-DLLVM_DIR=/gpfs/bbp.cscs.ch/data/project/proj16/software/llvm/install/0421/lib/cmake/llvm
-DNMODL_ENABLE_JIT_EVENT_LISTENERS=ON \
-DLLVM_DIR=/gpfs/bbp.cscs.ch/data/project/proj16/software/llvm/install/0521/lib/cmake/llvm
make -j6
popd
}
Expand Down
38 changes: 22 additions & 16 deletions cmake/LLVMHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,28 @@

find_package(LLVM REQUIRED CONFIG)

# include LLVM header and core library
llvm_map_components_to_libnames(
LLVM_LIBS_TO_LINK
analysis
codegen
core
executionengine
instcombine
ipo
mc
native
orcjit
target
transformutils
scalaropts
support)
# include LLVM libraries
set(NMODL_LLVM_COMPONENTS
analysis
codegen
core
executionengine
instcombine
ipo
mc
native
orcjit
target
transformutils
scalaropts
support)

if(NMODL_ENABLE_JIT_EVENT_LISTENERS)
list(APPEND NMODL_LLVM_COMPONENTS inteljitevents perfjitevents)
endif()

llvm_map_components_to_libnames(LLVM_LIBS_TO_LINK ${NMODL_LLVM_COMPONENTS})

set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${LLVM_LIBS_TO_LINK})

Expand Down
9 changes: 7 additions & 2 deletions src/codegen/llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ set(LLVM_CODEGEN_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/jit_driver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/jit_driver.hpp
${CMAKE_CURRENT_SOURCE_DIR}/llvm_benchmark.cpp
${CMAKE_CURRENT_SOURCE_DIR}/llvm_benchmark.hpp)
${CMAKE_CURRENT_SOURCE_DIR}/llvm_benchmark.hpp
${CMAKE_CURRENT_SOURCE_DIR}/llvm_debug_builder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/llvm_debug_builder.hpp)

# =============================================================================
# LLVM codegen library and executable
Expand All @@ -20,8 +22,11 @@ add_library(runner_obj OBJECT ${LLVM_CODEGEN_SOURCE_FILES})
add_dependencies(runner_obj lexer_obj)
set_property(TARGET runner_obj PROPERTY POSITION_INDEPENDENT_CODE ON)

add_library(llvm_codegen STATIC $<TARGET_OBJECTS:runner_obj>)
if(NMODL_ENABLE_JIT_EVENT_LISTENERS)
target_compile_definitions(runner_obj PUBLIC NMODL_HAVE_JIT_EVENT_LISTENERS)
endif()

add_library(llvm_codegen STATIC $<TARGET_OBJECTS:runner_obj>)
add_dependencies(llvm_codegen lexer util visitor)

if(NOT NMODL_AS_SUBPROJECT)
Expand Down
3 changes: 3 additions & 0 deletions src/codegen/llvm/codegen_llvm_helper_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ void CodegenLLVMHelperVisitor::create_function_for_node(ast::Block& node) {
/// we have all information for code generation function, create a new node
/// which will be inserted later into AST
auto function = std::make_shared<ast::CodegenFunction>(fun_ret_type, name, arguments, block);
if (node.get_token()) {
function->set_token(*node.get_token()->clone());
}
codegen_functions.push_back(function);
}
/**
Expand Down
Loading

0 comments on commit 150943c

Please sign in to comment.