Skip to content

[bazel] cross language LTO #32368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ParkMyCar
Copy link
Member

@ParkMyCar ParkMyCar commented Apr 28, 2025

This PR enables cross language LTO for our release builds, meaning function calls from external C dependencies like libdecimal can potentially get inlined into Rust code.

The way this works is when building our final binaries, e.g. environmentd and clusterd, we specify the -Clinker-plugin-lto flag to rustc which has our linker (lld) run the LTO passes instead of rustc. At which point all of our Rust and C code has been compiled to LLVM bitcode so to lld is free to optimize across languages.

This only works when building for Linux. Arguments that rustc passes to the linker when targetting macOS don't seem to be supported by ld64.lld? See rust-lang/rust#60059 for some more investigation.

Motivation

Faster runtime performance.

Tips for reviewer

The commits are broken down as follows:

  1. Some Bazel configuration so we can detect when the cross language LTO is requested and when we're building on a Linux machine.
  2. Updates to cargo-gazelle so we specify the right rustc flags. Theoretically something like this could be upstreamed into rules_rust which I started working on in feat: cross language LTO bazelbuild/rules_rust#3162. But for now updating cargo-gazelle is a lot easier.
  3. Running bin/bazel gen

Checklist

  • This PR has adequate test coverage / QA involvement has been duly considered. (trigger-ci for additional test/nightly runs)
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).
  • If this PR includes major user-facing behavior changes, I have pinged the relevant PM to schedule a changelog post.

@ParkMyCar
Copy link
Member Author

ParkMyCar commented Apr 28, 2025

To confirm some C functions actually got inlined I checked the symbols in the final binaries

main

00000000099da3e0 t decAddOp
00000000099e1be0 t decApplyRound
00000000099ded10 t decCompare
00000000099dad10 t decCompareOp
00000000099d85c0 T decContextDefault
00000000099db290 t decDivideOp
00000000099dc340 t decExpOp
00000000099da200 t decFinalize
00000000099d87f0 t decGetDigits
00000000099df840 t decGetInt
00000000099dd910 t decLnOp
00000000099dcd60 t decMultiplyOp
00000000099de380 t decNaNs
00000000099da340 T decNumberAbs
00000000099dabe0 T decNumberAdd
00000000099dac50 T decNumberCompare
00000000099db090 T decNumberCompareTotal
00000000099db110 t decNumberCopy
00000000099e1520 T decNumberCopyNegate
00000000099db210 T decNumberDivide
00000000099dc1f0 T decNumberDivideInteger
00000000099dc270 T decNumberExp
00000000099d8640 T decNumberFromInt32
00000000099d97b0 T decNumberFromString
00000000099d8720 T decNumberFromUInt32
00000000099e1620 T decNumberGetBCD
00000000099dd840 T decNumberLn
00000000099de760 T decNumberLog10
00000000099dec70 T decNumberMinus
00000000099deeb0 T decNumberMultiply
00000000099de6d0 T decNumberPlus
00000000099def20 T decNumberPower
00000000099dfcd0 T decNumberReduce
00000000099dff80 T decNumberRemainder
00000000099dff10 T decNumberRescale
00000000099e01f0 T decNumberScaleB
00000000099e0330 T decNumberSquareRoot
00000000099e1190 T decNumberSubtract
00000000099d9790 T decNumberToEngString
00000000099d8860 T decNumberToInt32
00000000099e1210 T decNumberToIntegralExact
00000000099d8a20 T decNumberToString
00000000099d8930 T decNumberToUInt32
00000000099e2190 T decPackedFromNumber
00000000099e2290 T decPackedToNumber
00000000099df9b0 t decQuantizeOp
00000000099d9e10 t decSetCoeff
00000000099e1f20 t decSetOverflow
00000000099e2070 t decSetSubnormal
00000000099e0000 t decShiftToLeast
00000000099df6a0 t decShiftToMost
00000000099d8a40 t decToString
00000000099dfdb0 t decTrim
00000000099e1690 t decUnitAddSub
00000000099e1970 t decUnitCompare

This PR

0000000007ee6790 t decAddOp.llvm.16459046354495111928
0000000007eeeb70 t decApplyRound
0000000007eeb810 t decCompare.llvm.16459046354495111928
0000000007ee7160 t decCompareOp.llvm.16459046354495111928
0000000007eef120 T decContextDefault
0000000007ee7610 t decDivideOp.llvm.16459046354495111928
0000000007ee87e0 t decExpOp.llvm.16459046354495111928
0000000007ee6650 t decFinalize.llvm.16459046354495111928
0000000007ee4cd0 t decGetDigits
0000000007eec310 t decGetInt.llvm.16459046354495111928
0000000007eea230 t decLnOp.llvm.16459046354495111928
0000000007ee9220 t decMultiplyOp.llvm.16459046354495111928
0000000007eeae30 t decNaNs.llvm.16459046354495111928
0000000007ee70a0 T decNumberCompare
0000000007ee7510 T decNumberCopy
0000000007ee8710 T decNumberExp
0000000007ee5ab0 T decNumberFromString
0000000007eea160 T decNumberLn
0000000007eeb180 T decNumberLog10
0000000007eeb770 T decNumberMinus
0000000007eeb9b0 T decNumberPower
0000000007eec7e0 T decNumberReduce
0000000007eecad0 T decNumberRemainder
0000000007eecd50 T decNumberScaleB
0000000007eece90 T decNumberSquareRoot
0000000007eee220 T decNumberToIntegralExact
000000000b0c8110 T decPackedToNumber
0000000007eec4b0 t decQuantizeOp.llvm.16459046354495111928
0000000007ee6260 t decSetCoeff.llvm.16459046354495111928
0000000007eeeeb0 t decSetOverflow
0000000007eef000 t decSetSubnormal
0000000007eecb50 t decShiftToLeast
0000000007eec150 t decShiftToMost
0000000007ee4d40 t decToString.llvm.16459046354495111928
0000000007eec8e0 t decTrim.llvm.16459046354495111928
0000000007eee530 t decUnitAddSub
0000000007eee810 t decUnitCompare

Symbols missing from the x-lang LTO version (and thus evidenced as inlined) are:

decNumberAbs
decNumberAdd
decNumberCompareTotal
decNumberCopyNegate
decNumberDivide
decNumberDivideInteger
decNumberFromInt32
decNumberFromUInt32
decNumberGetBCD
decNumberMultiply
decNumberPlus
decNumberRescale
decNumberSubtract
decNumberToEngString
decNumberToInt32
decNumberToString
decNumberToUInt32
decPackedFromNumber

@ParkMyCar ParkMyCar marked this pull request as ready for review April 28, 2025 15:09
@ParkMyCar ParkMyCar requested review from a team and ggevay as code owners April 28, 2025 15:09
@ParkMyCar ParkMyCar requested a review from aljoscha April 28, 2025 15:09
Copy link
Member

@antiguru antiguru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great; thank you!

@antiguru
Copy link
Member

decNumberRescale

I've seen this show up a bunch, every time we compare two decimals, we first have to normalize, which, if I'm not mistaken, includes a call to rescale.

@ParkMyCar
Copy link
Member Author

decNumberRescale

I've seen this show up a bunch, every time we compare two decimals, we first have to normalize, which, if I'm not mistaken, includes a call to rescale.

Great! Hopefully this will be a nice performance win then. I kicked off the Nightlies to see if we get any benchmark improvements

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants