Skip to content

Commit

Permalink
Nvidia backend: update for LLVM 17 (#440)
Browse files Browse the repository at this point in the history
* upd(llvm): remove Pass Registry and initialization

* upd(llvm): replace old PassManager by the new PassBuilder
  • Loading branch information
mratsim authored Jul 21, 2024
1 parent 39c6aae commit 26109ad
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 132 deletions.
39 changes: 14 additions & 25 deletions constantine/math_compiler/codegen_nvidia.nim
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ proc codegenNvidiaPTX*(asy: Assembler_LLVM, sm: tuple[major, minor: int32]): str
## - https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#compute-capabilities
##
## This requires the following function to be called beforehand:
## - initializePasses()
## - initializeFullNVPTXTarget()

debug: doAssert asy.backend == bkNvidiaPTX
Expand All @@ -188,30 +187,20 @@ proc codegenNvidiaPTX*(asy: Assembler_LLVM, sm: tuple[major, minor: int32]): str
codeModel = CodeModelDefault
)

# https://www.llvm.org/docs/Passes.html
let pm = createPassManager()

machine.addAnalysisPasses(pm)
pm.addDeduceFunctionAttributesPass()
pm.addMemCpyOptPass()
pm.addScalarReplacementOfAggregatesPass()
pm.addPromoteMemoryToRegisterPass()
pm.addGlobalValueNumberingPass()
pm.addDeadStoreEliminationPass()
pm.addInstructionCombiningPass()
pm.addFunctionInliningPass()
pm.addAggressiveDeadCodeEliminationPass()

when false:
# As most (all?) of our code is straightline, unoptimizable inline assembly, no loop and no branches
# most optimizations, even at -O3, are not applicable
let pmb = createPassManagerBuilder()
pmb.setOptLevel(3)
pmb.populateModulePassManager(pm)
pmb.dispose()

pm.run(asy.module)
pm.dispose()
let pbo = createPassBuilderOptions()
pbo.setMergeFunctions()
let err = asy.module.runPasses(
"default<O3>,function-attrs,memcpyopt,sroa,mem2reg,gvn,dse,instcombine,inline,adce",
machine,
pbo
)
if not err.pointer().isNil():
writeStackTrace()
let errMsg = err.getErrorMessage()
stderr.write("\"codegenNvidiaPTX\" for module '" & astToStr(module) & "' " & $instantiationInfo() &
" exited with error: " & $cstring(errMsg) & '\n')
errMsg.dispose()
quit 1

return machine.emitToString(asy.module, AssemblyFile)

