Skip to content

Build time improvement: [CSS Calc] Collapse RoundNearest/Up/Down/ToZero into a single Round struct#62308

Open
brentfulgham wants to merge 1 commit intoWebKit:mainfrom
brentfulgham:eng/Build-time-improvement-CSS-Calc-Collapse-RoundNearest-Up-Down-ToZero-into-a-single-Round-struct
Open

Build time improvement: [CSS Calc] Collapse RoundNearest/Up/Down/ToZero into a single Round struct#62308
brentfulgham wants to merge 1 commit intoWebKit:mainfrom
brentfulgham:eng/Build-time-improvement-CSS-Calc-Collapse-RoundNearest-Up-Down-ToZero-into-a-single-Round-struct

Conversation

@brentfulgham
Copy link
Copy Markdown
Contributor

@brentfulgham brentfulgham commented Apr 8, 2026

3fe5595

Build time improvement: [CSS Calc] Collapse RoundNearest/Up/Down/ToZero into a single Round struct
https://bugs.webkit.org/show_bug.cgi?id=311770
rdar://174359001

Reviewed by NOBODY (OOPS!).

Profiling builds has shown that a significant portion of build time is tied up in template
instantiation of `mpark::variant` types, primarily because of the very deep nesting involved
in WebKit.

We can improve the complexity by replacing the four separate round operation types
(RoundNearest, RoundUp, RoundDown, RoundToZero) with a single Round struct carrying a
RoundingStrategy enum field. This reduces the CSSCalc::Node variant from 37 to 34
alternatives, and the Style::Calculation::Node variant from 32 to 29 alternatives,
shrinking mpark::variant template instantiation depth across ~290 translation units.

This reduces build time be around 4.3%

* Source/WebCore/Headers.cmake:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/css/calc/CSSCalcRoundingStrategy.h: Added.
(WebCore::CSSCalc::nameLiteral):
* Source/WebCore/css/calc/CSSCalcTree+Copy.cpp:
(WebCore::CSSCalc::copy):
* Source/WebCore/css/calc/CSSCalcTree+Evaluation.cpp:
(WebCore::CSSCalc::evaluate):
* Source/WebCore/css/calc/CSSCalcTree+Mappings.h:
* Source/WebCore/css/calc/CSSCalcTree+Parser.cpp:
(WebCore::CSSCalc::consumeRoundArguments):
(WebCore::CSSCalc::consumeRound):
* Source/WebCore/css/calc/CSSCalcTree+Serialization.cpp:
(WebCore::CSSCalc::serializeMathFunctionPrefix):
* Source/WebCore/css/calc/CSSCalcTree+Simplification.cpp:
(WebCore::CSSCalc::simplify):
(WebCore::CSSCalc::copyAndSimplifyChildren):
(WebCore::CSSCalc::simplifyForRound): Deleted.
* Source/WebCore/css/calc/CSSCalcTree+Simplification.h:
* Source/WebCore/css/calc/CSSCalcTree.cpp:
(WebCore::CSSCalc::toType):
* Source/WebCore/css/calc/CSSCalcTree.h:
(WebCore::CSSCalc::toCSSValueID):
(WebCore::CSSCalc::get):
* Source/WebCore/style/calc/StyleCalculationTree+Conversion.cpp:
(WebCore::Style::Calculation::toCSS):
(WebCore::Style::Calculation::toStyle):
* Source/WebCore/style/calc/StyleCalculationTree+Copy.cpp:
(WebCore::Style::Calculation::copy):
* Source/WebCore/style/calc/StyleCalculationTree+Evaluation.cpp:
(WebCore::Style::Calculation::evaluate):
* Source/WebCore/style/calc/StyleCalculationTree.cpp:
(WebCore::Style::Calculation::operator<<):
* Source/WebCore/style/calc/StyleCalculationTree.h:
(WebCore::Style::Calculation::get):

3fe5595

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
❌ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win loading 🛠 ios-apple
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 win-tests loading 🛠 mac-apple
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe ⏳ 🛠 vision-apple
✅ 🧪 ios-wk2-wpt ✅ 🧪 api-mac-debug ✅ 🛠 gtk3-libwebrtc
✅ 🧪 api-ios ✅ 🧪 mac-wk1 ✅ 🛠 gtk
✅ 🛠 ios-safer-cpp ✅ 🧪 mac-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 api-gtk
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🛠 playstation
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2
✅ 🛠 tv ✅ 🛠 mac-safer-cpp
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

@brentfulgham brentfulgham self-assigned this Apr 8, 2026
@brentfulgham brentfulgham added the New Bugs Unclassified bugs are placed in this component until the correct component can be determined. label Apr 8, 2026
@brentfulgham brentfulgham marked this pull request as draft April 8, 2026 22:50
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Apr 8, 2026
…ro into a single Round struct

https://bugs.webkit.org/show_bug.cgi?id=311770
rdar://174359001

Reviewed by NOBODY (OOPS!).

Profiling builds has shown that a significant portion of build time is tied up in template
instantiation of `mpark::variant` types, primarily because of the very deep nesting involved
in WebKit.

We can improve the complexity by replacing the four separate round operation types
(RoundNearest, RoundUp, RoundDown, RoundToZero) with a single Round struct carrying a
RoundingStrategy enum field. This reduces the CSSCalc::Node variant from 37 to 34
alternatives, and the Style::Calculation::Node variant from 32 to 29 alternatives,
shrinking mpark::variant template instantiation depth across ~290 translation units.

