Hi jakub,

On Mon, 22 Aug 2011, Jakub Jelinek wrote:
On Mon, Aug 22, 2011 at 01:30:33PM +0300, Dimitrios Apostolou wrote:

@@ -1191,7 +1189,7 @@ dv_uid2hash (dvuid uid)
 static inline hashval_t
 dv_htab_hash (decl_or_value dv)
 {
-  return dv_uid2hash (dv_uid (dv));
+  return (hashval_t) (dv_uid (dv));
 }

Why?  dv_uid2hash is an inline that does exactly that.

@@ -1202,7 +1200,7 @@ variable_htab_hash (const void *x)
 {
   const_variable const v = (const_variable) x;

-  return dv_htab_hash (v->dv);
+  return (hashval_t) (dv_uid (v->dv));
 }

Why?

 /* Compare the declaration of variable X with declaration Y.  */
@@ -1211,9 +1209,8 @@ static int
 variable_htab_eq (const void *x, const void *y)
 {
   const_variable const v = (const_variable) x;
-  decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);

-  return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
+  return (v->dv) == y;
 }

Why?

I was hoping you'd ask so I'll ask back :-) Why are we doing it that way? Why so much indirection in the first place? Why create inline functions just to typecast and why do we need this CONST_CAST2 ugliness in C code. I bet there are things I don't understand so I'd be happy to listen...

The reason I did this (and many more I didn't publish) simplifications within var-tracking is because it hurt my brains to follow the logic. Even with the help of TAGS I have a specific stack depth before I forget where I begun diving into TAG declarations. Well in var-tracking this limit was surpassed by much...


@@ -1397,19 +1398,40 @@ shared_var_p (variable var, shared_hash
          || shared_hash_shared (vars));
 }

+/* Copy all variables from hash table SRC to hash table DST without rehashing
+   any values.  */
+
+static htab_t
+htab_dup (htab_t src)
+{
+  htab_t dst;
+
+  dst = (htab_t) xmalloc (sizeof (*src));
+  memcpy (dst, src, sizeof (*src));
+  dst->entries = (void **) xmalloc (src->size * sizeof (*src->entries));
+  memcpy (dst->entries, src->entries,
+         src->size * sizeof (*src->entries));
+  return dst;
+}
+

This certainly doesn't belong here, it should go into libiberty/hashtab.c
and prototype into include/hashtab.h.  It relies on hashtab.c
implementation details.

OK I'll do that in the future. Should I also move some other htab functions I saw in var-tracking and rtl? FOR_EACH_HTAB_ELEMENT comes to mind, probably other too.


@@ -2034,7 +2041,8 @@ val_resolve (dataflow_set *set, rtx val,
 static void
 dataflow_set_init (dataflow_set *set)
 {
-  init_attrs_list_set (set->regs);
+  /* Initialize the set (array) SET of attrs to empty lists.  */
+  memset (set->regs, 0, sizeof (set->regs));
   set->vars = shared_hash_copy (empty_shared_hash);
   set->stack_adjust = 0;
   set->traversed_vars = NULL;

I'd say you should instead just implement init_attrs_list_set inline using
memset.

It's used only once, that's why I deleted the function. I'll bring it back if you think it helps.


   dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
   dst->vars->refcount = 1;
   dst->vars->htab
-    = htab_create (MAX (src1_elems, src2_elems), variable_htab_hash,
+    = htab_create (2 * MAX (src1_elems, src2_elems), variable_htab_hash,
                   variable_htab_eq, variable_htab_free);

This looks wrong, 2 * max is definitely too much.

For a hash table to fit N elements, it has to have at least 4/3*N slots, or 2*N slots if htab has the 50% load factor I was proposing.

@@ -8996,11 +9006,13 @@ vt_finalize (void)

   FOR_ALL_BB (bb)
     {
-      dataflow_set_destroy (&VTI (bb)->in);
-      dataflow_set_destroy (&VTI (bb)->out);
+      /* The "false" do_free parameter means to not bother to iterate and free
+        all hash table elements, since we'll destroy the pools. */
+      dataflow_set_destroy (&VTI (bb)->in, false);
+      dataflow_set_destroy (&VTI (bb)->out, false);
       if (VTI (bb)->permp)
        {
-         dataflow_set_destroy (VTI (bb)->permp);
+         dataflow_set_destroy (VTI (bb)->permp, false);
          XDELETE (VTI (bb)->permp);
        }
     }


How much does this actually speed things up (the not freeing pool allocated
stuff during finalizaqtion)?  Is it really worth it?

In total for dataflow_set_destroy I can see that calls to attrs_list_clear() have been reduced from 500K to 250K, and I can also see a reduction of free() calls from htab_delete(), from 30K to 10K. I'm willing to bet that much of this is because of this change, I have kept only the ones that showed difference and remember clearly that var-tracking is iterating over hash tables too much, either directly or from htab_traverse()/htab_delete().


Thanks,
Dimitris

Reply via email to