Now possible to match specific pointer types.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 26 Aug 2010 01:17:09 +0000 (21:17 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Thu, 26 Aug 2010 01:17:09 +0000 (21:17 -0400)
src/aop-main.c
src/aop-type.c
src/aop-type.h
src/aop.h

index beac84191b5cb5821bc527ec4e47e9803dafefdd..1a06f31f80205d017a0d1797380cd108b8881f0c 100644 (file)
@@ -53,6 +53,7 @@
 #include "aop.h"
 #include "aop-duplicate.h"
 #include "aop-pointcut.h"
+#include "aop-type.h"
 
 //#define PAUSE_ON_START
 
@@ -218,6 +219,7 @@ cleanup_passes ()
 static void
 aop_cleanup (void *event_date, void *data)
 {
+  free_type_table ();
   cleanup_passes ();
 }
 
@@ -245,6 +247,9 @@ plugin_init (struct plugin_name_args *plugin_info,
 
   aop_plugin_name = plugin_info->base_name;
 
+  /* Initialization for aop-type.c. */
+  init_type_table ();
+
   /* Register our cleanup function. */
   register_callback (aop_plugin_name, PLUGIN_FINISH, aop_cleanup, NULL);
 
index f8eecf0084a64e888110daa2864513a976285771..113fc023af8a408056d52a27046ff1abb257c5c8 100644 (file)
@@ -29,6 +29,7 @@
 #include <coretypes.h>
 #include <tm.h>
 #include <tree.h>
+#include <hashtab.h>
 
 #include "aop.h"
 #include "aop-type.h"
@@ -169,6 +170,106 @@ static struct aop_type _aop_t_float128 = {
   .size = 16,
 };
 
+static htab_t type_table = NULL;
+
+/* Compare strings but safe to pass NULL strings.  Two NULL inputs are
+   considered equal. */
+static bool
+safe_str_equal (const char *a, const char *b)
+{
+  if (a == NULL && b == NULL)
+    return true;
+  else if (a == NULL || b == NULL)
+    return false;
+  else
+    return (strcmp (a, b) == 0);
+}
+
+/* Equality function for the type_table hash table. */
+static int
+eq_type_table (const void *table_ptr, const void *key_ptr)
+{
+  const struct aop_type *type_in_table = (const struct aop_type *)table_ptr;
+  const struct aop_type *key_type = (const struct aop_type *)key_ptr;
+
+  return ((type_in_table->kind == key_type->kind)
+         && (type_in_table->pointer_levels == key_type->pointer_levels)
+         && safe_str_equal (type_in_table->tag, key_type->tag)
+         && (type_in_table->size == key_type->size));
+}
+
+/* Hash function for the type_table hash table. */
+static hashval_t
+hash_type_table (const void *ptr)
+{
+  hashval_t hash;
+  const struct aop_type *type = (const struct aop_type *)ptr;
+
+  /* We start the hash off by hashing the tag string if there is one
+     or an arbitrary seed if there isn't. */
+  hash = (type->tag != NULL) ? htab_hash_string (type->tag) : 8675309;
+  hash = iterative_hash (&type->kind, sizeof (type->kind), hash);
+  hash = iterative_hash (&type->pointer_levels, sizeof (type->pointer_levels),
+                        hash);
+  hash = iterative_hash (&type->size, sizeof (type->size), hash);
+
+  return hash;
+}
+
+/* Function to destroy an element in the type table after it is
+   deleted (or when the whole table is destroyed). */
+static void
+del_type_table (void *ptr)
+{
+  struct aop_type *type = (struct aop_type *)ptr;
+
+  if (type->tag != NULL)
+    free ((char *)type->tag);
+
+  free (type);
+}
+
+/* Return a pointer to a type object that is identical to the supplied
+   type object.  If you pass two identical type objects to
+   get_dedup_type(), you will get the same pointer back.  The objects
+   that get_dedup_type() returns are valid for the rest of the
+   compiler's execution. */
+static const struct aop_type *
+get_dedup_type (struct aop_type *type)
+{
+  struct aop_type **type_slot;
+
+  aop_assert (type_table != NULL);
+
+  type_slot = (struct aop_type **)htab_find_slot (type_table, type, INSERT);
+  if (*type_slot == NULL)
+    {
+      *type_slot = xmalloc (sizeof (struct aop_type));
+      memcpy (*type_slot, type, sizeof (struct aop_type));
+
+      if (type->tag != NULL)
+       (*type_slot)->tag = xstrdup (type->tag);
+    }
+
+  return *type_slot;
+}
+
+void
+init_type_table ()
+{
+  type_table = htab_create_alloc (10, hash_type_table, eq_type_table,
+                                 del_type_table, xcalloc, free);
+  aop_assert (type_table != NULL);
+}
+
+void
+free_type_table ()
+{
+  aop_assert (type_table != NULL);
+  htab_delete (type_table);
+  type_table = NULL;
+}
+
 /**
  * \defgroup type InterAspect Types
  * \{
@@ -396,6 +497,17 @@ aop_t_float128 ()
   return &_aop_t_float128;
 }
 
+const struct aop_type *
+aop_t_pointer_to (const struct aop_type *type)
+{
+  struct aop_type pointer_type;
+
+  memcpy (&pointer_type, type, sizeof (struct aop_type));
+  pointer_type.pointer_levels++;
+
+  return get_dedup_type (&pointer_type);
+}
+
 /* Close Doxygen defgroup block. */
 /**
  * \}
@@ -472,25 +584,31 @@ does_fp_type_match (tree gcc_type, int aop_size)
 bool
 does_type_match (tree gcc_type, const struct aop_type *aop_type)
 {
+  int pointer_levels;
+
   aop_assert (gcc_type != NULL && aop_type != NULL);
 
-  if (aop_type->kind == ATK_ALL_POINTER)
+  pointer_levels = aop_type->pointer_levels;
+  while (pointer_levels > 0)
     {
-      return (TREE_CODE (gcc_type) == POINTER_TYPE);
+      if (TREE_CODE (gcc_type) != POINTER_TYPE)
+       return false;
+
+      /* What type does it point to? */
+      gcc_type = TREE_TYPE (gcc_type);
+      pointer_levels--;
     }
-  else if (aop_type->pointer_levels == 0)
+
+  switch (aop_type->kind)
     {
-      switch (aop_type->kind)
-       {
-       case ATK_SIGNED_INT:
-       case ATK_UNSIGNED_INT:
-         return does_int_type_match (gcc_type, aop_type->kind, aop_type->size);
-       case ATK_FP:
-         return does_fp_type_match (gcc_type, aop_type->size);
-       default:
-         break;
-       }
+    case ATK_ALL_POINTER:
+      return (TREE_CODE (gcc_type) == POINTER_TYPE);
+    case ATK_SIGNED_INT:
+    case ATK_UNSIGNED_INT:
+      return does_int_type_match (gcc_type, aop_type->kind, aop_type->size);
+    case ATK_FP:
+      return does_fp_type_match (gcc_type, aop_type->size);
+    default:
+      aop_assert (0);
     }
-
-  aop_assert (0);
 }
