[CodeGen] Allow -enable-ext-tsp-block-placement and -apply-ext-tsp-for-size passed together - #183642
Merged
Merged
Conversation
…for-size` work together Reorder the computation of `UseExtTspForPerf` and `UseExtTspForSize` so that when both `-enable-ext-tsp-block-placement` and `-apply-ext-tsp-for-size` are enabled, they are mutually exclusive per-function: functions with the `OptForSize` attribute use ext-tsp block placement for size, while hot functions with profile data use ext-tsp block placement for perf. Previously, `UseExtTspForPerf` was computed first without considering `UseExtTspForSize`, so a function could potentially have both flags set. Now `UseExtTspForSize` is evaluated first, and `UseExtTspForPerf` is only set when `!UseExtTspForSize`.
Member
|
@llvm/pr-subscribers-backend-x86 Author: None (SharonXSharon) ChangesCurrently, the asserts fires when both Ideally, we should allow The diff makes Full diff: https://github.com/llvm/llvm-project/pull/183642.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index 625fba36b3d3a..f0e5e7efd132c 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -3598,10 +3598,10 @@ bool MachineBlockPlacement::run(MachineFunction &MF) {
bool UseExtTspForPerf = false;
bool UseExtTspForSize = false;
if (3 <= MF.size() && MF.size() <= ExtTspBlockPlacementMaxBlocks) {
+ UseExtTspForSize = OptForSize && ApplyExtTspForSize;
UseExtTspForPerf =
- EnableExtTspBlockPlacement &&
+ !UseExtTspForSize && EnableExtTspBlockPlacement &&
(ApplyExtTspWithoutProfile || MF.getFunction().hasProfileData());
- UseExtTspForSize = OptForSize && ApplyExtTspForSize;
}
// Apply tail duplication.
diff --git a/llvm/test/CodeGen/X86/code_placement_ext_tsp_size_and_perf.ll b/llvm/test/CodeGen/X86/code_placement_ext_tsp_size_and_perf.ll
new file mode 100644
index 0000000000000..0980bba58f018
--- /dev/null
+++ b/llvm/test/CodeGen/X86/code_placement_ext_tsp_size_and_perf.ll
@@ -0,0 +1,91 @@
+; RUN: llc -mcpu=corei7 -mtriple=x86_64-linux -verify-machineinstrs -enable-ext-tsp-block-placement -apply-ext-tsp-for-size < %s | FileCheck %s
+
+;; Cold function with optsize: should use ext-tsp for size.
+;; The size-optimized layout keeps the original order (b0, b1, b2) since it
+;; minimizes code size by avoiding extra jumps.
+define void @cold_func() optsize !prof !2 {
+;
+; +-----+
+; | b0 | -+
+; +-----+ |
+; | |
+; | 10 |
+; v |
+; +-----+ |
+; | b1 | | 10000
+; +-----+ |
+; | |
+; | 10 |
+; v |
+; +-----+ |
+; | b2 | <+
+; +-----+
+;
+; CHECK-LABEL: cold_func:
+; CHECK: %b0
+; CHECK: %b1
+; CHECK: %b2
+
+b0:
+ %call = call zeroext i1 @a()
+ br i1 %call, label %b1, label %b2, !prof !1
+
+b1:
+ call void @d()
+ call void @d()
+ call void @d()
+ br label %b2
+
+b2:
+ call void @e()
+ ret void
+}
+
+;; Hot function without optsize: should use ext-tsp for perf.
+;; The perf-optimized layout reorders blocks to place the most likely successor
+;; (b2) right after b0, giving b0 -> b2 -> b1.
+define void @hot_func() !prof !3 {
+;
+; +-----+
+; | b0 | -+
+; +-----+ |
+; | |
+; | 40 |
+; v |
+; +-----+ |
+; | b1 | | 100
+; +-----+ |
+; | |
+; | 40 |
+; v |
+; +-----+ |
+; | b2 | <+
+; +-----+
+;
+; CHECK-LABEL: hot_func:
+; CHECK: %b0
+; CHECK: %b2
+; CHECK: %b1
+
+b0:
+ %call = call zeroext i1 @a()
+ br i1 %call, label %b1, label %b2, !prof !1
+
+b1:
+ call void @d()
+ call void @d()
+ call void @d()
+ br label %b2
+
+b2:
+ call void @e()
+ ret void
+}
+
+declare zeroext i1 @a()
+declare void @d()
+declare void @e()
+
+!1 = !{!"branch_weights", i32 10, i32 10000}
+!2 = !{!"function_entry_count", i64 1}
+!3 = !{!"function_entry_count", i64 2200}
|
ellishg
approved these changes
Feb 27, 2026
sahas3
pushed a commit
to sahas3/llvm-project
that referenced
this pull request
Mar 4, 2026
…-for-size` passed together (llvm#183642) Currently, the asserts fires when both `UseExtTspForPerf` and `UseExtTspForSize` are true on a given function. Ideally, we should allow `-enable-ext-tsp-block-placement` and `-apply-ext-tsp-for-size` passed together, meaning run the block placement for performance on hot functions, while run the placement for size on cold functions. The diff makes `UseExtTspForPerf` and `UseExtTspForSize` mutually exclusive per-function: functions with the `OptForSize` attribute use ext-tsp block placement for size, while the others use ext-tsp block placement for perf. Co-authored-by: Sharon Xu <sharonxu@fb.com>
sujianIBM
pushed a commit
to sujianIBM/llvm-project
that referenced
this pull request
Mar 5, 2026
…-for-size` passed together (llvm#183642) Currently, the asserts fires when both `UseExtTspForPerf` and `UseExtTspForSize` are true on a given function. Ideally, we should allow `-enable-ext-tsp-block-placement` and `-apply-ext-tsp-for-size` passed together, meaning run the block placement for performance on hot functions, while run the placement for size on cold functions. The diff makes `UseExtTspForPerf` and `UseExtTspForSize` mutually exclusive per-function: functions with the `OptForSize` attribute use ext-tsp block placement for size, while the others use ext-tsp block placement for perf. Co-authored-by: Sharon Xu <sharonxu@fb.com>
This was referenced Apr 15, 2026
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.
Currently, the asserts fires when both
UseExtTspForPerfandUseExtTspForSizeare true on a given function.Ideally, we should allow
-enable-ext-tsp-block-placementand-apply-ext-tsp-for-sizepassed together, meaning run the block placement for performance on hot functions, while run the placement for size on cold functions.The diff makes
UseExtTspForPerfandUseExtTspForSizemutually exclusive per-function: functions with theOptForSizeattribute use ext-tsp block placement for size, while the others use ext-tsp block placement for perf.