superedge *sedge;
FOR_EACH_VEC_ELT (v_snode->m_succs, i, sedge)
{
+ if (sedge->get_kind () != SUPEREDGE_CFG_EDGE
+ && sedge->get_kind () != SUPEREDGE_INTRAPROCEDURAL_CALL)
+ continue;
supernode *w_snode = sedge->m_dest;
per_node_data *w = &m_per_node[w_snode->m_index];
if (w->m_index == -1)
/* Comparator for implementing worklist::key_t comparison operators.
Return negative if KA is before KB
Return positive if KA is after KB
- Return 0 if they are equal. */
+ Return 0 if they are equal.
+
+ The ordering of the worklist is critical for performance and for
+ avoiding node explosions. Ideally we want all enodes at a CFG join-point
+ with the same callstring to be sorted next to each other in the worklist
+ so that a run of consecutive enodes can be merged and processed "in bulk"
+ rather than individually or pairwise, minimizing the number of new enodes
+ created. */
int
worklist::key_t::cmp (const worklist::key_t &ka, const worklist::key_t &kb)
gcc_assert (snode_a == snode_b);
+ /* The points might vary by callstring; try sorting by callstring. */
+ int cs_cmp = call_string::cmp (call_string_a, call_string_b);
+ if (cs_cmp)
+ return cs_cmp;
+
/* Order within supernode via program point. */
int within_snode_cmp
= function_point::cmp_within_supernode (point_a.get_function_point (),
if (within_snode_cmp)
return within_snode_cmp;
- /* The points might vary by callstring; try sorting by callstring. */
- int cs_cmp = call_string::cmp (call_string_a, call_string_b);
- if (cs_cmp)
- return cs_cmp;
-
/* Otherwise, we ought to have the same program_point. */
gcc_assert (point_a == point_b);
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
- // FIXME: why 5 here?
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
- // FIXME: why 5 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
- // FIXME: why 5 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
if (need_to_free)
free (ptr); /* { dg-bogus "not on the heap" } */
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
- // FIXME: why 5 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
if (ptr != buf)
free (ptr); /* { dg-bogus "not on the heap" } */
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "6 processed enodes" } */
- // FIXME: why 6 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ // FIXME: why 3 here?
if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */
/* Examples of switch statements with many cases (with default values).
Adapted from Linux 5.9-rc1:drivers/media/v4l2-core/v4l2-ctrls.c. */
-/* { dg-additional-options "-O1 -Wno-analyzer-too-complex" } */
-// TODO: remove need for -Wno-analyzer-too-complex
+/* { dg-additional-options "-O1" } */
typedef unsigned int u32;
typedef long long s64;