index 5d3ca044ee7ddeab9bbc2c84a5efe903e9e44789..ce37c9e7bc3793d5d2aab89e340d37dc5008abc9 100644 (file)
@@ -28,6 +28,9 @@ enum aop_tykind {
   ATK_UNION,
 };
 
+/* NB: Do not update this struct without updating the correspodning
+   equality (eq_type_table()) and hash (hash_type_table()) functions
+   in aop-type.c. */
 struct aop_type {
   enum aop_tykind kind;
 
@@ -37,6 +40,9 @@ struct aop_type {
   int size;
 };
 
+extern void init_type_table ();
+extern void free_type_table ();
+
 extern bool is_all_integer_type (const struct aop_type *type);
 extern bool is_all_fp_type (const struct aop_type *type);
 extern bool does_type_match (tree gcc_type, const struct aop_type *aop_type);
index eff2ab342e7f9959e2e0feafc7d455c24059efaf..10f9f72a3e63f7485139f2eaa83f5af766b2baf3 100644 (file)
--- a/src/aop.h
+++ b/src/aop.h
@@ -180,6 +180,7 @@ extern const struct aop_type *aop_t_unsigned128 ();
 extern const struct aop_type *aop_t_float32 ();
 extern const struct aop_type *aop_t_float64 ();
 extern const struct aop_type *aop_t_float128 ();
+extern const struct aop_type *aop_t_pointer_to (const struct aop_type *type);
 
 extern void aop_register_pass (const char *pass_name, pass_callback callback);
 extern void aop_join_on (struct aop_pointcut *pc, join_callback callback,