java-topology/defects/gcc/patch/gcc-0002-gimple-range-path-hashset.patch

88 lines
3 KiB
Diff

# UNDF: UNDF-2026-000000077
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index d3e4f5a..c6b7d8e 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -15,6 +15,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
+#include "hash-set.h"
#include "gimple.h"
#include "cfganal.h"
@@ -487,6 +487,12 @@ path_range_query::compute_exit_dependencies (bitmap dependencies)
basic_block exit = m_path[0];
bitmap_copy (dependencies, gori_ssa ()->imports (exit));
+ // CWE-407 fix: m_path.contains(bb) was O(|m_path|) per SSA name in the
+ // worklist. The worklist can hold O(|m_path| * SSA_names) items, making
+ // the total cost O(|m_path|^2 * SSA_names).
+ // Pre-build a hash_set<basic_block> from m_path for O(1) membership.
+ hash_set<basic_block> path_set;
+ for (basic_block bb : m_path)
+ path_set.add (bb);
+
auto_vec<tree> worklist (bitmap_count_bits (dependencies));
bitmap_iterator bi;
unsigned i;
@@ -503,14 +510,14 @@ path_range_query::compute_exit_dependencies (bitmap dependencies)
tree name = worklist.pop ();
gimple *def_stmt = SSA_NAME_DEF_STMT (name);
if (SSA_NAME_IS_DEFAULT_DEF (name)
- || !m_path.contains (gimple_bb (def_stmt)))
+ || !path_set.contains (gimple_bb (def_stmt)))
continue;
if (gphi *phi = dyn_cast <gphi *> (def_stmt))
{
for (size_t i = 0; i < gimple_phi_num_args (phi); ++i)
{
edge e = gimple_phi_arg_edge (phi, i);
tree arg = gimple_phi_arg (phi, i)->def;
if (TREE_CODE (arg) == SSA_NAME
- && m_path.contains (e->src)
+ && path_set.contains (e->src)
&& bitmap_set_bit (dependencies, SSA_NAME_VERSION (arg)))
worklist.safe_push (arg);
}
@@ -528,5 +535,5 @@ path_range_query::compute_exit_dependencies (bitmap dependencies)
for (i = 0; i < m_path.length (); ++i)
{
basic_block bb = m_path[i];
tree name;
FOR_EACH_GORI_EXPORT_NAME (gori_ssa (), bb, name)
if (TREE_CODE (TREE_TYPE (name)) == BOOLEAN_TYPE)
bitmap_set_bit (dependencies, SSA_NAME_VERSION (name));
}
}
# Ticket: gcc-0002
# File: gcc/gimple-range-path.cc
# Line: 510, 521 (compute_exit_dependencies)
# CWE: 407 — Inefficient Algorithmic Complexity
# Severity: HIGH
#
# Pattern:
# while (!worklist.is_empty ())
# {
# ...
# if (!m_path.contains (gimple_bb (def_stmt))) // O(|m_path|)
# continue;
# for (phi args) {
# if (m_path.contains (e->src) ...) // O(|m_path|)
# worklist.safe_push (arg);
# }
# }
#
# m_path is an auto_vec<basic_block>. auto_vec::contains() is a linear
# scan. The worklist grows with each phi arg that is on the path, so
# worst-case |worklist| = O(P * N) where P = path length, N = SSA names.
# Each worklist item does O(P) work → total O(P^2 * N).
#
# Fix: pre-build hash_set<basic_block> from m_path; O(1) per lookup.
# Total cost drops to O(P + P*N) = O(P*N).
#
# Speedup: O(P^2*N) → O(P*N). At P=100 BBs, N=500 SSA names: 5M ops → 50K.
# Speedup factor: ~100x (= P).