This reduces build time be around 4.3%

* Source/WebCore/Headers.cmake:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/css/calc/CSSCalcRoundingStrategy.h: Added.
(WebCore::CSSCalc::nameLiteral):
* Source/WebCore/css/calc/CSSCalcTree+Copy.cpp:
(WebCore::CSSCalc::copy):
* Source/WebCore/css/calc/CSSCalcTree+Evaluation.cpp:
(WebCore::CSSCalc::evaluate):
* Source/WebCore/css/calc/CSSCalcTree+Mappings.h:
* Source/WebCore/css/calc/CSSCalcTree+Parser.cpp:
(WebCore::CSSCalc::consumeRoundArguments):
(WebCore::CSSCalc::consumeRound):
* Source/WebCore/css/calc/CSSCalcTree+Serialization.cpp:
(WebCore::CSSCalc::serializeMathFunctionPrefix):
* Source/WebCore/css/calc/CSSCalcTree+Simplification.cpp:
(WebCore::CSSCalc::simplify):
(WebCore::CSSCalc::copyAndSimplifyChildren):
(WebCore::CSSCalc::simplifyForRound): Deleted.
* Source/WebCore/css/calc/CSSCalcTree+Simplification.h:
* Source/WebCore/css/calc/CSSCalcTree.cpp:
(WebCore::CSSCalc::toType):
* Source/WebCore/css/calc/CSSCalcTree.h:
(WebCore::CSSCalc::toCSSValueID):
(WebCore::CSSCalc::get):
* Source/WebCore/style/calc/StyleCalculationTree+Conversion.cpp:
(WebCore::Style::Calculation::toCSS):
(WebCore::Style::Calculation::toStyle):
* Source/WebCore/style/calc/StyleCalculationTree+Copy.cpp:
(WebCore::Style::Calculation::copy):
* Source/WebCore/style/calc/StyleCalculationTree+Evaluation.cpp:
(WebCore::Style::Calculation::evaluate):
* Source/WebCore/style/calc/StyleCalculationTree.cpp:
(WebCore::Style::Calculation::operator<<):
* Source/WebCore/style/calc/StyleCalculationTree.h:
(WebCore::Style::Calculation::get):
@brentfulgham brentfulgham removed the merging-blocked Applied to prevent a change from being merged label Apr 8, 2026
@brentfulgham brentfulgham force-pushed the eng/Build-time-improvement-CSS-Calc-Collapse-RoundNearest-Up-Down-ToZero-into-a-single-Round-struct branch from bc4929f to 3fe5595 Compare April 8, 2026 23:03
@weinig
Copy link
Copy Markdown
Contributor

weinig commented Apr 9, 2026

Crazy, but if that is the improvement, wow.

Do you know what translation units calc tree types are getting instantiated in? I made an effort to limit this when I originally wrote it, but perhaps that has regressed.

@brentfulgham brentfulgham marked this pull request as ready for review April 9, 2026 17:13
@brentfulgham
Copy link
Copy Markdown
Contributor Author

A/B is partially done and shows no regression so far. I won't land until we get a complete run (hopefully by tomorrow).

@brentfulgham
Copy link
Copy Markdown
Contributor Author

Do you know what translation units calc tree types are getting instantiated in? I made an effort to limit this when I originally wrote it, but perhaps that has regressed.

I attached some output to the bugzilla just now. It's not super helpful but might be usable to figure out what's going on. I'll see if I can get more complete symbol names for the template instantiations so you can at least see the types being used.

The data is primarily about the cost per unified build file, which makes teasing out specific implementation files tedious.

Hopefully that's at least some help.

@brentfulgham brentfulgham added the request-merge-queue Request a pull request to be added to merge-queue once ready label Apr 10, 2026
@weinig
Copy link
Copy Markdown
Contributor

weinig commented Apr 12, 2026

@brentfulgham, out of curiosity, did you try using extern template (like you did for others here #62367) for this?

Copy link
Copy Markdown
Contributor

@weinig weinig left a comment

Choose a reason for hiding this comment

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

By adding support for the new struct layout in CSSCalcTree+Traversal.h, a lot of the overloads should be reduced to just adding support for the enum value.

constexpr ASCIILiteral nameLiteral(RoundingStrategy strategy)
{
switch (strategy) {
case RoundingStrategy::Nearest: return ASCIILiteral::fromLiteralUnsafe("nearest");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These should just use the literal syntax "nearest"_s (etc.).

case RoundingStrategy::Down: return ASCIILiteral::fromLiteralUnsafe("down");
case RoundingStrategy::ToZero: return ASCIILiteral::fromLiteralUnsafe("to-zero");
}
return ASCIILiteral::fromLiteralUnsafe("nearest");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can do a RELEASE_ASSERT_NOT_REACHED() here since the switch is exhaustive.

@weinig
Copy link
Copy Markdown
Contributor

weinig commented Apr 12, 2026

Overall I don't love this, because it doesn't really solve the problem, and it means that with each additional calc node we add (which we will do, there are already some I am working on) it will cause a slowdown.

I'd love to find a solution that reduced the number of translation units these got instantiated in, but if that is not possible, I this seems like an ok short term solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New Bugs Unclassified bugs are placed in this component until the correct component can be determined. request-merge-queue Request a pull request to be added to merge-queue once ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants