Repository navigation
Copy instruction metadata in one call, iterate over call sites, and build a local LLVMExtra with optimization - #693
Merged
Merged
Conversation
Passes that replace an instruction copy its metadata to the new one. Going through the metadata dictionary for that wraps every attachment and converts it through MetadataAsValue; Instruction::copyMetadata does it in one call, and handles the debug location the way the LLVM version in use does (which changed in LLVM 21). Copying the metadata of 5000 loads with !tbaa, !range, !noundef and a debug location (LLVM 18, Julia 1.12): 5.4-9.2 ms and 4.7 MiB through the dictionary, 0.37 ms and no allocations with copy_metadata!.
Without a build type, CMake compiles without optimization, so a locally built LLVMExtra was -O0, and even trivial wrappers made out-of-line calls to LLVM's unwrap/wrap helpers. Use RelWithDebInfo, like the LLVMExtra_jll recipe. copy_metadata! on 5000 instructions (LLVM 18, Julia 1.12): 0.53-0.56 ms with the -O0 build, 0.37 ms with RelWithDebInfo.
Passes often only look at the calls in a function. Filtering the instructions of every block wraps each of them, which identifies its concrete type with a dynamic call; `f.calls` checks the opcode first and only wraps the calls. Visiting the 1000 calls of a function with 10000 instructions and reading their callee (LLVM 18, Julia 1.12): 0.13-0.23 ms and 158 KiB when filtering `bb.instructions`, 0.09 ms and 125 KiB with `f.calls`.
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #693 +/- ##
==========================================
+ Coverage 94.82% 94.84% +0.01%
==========================================
Files 58 58
Lines 6817 6843 +26
==========================================
+ Hits 6464 6490 +26
Misses 353 353
🚀 New features to boost your workflow:
|
LLVM is built without exceptions, and LLVMExtra neither throws nor catches. Building it with exceptions enabled made GCC 14+ emit calls to __cxa_call_terminate in optimized code, which the libstdc++ shipped with Julia 1.10 and 1.11 on Windows doesn't export, so the RelWithDebInfo library built by deps/build_local.jl failed to load there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three additions that came out of profiling passes written in Julia (JuliaIR.jl):
copy_metadata!(dest, src, kinds=())copies the metadata of an instruction with LLVM'sInstruction::copyMetadata(a new LLVMExtra function). Passes that replace an instructiondid this through the metadata dictionary, which wraps every attachment and converts it
through
MetadataAsValue. The debug location is handled the way the LLVM version in usedoes: if
srchas none, LLVM 21 and later keep the one ofdest, earlier versions removeit (unless
srchas no metadata at all). Copying the metadata of 5000 loads with!tbaa,!range,!noundefand a debug location: 5.4-9.2 ms and 4.7 MiB through the dictionary,0.37 ms and no allocations with
copy_metadata!.f.callsis a read-only view of thecall,invokeandcallbrinstructions of afunction, as
CallBasevalues. It checks the opcode before wrapping an instruction, sopasses that only look at calls don't wrap (and dynamically identify) every other
instruction. Visiting the 1000 calls of a function with 10000 instructions: 0.13-0.23 ms
when filtering
bb.instructions, 0.09 ms withf.calls.deps/build_local.jlnow builds LLVMExtra asRelWithDebInfo, like the LLVMExtra_jllrecipe. Without a build type CMake doesn't optimize, so local builds were -O0 and even
one-line wrappers made out-of-line calls to
unwrap. The build type is part of thedirectory the library is installed in, so an existing -O0 build of the same sources isn't
reused.
copy_metadata!on 5000 instructions: 0.53-0.56 ms with -O0, 0.37 ms optimized.Measured with LLVM 18 on Julia 1.12, on a loaded machine; ranges are over separate processes.
New LLVMExtra function:
LLVMExtraCopyMetadata, so this needs a new LLVMExtra_jll buildbefore release.