Expand Down
72 changes: 2 additions & 70 deletions constantine/platforms/llvm/bindings/llvm_abi.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ type
TargetRef* = distinct pointer
ExecutionEngineRef* = distinct pointer
TargetMachineRef* = distinct pointer
PassManagerRef* = distinct pointer
PassManagerBuilderRef* = distinct pointer
PassBuilderOptionsRef* = distinct pointer
PassRegistryRef* = distinct pointer
TypeRef* = distinct pointer
ValueRef* = distinct pointer
MetadataRef = distinct pointer
Expand Down Expand Up @@ -216,78 +213,13 @@ proc targetMachineEmitToMemoryBuffer*(t: TargetMachineRef, m: ModuleRef,
# - https://blog.llvm.org/posts/2021-03-26-the-new-pass-manager/
# - https://llvm.org/docs/NewPassManager.html

# https://llvm.org/doxygen/group__LLVMCCorePassManagers.html
# # header: "<llvm-c/Core.h>"

proc createPassManager*(): PassManagerRef {.importc: "LLVMCreatePassManager".}
proc dispose*(pm: PassManagerRef) {.importc: "LLVMDisposePassManager".}
proc run*(pm: PassManagerRef, module: ModuleRef) {. importc: "LLVMRunPassManager".}

# https://llvm.org/doxygen/group__LLVMCTransformsPassManagerBuilder.html
# header: "<llvm-c/Transforms/PassManagerBuilder.h>"

proc createPassManagerBuilder*(): PassManagerBuilderRef {.importc: "LLVMPassManagerBuilderCreate".}
proc dispose*(pmb: PassManagerBuilderRef) {.importc: "LLVMPassManagerBuilderDispose".}
proc setOptLevel*(pmb: PassManagerBuilderRef, level: uint32) {.importc: "LLVMPassManagerBuilderSetOptLevel".}
proc setSizeLevel*(pmb: PassManagerBuilderRef, level: uint32) {.importc: "LLVMPassManagerBuilderSetSizeLevel".}
proc populateModulePassManager*(pmb: PassManagerBuilderRef, legacyPM: PassManagerRef) {. importc: "LLVMPassManagerBuilderPopulateModulePassManager".}

# https://llvm.org/doxygen/group__LLVMCCoreNewPM.html
# header: "<llvm-c/Transforms/PassBuilder.h>"

proc createPassBuilderOptions*(): PassBuilderOptionsRef {.importc: "LLVMCreatePassBuilderOptions".}
proc dispose*(pbo: PassBuilderOptionsRef) {.importc: "LLVMDisposePassBuilderOptions".}
proc runPasses(module: ModuleRef, passes: cstring, machine: TargetMachineRef, pbo: PassBuilderOptionsRef): ErrorRef {.used, importc: "LLVMRunPasses".}

# https://llvm.org/docs/doxygen/group__LLVMCInitialization.html
# header: "<llvm-c/Initialization.h>"

{.push used.}
proc getGlobalPassRegistry(): PassRegistryRef {.importc: "LLVMGetGlobalPassRegistry".}

proc initializeCore(registry: PassRegistryRef) {.importc: "LLVMInitializeCore".}
proc initializeTransformUtils(registry: PassRegistryRef) {.importc: "LLVMInitializeTransformUtils".}
proc initializeScalarOpts(registry: PassRegistryRef) {.importc: "LLVMInitializeScalarOpts".}
proc initializeVectorization(registry: PassRegistryRef) {.importc: "LLVMInitializeVectorization".}
proc initializeInstCombine(registry: PassRegistryRef) {.importc: "LLVMInitializeInstCombine".}
proc initializeIPO(registry: PassRegistryRef) {.importc: "LLVMInitializeIPO".}
proc initializeAnalysis(registry: PassRegistryRef) {.importc: "LLVMInitializeAnalysis".}
proc initializeIPA(registry: PassRegistryRef) {.importc: "LLVMInitializeIPA".}
proc initializeCodeGen(registry: PassRegistryRef) {.importc: "LLVMInitializeCodeGen".}
proc initializeTarget(registry: PassRegistryRef) {.importc: "LLVMInitializeTarget".}

# Removed in LLVM 16
# ------------------
# proc initializeObjCARCOpts(registry: PassRegistryRef) {.importc: "LLVMInitializeObjCARCOpts".}
# proc initializeAggressiveInstCombiner(registry: PassRegistryRef) {.importc: "LLVMInitializeAggressiveInstCombiner".}
# proc initializeInstrumentation(registry: PassRegistryRef) {.importc: "LLVMInitializeInstrumentation".}

{.pop.}

# https://llvm.org/doxygen/group__LLVMCTarget.html
proc addTargetLibraryInfo*(tli: TargetLibraryInfoRef, pm: PassManagerRef) {.importc: "LLVMAddTargetLibraryInfo".}
# There doesn't seem to be a way to instantiate TargetLibraryInfoRef :/
proc addAnalysisPasses*(machine: TargetMachineRef, pm: PassManagerRef) {.importc: "LLVMAddAnalysisPasses".}

# https://www.llvm.org/docs/Passes.html
# -------------------------------------

# https://llvm.org/doxygen/group__LLVMCTransformsInstCombine.html
proc addInstructionCombiningPass*(pm: PassManagerRef) {.importc: "LLVMAddInstructionCombiningPass".}

# https://llvm.org/doxygen/group__LLVMCTransformsUtils.html
proc addPromoteMemoryToRegisterPass*(pm: PassManagerRef) {.importc: "LLVMAddPromoteMemoryToRegisterPass".}

# https://llvm.org/doxygen/group__LLVMCTransformsScalar.html
proc addAggressiveDeadCodeEliminationPass*(pm: PassManagerRef) {.importc: "LLVMAddAggressiveDCEPass".}
proc addDeadStoreEliminationPass*(pm: PassManagerRef) {.importc: "LLVMAddDeadStoreEliminationPass".}
proc addGlobalValueNumberingPass*(pm: PassManagerRef) {.importc: "LLVMAddNewGVNPass".}
proc addMemCpyOptPass*(pm: PassManagerRef) {.importc: "LLVMAddMemCpyOptPass".}
proc addScalarReplacementOfAggregatesPass*(pm: PassManagerRef) {.importc: "LLVMAddScalarReplAggregatesPass".}

# https://llvm.org/doxygen/group__LLVMCTransformsIPO.html
proc addDeduceFunctionAttributesPass*(pm: PassManagerRef) {.importc: "LLVMAddFunctionAttrsPass".}
proc addFunctionInliningPass*(pm: PassManagerRef) {.importc: "LLVMAddFunctionInliningPass".}
proc runPasses*(module: ModuleRef, passes: cstring, machine: TargetMachineRef, pbo: PassBuilderOptionsRef): ErrorRef {.used, importc: "LLVMRunPasses".}
proc setMergeFunctions*(pbo: PassBuilderOptionsRef, mergeFunctions = LlvmBool(1)) {.importc: "LLVMPassBuilderOptionsSetMergeFunctions".}

# ############################################################
#
Expand Down
23 changes: 0 additions & 23 deletions constantine/platforms/llvm/llvm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -138,29 +138,6 @@ template emitToString*(t: TargetMachineRef, m: ModuleRef, codegen: CodeGenFileTy
mb.dispose()
emitted

# Target Machine
# ------------------------------------------------------------

proc initializePasses* =
let registry = getGlobalPassRegistry()

registry.initializeCore()
registry.initializeTransformUtils()
registry.initializeScalarOpts()
registry.initializeVectorization()
registry.initializeInstCombine()
registry.initializeIPO()
registry.initializeAnalysis()
registry.initializeIPA()
registry.initializeCodeGen()
registry.initializeTarget()

# Removed in LLVM 16
# --------------------------------
# registry.initializeObjCARCOpts()
# registry.initializeAggressiveInstCombiner()
# registry.initializeInstrumentation()

# Builder
# ------------------------------------------------------------

Expand Down
13 changes: 0 additions & 13 deletions constantine/platforms/type_ff.nim

This file was deleted.

1 change: 0 additions & 1 deletion tests/gpu/t_nvidia_fp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ proc genFieldMulPTX(asy: Assembler_LLVM, cm: CurveMetadata) =
# Init LLVM
# -------------------------
initializeFullNVPTXTarget()
initializePasses()

# Init GPU
# -------------------------
Expand Down

0 comments on commit 26109ad

Please sign in to comment.