29 lines
1.3 KiB
Diff
29 lines
1.3 KiB
Diff
# UNDF: UNDF-2026-000000774
|
||
# UNDF: (leave blank)
|
||
# CWE-407: PartialInlinerImpl IsSingleExit BlockList membership O(N²)
|
||
#
|
||
# In computeOutliningColdRegionsInfo, the IsSingleExit lambda iterates
|
||
# over every block in BlockList and for each successor calls
|
||
# is_contained(BlockList, Succ), which is O(N) per call.
|
||
# Total: O(N × S × N) = O(N² × S) where N = region blocks, S = avg successors.
|
||
#
|
||
# Fix: build a SmallPtrSet from BlockList for O(1) membership lookups.
|
||
#
|
||
# Severity: LOW-MEDIUM — only runs with instrumentation profiling data,
|
||
# but region sizes can be large in profiled builds of complex functions.
|
||
#
|
||
--- a/llvm/lib/Transforms/IPO/PartialInlining.cpp
|
||
+++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp
|
||
@@ -368,10 +368,12 @@
|
||
auto IsSingleExit =
|
||
[&ORE](SmallVectorImpl<BasicBlock *> &BlockList) -> BasicBlock * {
|
||
BasicBlock *ExitBlock = nullptr;
|
||
+ // Build set for O(1) membership tests (was O(N) linear scan).
|
||
+ SmallPtrSet<BasicBlock *, 16> BlockSet(BlockList.begin(), BlockList.end());
|
||
for (auto *Block : BlockList) {
|
||
for (BasicBlock *Succ : successors(Block)) {
|
||
- if (!is_contained(BlockList, Succ)) {
|
||
+ if (!BlockSet.count(Succ)) {
|
||
if (ExitBlock) {
|
||
ORE.emit([&]() {
|
||
return OptimizationRemarkMissed(DEBUG_TYPE, "MultiExitRegion",
|