diff options
author | Alexis Engelke <engelke@in.tum.de> | 2025-06-18 18:56:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-18 18:56:30 +0200 |
commit | 2a8c65e983b3f4e1c83d8028d354f7bacc149015 (patch) | |
tree | 892caefb080a91744d780b7c9f5762728e2db343 /llvm/lib/CodeGen/MachineFunction.cpp | |
parent | 4084ffcf1e69b962e864aa138bb54dabbcec912f (diff) | |
download | llvm-2a8c65e983b3f4e1c83d8028d354f7bacc149015.zip llvm-2a8c65e983b3f4e1c83d8028d354f7bacc149015.tar.gz llvm-2a8c65e983b3f4e1c83d8028d354f7bacc149015.tar.bz2 |
[CodeGen][NFC] Fix quadratic c-t for large jump tables
Deleting a basic block removes all references from jump tables, which
is O(n). When freeing a MachineFunction, all basic blocks are deleted
before the jump tables, causing O(n^2) runtime. Fix this by deallocating
the jump table first.
Test case generator:
import sys
n = int(sys.argv[1])
print("define void @f(i64 %c, ptr %p) {")
print(" switch i64 %c, label %d [")
for i in range(n):
print(f" i64 {i}, label %h{i}")
print(f" ]")
for i in range(n):
print(f'h{i}:')
print(f' store i64 {i*i}, ptr %p')
print(f' ret void')
print('d:')
print(' ret void')
print('}')
Improvement at 5000 entries:
Benchmark 1: ./llc.pre -filetype=obj -O0 <switch5k.bc
Time (mean ± σ): 49.7 ms ± 1.0 ms
Range (min … max): 48.0 ms … 52.1 ms 57 runs
Benchmark 2: ./llc.post -filetype=obj -O0 <switch5k.bc
Time (mean ± σ): 39.4 ms ± 0.8 ms
Range (min … max): 37.1 ms … 41.1 ms 72 runs
Summary
./llc.post -filetype=obj -O0 <switch5k.bc ran
1.26 ± 0.04 times faster than ./llc.pre -filetype=obj -O0 <switch5k.bc
Improvement at 20000 entries:
Benchmark 1: ./llc.pre -filetype=obj -O0 <switch20k.bc
Time (mean ± σ): 281.7 ms ± 1.0 ms
Range (min … max): 280.2 ms … 283.0 ms 10 runs
Benchmark 2: ./llc.post -filetype=obj -O0 <switch20k.bc
Time (mean ± σ): 123.9 ms ± 1.5 ms
Range (min … max): 121.4 ms … 129.2 ms 23 runs
Summary
./llc.post -filetype=obj -O0 <switch20k.bc ran
2.27 ± 0.03 times faster than ./llc.pre -filetype=obj -O0 <switch20k.bc
Pull Request: https://github.com/llvm/llvm-project/pull/144108
Diffstat (limited to 'llvm/lib/CodeGen/MachineFunction.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineFunction.cpp | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index 607e87a..38ad582 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -259,6 +259,15 @@ MachineFunction::~MachineFunction() { void MachineFunction::clear() { Properties.reset(); + + // Clear JumpTableInfo first. Otherwise, every MBB we delete would do a + // linear search over the jump table entries to find and erase itself. + if (JumpTableInfo) { + JumpTableInfo->~MachineJumpTableInfo(); + Allocator.Deallocate(JumpTableInfo); + JumpTableInfo = nullptr; + } + // Don't call destructors on MachineInstr and MachineOperand. All of their // memory comes from the BumpPtrAllocator which is about to be purged. // @@ -287,11 +296,6 @@ void MachineFunction::clear() { ConstantPool->~MachineConstantPool(); Allocator.Deallocate(ConstantPool); - if (JumpTableInfo) { - JumpTableInfo->~MachineJumpTableInfo(); - Allocator.Deallocate(JumpTableInfo); - } - if (WinEHInfo) { WinEHInfo->~WinEHFuncInfo(); Allocator.Deallocate(WinEHInfo); |