return m_vars[0];
}
-/* Comparator for use by equiv_class::canonicalize. */
-
-static int
-svalue_cmp_by_ptr (const void *p1, const void *p2)
-{
- const svalue *sval1 = *(const svalue * const *)p1;
- const svalue *sval2 = *(const svalue * const *)p2;
- if (sval1 < sval2)
- return 1;
- if (sval1 > sval2)
- return -1;
- return 0;
-}
-
/* Sort the svalues within this equiv_class. */
void
equiv_class::canonicalize ()
{
- m_vars.qsort (svalue_cmp_by_ptr);
+ m_vars.qsort (svalue::cmp_ptr_ptr);
}
/* Get a debug string for C_OP. */
gcc_assert (rep1);
gcc_assert (rep2);
- if (rep1 < rep2)
- return 1;
- if (rep1 > rep2)
- return -1;
- return 0;
+ return svalue::cmp_ptr (rep1, rep2);
}
/* Comparator for use by constraint_manager::canonicalize.
location_t loc1 = pk1->get_location ();
location_t loc2 = pk2->get_location ();
- return linemap_compare_locations (line_table, loc2, loc1);
+ if (int cmp = linemap_compare_locations (line_table, loc2, loc1))
+ return cmp;
+ if (int cmp = ((int)pk1->m_sd.get_epath_length ()
+ - (int)pk2->m_sd.get_epath_length ()))
+ return cmp;
+ if (int cmp = strcmp (pk1->m_sd.m_d->get_kind (),
+ pk2->m_sd.m_d->get_kind ()))
+ return cmp;
+ return 0;
}
const saved_diagnostic &m_sd;
if (int cmp = pv2.m_stack_depth - pv1.m_stack_depth)
return cmp;
+ /* Otherwise, if they have the same readability, then impose an
+ arbitrary deterministic ordering on them. */
+
+ if (int cmp = TREE_CODE (pv1.m_tree) - TREE_CODE (pv2.m_tree))
+ return cmp;
+
+ switch (TREE_CODE (pv1.m_tree))
+ {
+ default:
+ break;
+ case SSA_NAME:
+ if (int cmp = (SSA_NAME_VERSION (pv1.m_tree)
+ - SSA_NAME_VERSION (pv2.m_tree)))
+ return cmp;
+ break;
+ case PARM_DECL:
+ case VAR_DECL:
+ case RESULT_DECL:
+ if (int cmp = DECL_UID (pv1.m_tree) - DECL_UID (pv2.m_tree))
+ return cmp;
+ break;
+ }
+
/* TODO: We ought to find ways of sorting such cases. */
return 0;
}
&& point_b.get_function () != NULL
&& point_a.get_function () != point_b.get_function ())
{
- return ka.m_worklist.m_plan.cmp_function (point_a.get_function (),
- point_b.get_function ());
+ if (int cmp = ka.m_worklist.m_plan.cmp_function (point_a.get_function (),
+ point_b.get_function ()))
+ return cmp;
}
/* First, order by SCC. */
const program_state &state_b = kb.m_enode->get_state ();
/* Sort by sm-state, so that identical sm-states are grouped
- together in the worklist.
- For now, sort by the hash value (might not be deterministic). */
+ together in the worklist. */
for (unsigned sm_idx = 0; sm_idx < state_a.m_checker_states.length ();
++sm_idx)
{
sm_state_map *smap_a = state_a.m_checker_states[sm_idx];
sm_state_map *smap_b = state_b.m_checker_states[sm_idx];
- hashval_t hash_a = smap_a->hash ();
- hashval_t hash_b = smap_b->hash ();
- if (hash_a < hash_b)
- return -1;
- else if (hash_a > hash_b)
- return 1;
+ if (int smap_cmp = sm_state_map::cmp (*smap_a, *smap_b))
+ return smap_cmp;
}
/* Otherwise, we have two enodes at the same program point but with
return NULL; /* for selftests. */
}
+/* struct sm_state_map::entry_t. */
+
+int
+sm_state_map::entry_t::cmp (const entry_t &entry_a, const entry_t &entry_b)
+{
+ gcc_assert (entry_a.m_state);
+ gcc_assert (entry_b.m_state);
+ if (int cmp_state = ((int)entry_a.m_state->get_id ()
+ - (int)entry_b.m_state->get_id ()))
+ return cmp_state;
+ if (entry_a.m_origin && entry_b.m_origin)
+ return svalue::cmp_ptr (entry_a.m_origin, entry_b.m_origin);
+ if (entry_a.m_origin)
+ return 1;
+ if (entry_b.m_origin)
+ return -1;
+ return 0;
+}
+
/* class sm_state_map. */
/* sm_state_map's ctor. */
impl_set_state (*iter, (state_machine::state_t)0, NULL, ext_state);
}
+/* Comparator for imposing an order on sm_state_map instances. */
+
+int
+sm_state_map::cmp (const sm_state_map &smap_a, const sm_state_map &smap_b)
+{
+ if (int cmp_count = smap_a.elements () - smap_b.elements ())
+ return cmp_count;
+
+ auto_vec <const svalue *> keys_a (smap_a.elements ());
+ for (map_t::iterator iter = smap_a.begin ();
+ iter != smap_a.end ();
+ ++iter)
+ keys_a.quick_push ((*iter).first);
+ keys_a.qsort (svalue::cmp_ptr_ptr);
+
+ auto_vec <const svalue *> keys_b (smap_b.elements ());
+ for (map_t::iterator iter = smap_b.begin ();
+ iter != smap_b.end ();
+ ++iter)
+ keys_b.quick_push ((*iter).first);
+ keys_b.qsort (svalue::cmp_ptr_ptr);
+
+ unsigned i;
+ const svalue *sval_a;
+ FOR_EACH_VEC_ELT (keys_a, i, sval_a)
+ {
+ const svalue *sval_b = keys_b[i];
+ if (int cmp_sval = svalue::cmp_ptr (sval_a, sval_b))
+ return cmp_sval;
+ const entry_t *e_a = const_cast <map_t &> (smap_a.m_map).get (sval_a);
+ const entry_t *e_b = const_cast <map_t &> (smap_b.m_map).get (sval_b);
+ if (int cmp_entry = entry_t::cmp (*e_a, *e_b))
+ return cmp_entry;
+ }
+
+ return 0;
+}
+
/* Canonicalize SVAL before getting/setting it within the map.
Convert all NULL pointers to (void *) to avoid state explosions
involving all of the various (foo *)NULL vs (bar *)NULL. */
return !(*this == other);
}
+ static int cmp (const entry_t &entry_a, const entry_t &entry_b);
+
state_machine::state_t m_state;
const svalue *m_origin;
};
iterator_t begin () const { return m_map.begin (); }
iterator_t end () const { return m_map.end (); }
+ size_t elements () const { return m_map.elements (); }
+
+ static int cmp (const sm_state_map &smap_a, const sm_state_map &smap_b);
static const svalue *
canonicalize_svalue (const svalue *sval, const extrinsic_state &ext_state);