public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Martin Koegler <mkoegler@auto.tuwien.ac.at>
To: "Björn Haase" <bjoern.m.haase@web.de>
Cc: gcc@gcc.gnu.org
Subject: named address spaces (update)
Date: Wed, 29 Jun 2005 08:48:00 -0000	[thread overview]
Message-ID: <20050629084740.GA8315@ahab.auto.tuwien.ac.at> (raw)

I continued to work on the support for named address spaces in GCC. I
managed to move much of the managing code for the namespace attribute
into the create funtions of tree nodes, so in most cases, only the
language frontends need to assign and check the named address spaces.

I moved to creation of the namespace list to the gen-modes program
(all examples are taken out of my m68hc05 GCC port
http://www.auto.tuwien.ac.at/~mkoegler/index.php/gcc ). A named
address space is allocated with NAMESPACE(name) in the mode definition
file of the port, eg:

NAMESPACE(EEPROM);
NAMESPACE(LORAM);

(I know, that the NAMESPACE is not the correct naming, but named
address space is a bit too long. Any suggestions?)

This will result in the address spaces EEPROMspace and LORAMspace.  By
default the address spaces DEFAULTspace and NONEspace are generated.
DEFAULTspace is the normal memory, NONEspace an invalid address space
to catch errors.

Index: genmodes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genmodes.c,v
retrieving revision 1.17
diff -u -r1.17 genmodes.c
--- genmodes.c	1 Jun 2005 02:55:50 -0000	1.17
+++ genmodes.c	19 Jun 2005 13:02:16 -0000
@@ -104,6 +104,87 @@
 static struct mode_adjust *adj_alignment;
 static struct mode_adjust *adj_format;
 
+/* named address space */
+struct namespace_data
+{
+  struct namespace_data *next;	/* next this class - arbitrary order */
+
+  const char *name;		/* printable mode name without suffix */
+  const char *file;		/* file and line of definition, */
+  unsigned int line;		/* for error reporting */
+};
+
+static struct namespace_data *namespaces = 0;
+static int n_namespaces = 0;
+static htab_t namespaces_by_name;
+
+/* Utility routines.  */
+static inline struct namespace_data *
+find_namespace (const char *name)
+{
+  struct mode_data key;
+
+  key.name = name;
+  return (struct namespace_data *) htab_find (namespaces_by_name, &key);
+}
+
+static struct namespace_data *
+new_namespace (const char *name,
+	       const char *file, unsigned int line)
+{
+  struct namespace_data *m;
+
+  m = find_namespace (name);
+  if (m)
+    {
+      error ("%s:%d: duplicate definition of namespace \"%s\"",
+	     trim_filename (file), line, name);
+      error ("%s:%d: previous definition here", m->file, m->line);
+      return m;
+    }
+
+  m = XNEW (struct namespace_data);
+  memset (m, 0, sizeof (struct namespace_data));
+  m->name = name;
+  if (file)
+    m->file = trim_filename (file);
+  m->line = line;
+
+  m->next = namespaces;
+  namespaces = m;
+  n_namespaces++;
+
+  *htab_find_slot (namespaces_by_name, m, INSERT) = m;
+  
+  return m;
+}
+
+static hashval_t
+hash_namespace (const void *p)
+{
+  const struct namespace_data *m = (const struct namespace_data *)p;
+  return htab_hash_string (m->name);
+}
+
+static int
+eq_namespace (const void *p, const void *q)
+{
+  const struct namespace_data *a = (const struct namespace_data *)p;
+  const struct namespace_data *b = (const struct namespace_data *)q;
+
+  return !strcmp (a->name, b->name);
+}
+
+#define NAMESPACE(N) make_namespace(#N, __FILE__, __LINE__)
+
+static void
+make_namespace (const char *name,
+		const char *file, unsigned int line)
+{
+  new_namespace (name, file, line);
+}
+
+
 /* Mode class operations.  */
 static enum mode_class
 complex_class (enum mode_class c)
@@ -769,6 +850,7 @@
 {
   int c;
   struct mode_data *m, *first, *last;
+  struct namespace_data *n;
 
   printf ("/* Generated automatically from machmode.def%s%s\n",
 	   HAVE_EXTRA_MODES ? " and " : "",
@@ -827,6 +909,23 @@
 #if 0 /* disabled for backward compatibility, temporary */
   printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
 #endif
+
+  puts ("\
+\n\
+enum namespace_type\n{\n");
+
+  for (n = namespaces; n; n = n->next)
+      {
+	int count_;
+	printf ("  %sspace,%n", n->name, &count_);
+	printf ("%*s/* %s:%d */\n", 27 - count_, "",
+		 trim_filename (n->file), n->line);
+      }
+
+  puts ("\
+  MAX_NAMESPACE,\n\
+  NUM_NAMESPACES = MAX_NAMESPACE\n\
+};\n");
   puts ("\
 \n\
 #endif /* insn-modes.h */");
@@ -866,6 +965,19 @@
 }
 
 static void
+emit_namespace_name (void)
+{
+  struct namespace_data *m;
+
+  print_decl ("char *const", "namespace_name", "NUM_NAMESPACES");
+
+  for (m = namespaces; m; m = m->next)
+    printf ("  \"%s\",\n", m->name);
+
+  print_closer ();
+}
+
+static void
 emit_mode_name (void)
 {
   int c;
@@ -1190,6 +1302,7 @@
 {
   emit_insn_modes_c_header ();
   emit_mode_name ();
+  emit_namespace_name ();
   emit_mode_class ();
   emit_mode_precision ();
   emit_mode_size ();
@@ -1233,6 +1346,7 @@
     }
 
   modes_by_name = htab_create_alloc (64, hash_mode, eq_mode, 0, xcalloc, free);
+  namespaces_by_name = htab_create_alloc (64, hash_namespace, eq_namespace, 0, xcalloc, free);
 
   create_modes ();
   complete_all_modes ();
Index: machmode.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/machmode.def,v
retrieving revision 1.31
diff -u -r1.31 machmode.def
--- machmode.def	28 Apr 2005 05:38:33 -0000	1.31
+++ machmode.def	19 Jun 2005 13:02:17 -0000
@@ -189,6 +189,9 @@
 /* The symbol Pmode stands for one of the above machine modes (usually SImode).
    The tm.h file specifies which one.  It is not a distinct mode.  */
 
+NAMESPACE(DEFAULT);
+NAMESPACE(NONE);
+
 /*
 Local variables:
 mode:c
Index: machmode.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/machmode.h,v
retrieving revision 1.39
diff -u -r1.39 machmode.h
--- machmode.h	1 Jun 2005 00:20:13 -0000	1.39
+++ machmode.h	19 Jun 2005 13:02:17 -0000
@@ -163,4 +163,9 @@
 /* Target-dependent machine mode initialization - in insn-modes.c.  */
 extern void init_adjust_machine_modes (void);
 
+/* Get the name of namespace N as a string.  */
+
+extern const char * const namespace_name[NUM_NAMESPACES];
+#define GET_NAMESPACE_NAME(N)  namespace_name[N]
+
 #endif /* not HAVE_MACHINE_MODES */


The type tree contains a address space attribute, which store the 
address space, a pointer (or reference) point to.

decls contain the address space, in which they are. expression also
contains an address space, in which eg. the members of a structure or
array (this expression) are.

Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.734
diff -u -r1.734 tree.h
--- tree.h	4 Jun 2005 17:22:21 -0000	1.734
+++ tree.h	19 Jun 2005 13:02:19 -0000
@@ -1178,6 +1178,8 @@
 /* In a LOOP_EXPR node.  */
 #define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0)
 
+#define EXPR_NAMESPACE(NODE) (EXPR_CHECK (NODE)->exp.namespace)
+
 #ifdef USE_MAPPED_LOCATION
 /* The source location of this expression.  Non-tree_exp nodes such as
    decls and constants can be shared among multiple locations, so
@@ -1297,6 +1299,7 @@
   struct tree_common common;
   source_locus locus;
   int complexity;
+  enum namespace_type namespace;
   tree block;
   tree GTY ((special ("tree_exp"),
 	     desc ("TREE_CODE ((tree) &%0)")))
@@ -1542,6 +1545,7 @@
 #define TYPE_MAIN_VARIANT(NODE) (TYPE_CHECK (NODE)->type.main_variant)
 #define TYPE_CONTEXT(NODE) (TYPE_CHECK (NODE)->type.context)
 #define TYPE_LANG_SPECIFIC(NODE) (TYPE_CHECK (NODE)->type.lang_specific)
+#define TYPE_NAMESPACE(NODE) (TYPE_CHECK (NODE)->type.namespace)
 
 /* For a VECTOR_TYPE node, this describes a different type which is emitted
    in the debugging output.  We use this to describe a vector as a
@@ -1739,6 +1743,7 @@
   HOST_WIDE_INT alias_set;
   /* Points to a structure whose details depend on the language in use.  */
   struct lang_type *lang_specific;
+  enum namespace_type namespace;
 };
 \f
 /* Define accessor macros for information about type inheritance
@@ -1920,6 +1925,8 @@
     NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file
     scope".  */
 #define DECL_CONTEXT(NODE) (DECL_CHECK (NODE)->decl.context)
+/* namespace */
+#define DECL_NAMESPACE(NODE) (DECL_CHECK (NODE)->decl.namespace)
 #define DECL_FIELD_CONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.context)
 /* In a DECL this is the field where attributes are stored.  */
 #define DECL_ATTRIBUTES(NODE) (DECL_CHECK (NODE)->decl.attributes)
@@ -2447,6 +2454,7 @@
   tree assembler_name;
   tree section_name;
   tree attributes;
+  enum namespace_type namespace;
   rtx rtl;	/* RTL representation for object.  */
 
   /* In FUNCTION_DECL, if it is inline, holds the saved insn chain.
@@ -3503,6 +3511,9 @@
 extern tree upper_bound_in_type (tree, tree);
 extern tree lower_bound_in_type (tree, tree);
 extern int operand_equal_for_phi_arg_p (tree, tree);
+extern enum namespace_type tree_get_namespace (tree);
+extern void tree_copy_namespace (tree, tree);
+
 \f
 /* In stmt.c */
Index: print-tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v
retrieving revision 1.100
diff -u -r1.100 print-tree.c
--- print-tree.c	31 Mar 2005 00:09:10 -0000	1.100
+++ print-tree.c	19 Jun 2005 13:02:17 -0000
@@ -335,6 +335,8 @@
       if (DECL_NONLOCAL (node))
 	fputs (" nonlocal", file);
 
+      fprintf (file, " namespace:%s", GET_NAMESPACE_NAME (DECL_NAMESPACE (node)));
+
       if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
 	fputs (" suppress-debug", file);
 
@@ -528,6 +530,8 @@
       if (TYPE_LANG_FLAG_6 (node))
 	fputs (" type_6", file);
 
+      fprintf (file, " namespace:%s", GET_NAMESPACE_NAME (TYPE_NAMESPACE (node)));
+
       mode = TYPE_MODE (node);
       fprintf (file, " %s", GET_MODE_NAME (mode));
 
@@ -594,6 +598,9 @@
     case tcc_binary:
     case tcc_reference:
     case tcc_statement:
+      if (EXPR_P(node))
+	      fprintf (file, " namespace:%s", GET_NAMESPACE_NAME( EXPR_NAMESPACE (node)));
+
       if (TREE_CODE (node) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (node))
 	fputs (" unsigned", file);
       if (TREE_CODE (node) == BIND_EXPR)
 

If a tree element is created, its address space attribute is
automatically computed. Only in a few cases, it needs to be changed.

tree_copy_namespace is used for propagating the address space.

All build functions of decls, pointer and reference types set the
address space to DEFAULTspace, so that in the normal case, no changes
in the frontend are necessary. I have not yet verfied, that the use of
these functions in the middle-end change a namespace incorrectly.

Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.485
diff -u -r1.485 tree.c
--- tree.c	4 Jun 2005 17:22:20 -0000	1.485
+++ tree.c	19 Jun 2005 13:02:19 -0000
@@ -401,6 +401,7 @@
 
       /* We have not yet computed the alias set for this declaration.  */
       DECL_POINTER_ALIAS_SET (t) = -1;
+      DECL_NAMESPACE (t) = NONEspace;
       break;
 
     case tcc_type:
@@ -415,6 +416,7 @@
 
       /* We have not yet computed the alias set for this type.  */
       TYPE_ALIAS_SET (t) = -1;
+      TYPE_NAMESPACE (t) = NONEspace;
       break;
 
     case tcc_constant:
@@ -440,6 +442,7 @@
 	default:
 	  break;
 	}
+      EXPR_NAMESPACE (t) = NONEspace;
       break;
 
     default:
@@ -2279,12 +2282,14 @@
     case INDIRECT_REF:
       result = build_nt (INDIRECT_REF,
 			 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
+      tree_copy_namespace (result,ref);
       break;
 
     case COMPONENT_REF:
       result = build_nt (COMPONENT_REF,
 			 stabilize_reference (TREE_OPERAND (ref, 0)),
 			 TREE_OPERAND (ref, 1), NULL_TREE);
+      tree_copy_namespace (result,ref);
       break;
 
     case BIT_FIELD_REF:
@@ -2299,6 +2304,7 @@
 			 stabilize_reference (TREE_OPERAND (ref, 0)),
 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
+      tree_copy_namespace (result,ref);
       break;
 
     case ARRAY_RANGE_REF:
@@ -2306,6 +2312,7 @@
 			 stabilize_reference (TREE_OPERAND (ref, 0)),
 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
+      tree_copy_namespace (result,ref);
       break;
 
     case COMPOUND_EXPR:
@@ -2553,6 +2560,7 @@
   t = ggc_alloc_zone_pass_stat (length, &tree_zone);
 
   memset (t, 0, sizeof (struct tree_common));
+  memset (t, 0, length);
 
   TREE_SET_CODE (t, code);
 
@@ -2609,6 +2617,12 @@
       break;
     }
 
+  if(code==NOP_EXPR)
+    tree_copy_namespace(t, node);
+  else if(code==INDIRECT_REF && node)
+      EXPR_NAMESPACE(t) = TYPE_NAMESPACE (TREE_TYPE (node));
+
+
   return t;
 }
 
@@ -2663,6 +2677,13 @@
     = (TREE_CODE_CLASS (code) == tcc_reference
        && arg0 && TREE_THIS_VOLATILE (arg0));
 
+  if(code==COMPOUND_EXPR)
+    tree_copy_namespace (t, arg1);
+  else if(code==MODIFY_EXPR)
+    tree_copy_namespace (t, arg0);
+  else if(code==MISALIGNED_INDIRECT_REF)
+    EXPR_NAMESPACE(t) = TYPE_NAMESPACE (TREE_TYPE (arg0));
+
   return t;
 }
 
@@ -2709,6 +2730,13 @@
     = (TREE_CODE_CLASS (code) == tcc_reference
        && arg0 && TREE_THIS_VOLATILE (arg0));
 
+  if(code==COMPONENT_REF)
+    tree_copy_namespace (t, arg0);
+  else if(code==CALL_EXPR)
+    EXPR_NAMESPACE (t) = DEFAULTspace;
+  else if(code==COND_EXPR)
+    EXPR_NAMESPACE (t)= targetm.merge_namespace(tree_get_namespace(arg1),
+						tree_get_namespace(arg2));
   return t;
 }
 
@@ -2736,6 +2764,11 @@
     = (TREE_CODE_CLASS (code) == tcc_reference
        && arg0 && TREE_THIS_VOLATILE (arg0));
 
+  if(code==ARRAY_REF)
+    tree_copy_namespace (t, arg0);
+  else if(code==TARGET_EXPR)
+    tree_copy_namespace (t, arg0);
+
   return t;
 }
 
@@ -2835,6 +2868,9 @@
   else if (code == FUNCTION_DECL)
     DECL_MODE (t) = FUNCTION_MODE;
 
+  if(code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
+    DECL_NAMESPACE (t) = DEFAULTspace;
+
   /* Set default visibility to whatever the user supplied with
      visibility_specified depending on #pragma GCC visibility.  */
   DECL_VISIBILITY (t) = default_visibility;
@@ -4425,6 +4461,7 @@
   TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
   TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type);
   TYPE_POINTER_TO (to_type) = t;
+  TYPE_NAMESPACE (t)  = DEFAULTspace;
 
   /* Lay out the type.  This function has many callers that are concerned
      with expression-construction, and this simplifies them all.  */
@@ -4474,6 +4511,7 @@
   TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
   TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (to_type);
   TYPE_REFERENCE_TO (to_type) = t;
+  TYPE_NAMESPACE (t)  = DEFAULTspace;
 
   layout_type (t);
 
@@ -6838,4 +6876,33 @@
   return result;
 }
 
+enum namespace_type
+tree_get_namespace (tree t)
+{
+  if(!t)
+    return NONEspace;
+
+  if (TREE_CODE (t) == IMAGPART_EXPR || TREE_CODE (t) == REALPART_EXPR)
+    t = TREE_OPERAND (t, 0);
+
+  if (EXCEPTIONAL_CLASS_P(t))
+    return NONEspace;
+  if (CONSTANT_CLASS_P(t))
+    return DEFAULTspace;
+  if (TREE_CODE(t)==STRING_CST)
+    return DEFAULTspace;
+  if (TYPE_P(t))
+    return NONEspace;
+  if (DECL_P(t))
+    return DECL_NAMESPACE(t);
+  else
+    return EXPR_NAMESPACE(t);
+}
+
+void
+tree_copy_namespace (tree to, tree from)
+{
+  EXPR_NAMESPACE(to) = tree_get_namespace(from);
+}
+
 #include "gt-tree.h"


It introduces tree new hooks:

* compare_namespace checks, if the address space in the first parameter
  can be converted to the address space of the second parameter.
  It is used to check, if assignments are possible.

* merge_namespace returns for any valid combination (where compare_namespace
  succeeds in one way) the union address space.

* extract_mem_ref_flags takes a tree expression and extracts the MEM_REF_FLAGS for
  this expression (which should contain the information about the address space).

For extract_mem_ref_flags, the funtions check_extract_mem_ref_flags is
used at the moment, which fails, if the namespace is missing. This is
intended only for debugging purposes. It can be changed to
hook_int_tree_0, which will cause, that this changes will not affact
any address space unaware backends.

Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.135
diff -u -r1.135 target.h
--- target.h	31 May 2005 15:51:37 -0000	1.135
+++ target.h	19 Jun 2005 13:02:18 -0000
@@ -49,6 +49,7 @@
 
 #include "tm.h"
 #include "insn-modes.h"
+#include "tree.h"
 
 struct stdarg_info;
 
@@ -528,6 +529,21 @@
   /* Returns true if target supports the insn within a doloop block.  */
   bool (*insn_valid_within_doloop) (rtx);
     
+  /* extracts MEM_REF_FLAGS out of a tree expression */
+  int (*extract_mem_ref_flags) (tree t);
+
+  /* compare, if pointer with first namespace can be converted to the value of 
+     the second namespace
+     returns
+     0 error
+     1 ok
+     2 issue warning
+   */
+  int (*compare_namespace) (enum namespace_type, enum namespace_type);
+
+  /* returns the super memory area of both parameters */
+  enum namespace_type (*merge_namespace) (enum namespace_type, enum namespace_type);
+
   /* Functions relating to calls - argument passing, returns, etc.  */
   struct calls {
     bool (*promote_function_args) (tree fntype);
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.123
diff -u -r1.123 target-def.h
--- target-def.h	31 May 2005 15:51:37 -0000	1.123
+++ target-def.h	19 Jun 2005 13:02:18 -0000
@@ -393,6 +393,13 @@
 
 #define TARGET_STDARG_OPTIMIZE_HOOK 0
 
+/* #define TARGET_EXTRACT_MEM_REF_FLAGS hook_int_tree_0 */
+#define TARGET_EXTRACT_MEM_REF_FLAGS check_extract_mem_ref_flags
+
+#define TARGET_COMPARE_NAMESPACE default_compare_namespace
+
+#define TARGET_MERGE_NAMESPACE default_merge_namespace
+
 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_false
 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_false
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
@@ -560,6 +567,9 @@
   TARGET_DWARF_HANDLE_FRAME_UNSPEC,		\
   TARGET_STDARG_OPTIMIZE_HOOK,			\
   TARGET_INSN_VALID_WITHIN_DOLOOP,		\
+  TARGET_EXTRACT_MEM_REF_FLAGS,                 \
+  TARGET_COMPARE_NAMESPACE,                     \
+  TARGET_MERGE_NAMESPACE,                       \
   TARGET_CALLS,					\
   TARGET_CXX,					\
   TARGET_HAVE_NAMED_SECTIONS,			\
Index: targhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/targhooks.c,v
retrieving revision 2.40
diff -u -r2.40 targhooks.c
--- targhooks.c	26 May 2005 18:14:47 -0000	2.40
+++ targhooks.c	19 Jun 2005 13:02:18 -0000
@@ -327,3 +327,34 @@
 {
   return NULL;
 }
+
+int
+default_compare_namespace (enum namespace_type to  ATTRIBUTE_UNUSED,
+			   enum namespace_type from  ATTRIBUTE_UNUSED)
+{
+  return 1;
+}
+
+enum namespace_type
+default_merge_namespace (enum namespace_type a ATTRIBUTE_UNUSED,
+			 enum namespace_type b ATTRIBUTE_UNUSED)
+{
+  return DEFAULTspace;
+}
+
+/* check namespace */
+int
+check_extract_mem_ref_flags (tree expr)
+{
+  enum namespace_type ref = tree_get_namespace(expr);
+  if (TYPE_P (expr))
+    ref = DEFAULTspace;
+
+  if(ref == NONEspace)
+    {
+      if(TREE_CODE (expr) == CONSTRUCTOR)
+	ref=DEFAULTspace;
+    }
+  gcc_assert (ref!=NONEspace);
+  return 0;
+}
Index: targhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/targhooks.h,v
retrieving revision 2.28
diff -u -r2.28 targhooks.h
--- targhooks.h	25 May 2005 11:52:12 -0000	2.28
+++ targhooks.h	19 Jun 2005 13:02:18 -0000
@@ -62,3 +62,6 @@
   (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
 extern const char *hook_invalid_arg_for_unprototyped_fn
   (tree, tree, tree);
+extern int check_extract_mem_ref_flags (tree expr);
+extern int default_compare_namespace (enum namespace_type, enum namespace_type);
+extern enum namespace_type default_merge_namespace (enum namespace_type, enum namespace_type);

Defition and handling of the MEM_REF_FLAGS:

Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.440
diff -u -r1.440 emit-rtl.c
--- emit-rtl.c	28 Apr 2005 05:03:02 -0000	1.440
+++ emit-rtl.c	19 Jun 2005 13:02:15 -0000
@@ -55,6 +55,7 @@
 #include "ggc.h"
 #include "debug.h"
 #include "langhooks.h"
+#include "target.h"
 
 /* Commonly used modes.  */
 
@@ -1450,6 +1454,8 @@
   if (t == NULL_TREE)
     return;
 
+  MEM_REF_FLAGS(ref) = targetm.extract_mem_ref_flags (t);
+
   type = TYPE_P (t) ? t : TREE_TYPE (t);
   if (type == error_mark_node)
     return;
@@ -1686,6 +1692,10 @@
     = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg),
 		     GEN_INT (REG_OFFSET (reg)),
 		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
+
+  if(REG_EXPR (reg))
+    MEM_REF_FLAGS(mem) = targetm.extract_mem_ref_flags (REG_EXPR (reg));
+
 }
 
 /* Set the alias set of MEM to SET.  */
Index: gengtype.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gengtype.c,v
retrieving revision 1.75
diff -u -r1.75 gengtype.c
--- gengtype.c	17 May 2005 20:11:42 -0000	1.75
+++ gengtype.c	19 Jun 2005 13:02:16 -0000
@@ -531,6 +531,8 @@
 	    case '0':
 	      if (i == MEM && aindex == 1)
 		t = mem_attrs_tp, subname = "rt_mem";
+	      else if (i == MEM && aindex == 2)
+		t = scalar_tp, subname = "rt_int";
 	      else if (i == JUMP_INSN && aindex == 9)
 		t = rtx_tp, subname = "rt_rtx";
 	      else if (i == CODE_LABEL && aindex == 4)
Index: print-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v
retrieving revision 1.123
diff -u -r1.123 print-rtl.c
--- print-rtl.c	28 Apr 2005 05:38:34 -0000	1.123
+++ print-rtl.c	19 Jun 2005 13:02:17 -0000
@@ -578,6 +578,8 @@
       if (MEM_ALIGN (in_rtx) != 1)
 	fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
 
+      fprintf (outfile, " %08X", MEM_REF_FLAGS (in_rtx));
+
       fputc (']', outfile);
       break;
 
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.100
diff -u -r1.100 rtl.def
--- rtl.def	22 Jan 2005 22:48:57 -0000	1.100
+++ rtl.def	19 Jun 2005 13:02:17 -0000
@@ -385,8 +385,9 @@
 
 /* A memory location; operand is the address.  The second operand is the
    alias set to which this MEM belongs.  We use `0' instead of `w' for this
-   field so that the field need not be specified in machine descriptions.  */
-DEF_RTL_EXPR(MEM, "mem", "e0", RTX_OBJ)
+   field so that the field need not be specified in machine descriptions.  
+   the third the memory flags */
+DEF_RTL_EXPR(MEM, "mem", "e00", RTX_OBJ)
 
 /* Reference to an assembler label in the code for this function.
    The operand is a CODE_LABEL found in the insn chain.
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.551
diff -u -r1.551 rtl.h
--- rtl.h	1 Jun 2005 11:38:49 -0000	1.551
+++ rtl.h	19 Jun 2005 13:02:17 -0000
@@ -1056,6 +1056,9 @@
    in the block and provide defaults if none specified.  */
 #define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1)
 
+/* A set of flags on a mem */
+#define MEM_REF_FLAGS(RTX)	X0INT ((RTX), 2)
+
 /* The register attribute block.  We provide access macros for each value
    in the block and provide defaults if none specified.  */
 #define REG_ATTRS(RTX) X0REGATTR (RTX, 2)
@@ -1106,6 +1109,7 @@
    MEM_NOTRAP_P (LHS) = MEM_NOTRAP_P (RHS),			\
    MEM_READONLY_P (LHS) = MEM_READONLY_P (RHS),			\
    MEM_KEEP_ALIAS_SET_P (LHS) = MEM_KEEP_ALIAS_SET_P (RHS),	\
+   MEM_REF_FLAGS (LHS) = MEM_REF_FLAGS (RHS),	                \
    MEM_ATTRS (LHS) = MEM_ATTRS (RHS))
 
 /* 1 if RTX is a label_ref to a label outside the loop containing the


The C frontend is extended to support the handling of the address
space attributes. Setting them is done using attributes in backend.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.662
diff -u -r1.662 c-decl.c
--- c-decl.c	6 Jun 2005 19:31:24 -0000	1.662
+++ c-decl.c	19 Jun 2005 13:02:14 -0000
@@ -3638,7 +3638,9 @@
     return error_mark_node;
 
   stmt = build_stmt (DECL_EXPR, decl);
+  tree_copy_namespace(stmt,decl);
   complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
+  tree_copy_namespace(complit,decl);
   TREE_SIDE_EFFECTS (complit) = 1;
 
   layout_decl (decl, 0);
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.449
diff -u -r1.449 c-typeck.c
--- c-typeck.c	6 Jun 2005 19:31:25 -0000	1.449
+++ c-typeck.c	19 Jun 2005 13:02:15 -0000
@@ -652,7 +652,7 @@
 {
   tree t1 = type1;
   tree t2 = type2;
-  int attrval, val;
+  int attrval, val, memareaval;
 
   /* Suppress errors caused by previously reported errors.  */
 
@@ -717,6 +717,12 @@
 	break;
       val = (TREE_TYPE (t1) == TREE_TYPE (t2)
 	     ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
+      memareaval = targetm.compare_namespace (TYPE_NAMESPACE(t1),
+					      TYPE_NAMESPACE(t2));
+      if(!memareaval)
+	return 0;
+      if(memareaval == 2 && val == 1)
+	val = 2;
       break;
 
     case FUNCTION_TYPE:
@@ -3033,6 +3039,15 @@
     }
   else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
     {
+      int memarea_cmp1 = targetm.compare_namespace (TYPE_NAMESPACE(type1),
+						    TYPE_NAMESPACE(type2));
+      int memarea_cmp2 = targetm.compare_namespace  (TYPE_NAMESPACE(type2),
+						     TYPE_NAMESPACE(type1));
+      if(!memarea_cmp1 && !memarea_cmp2)
+	error (N_("incompatible memory areas used"));
+      if(memarea_cmp1==2 && memarea_cmp2==2)
+	warning (0, N_("incompatible memory areas used"));
+
       if (comp_target_types (type1, type2))
 	result_type = common_pointer_type (type1, type2);
       else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
@@ -3062,6 +3077,8 @@
 	  pedwarn ("pointer type mismatch in conditional expression");
 	  result_type = build_pointer_type (void_type_node);
 	}
+      TYPE_NAMESPACE(result_type)=targetm.merge_namespace(TYPE_NAMESPACE(type1),
+							  TYPE_NAMESPACE(type2));
     }
   else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
     {
@@ -3769,6 +3786,13 @@
       bool is_opaque_pointer;
       int target_cmp = 0;   /* Cache comp_target_types () result.  */
 
+      int memarea_cmp = targetm.compare_namespace (TYPE_NAMESPACE(type),
+						   TYPE_NAMESPACE(rhstype));
+      if(!memarea_cmp)
+	error(N_("incompatible memory areas used"));
+      if(memarea_cmp==2)
+	warning (0, N_("incompatible memory areas used"));
+
       if (TREE_CODE (mvl) != ARRAY_TYPE)
 	mvl = TYPE_MAIN_VARIANT (mvl);
       if (TREE_CODE (mvr) != ARRAY_TYPE)
@@ -7675,6 +7699,16 @@
 	{
 	  tree tt0 = TREE_TYPE (type0);
 	  tree tt1 = TREE_TYPE (type1);
+
+	  int memarea_cmp1 = targetm.compare_namespace (TYPE_NAMESPACE(type0),
+							TYPE_NAMESPACE(type1));
+	  int memarea_cmp2 = targetm.compare_namespace (TYPE_NAMESPACE(type1),
+							TYPE_NAMESPACE(type0));
+	  if(!memarea_cmp1 && !memarea_cmp2)
+	    error(N_("incompatible memory areas used"));
+	  if(memarea_cmp1==2 && memarea_cmp2==2)
+	    warning (0, N_("incompatible memory areas used"));
+
 	  /* Anything compares with void *.  void * compares with anything.
 	     Otherwise, the targets must be compatible
 	     and both must be object or both incomplete.  */
@@ -7732,6 +7766,15 @@
 	short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
 	{
+	  int memarea_cmp1 = targetm.compare_namespace (TYPE_NAMESPACE(type0),
+							TYPE_NAMESPACE(type1));
+	  int memarea_cmp2 = targetm.compare_namespace (TYPE_NAMESPACE(type1),
+							TYPE_NAMESPACE(type0));
+	  if(!memarea_cmp1&&!memarea_cmp2)
+	    error(N_("incompatible memory areas used"));
+	  if(memarea_cmp1==2&&memarea_cmp2==2)
+	    warning(0, N_("incompatible memory areas used"));
+	  
 	  if (comp_target_types (type0, type1))
 	    {
 	      result_type = common_pointer_type (type0, type1);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.785
diff -u -r1.785 decl2.c
--- cp/decl2.c	6 Jun 2005 14:18:06 -0000	1.785
+++ cp/decl2.c	19 Jun 2005 13:02:19 -0000
@@ -2001,6 +2001,7 @@
 {
   if (!targetm.cxx.guard_mask_bit ())
     {
+      tree orig = guard;
       /* We only set the first byte of the guard, in order to leave room
 	 for a mutex in the high-order bits.  */
       guard = build1 (ADDR_EXPR, 
@@ -2010,6 +2011,7 @@
 		      build_pointer_type (char_type_node), 
 		      guard);
       guard = build1 (INDIRECT_REF, char_type_node, guard);
+      tree_copy_namespace (guard, orig);
     }
 
   return guard;


As attribute handler, my backend uses:
/* Handle a "eeprom" attribute; arguments as in
   struct attribute_spec.handler.  */
static tree
m68hc05_handle_eeprom_attribute (tree * node, tree name,
                                 tree args ATTRIBUTE_UNUSED,
                                 int flags ATTRIBUTE_UNUSED,
                                 bool * no_add_attrs ATTRIBUTE_UNUSED)
{
  if (POINTER_TYPE_P (*node))
    {
      *node = copy_node (*node);
      TYPE_NAMESPACE (*node) = EEPROMspace;
    }
  else if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
    {
      *node = copy_node (*node);
      DECL_NAMESPACE (*node) = EEPROMspace;
    }
  else
    warning (0, "%qs attribute does not apply", IDENTIFIER_POINTER (name));

  return NULL_TREE;
}

The attributes are defined as:
  {"eepromt", 0, 0, false, true, false, m68hc05_handle_eeprom_attribute},
  {"eeprom", 0, 0, true, false, false, m68hc05_handle_eeprom_attribute},
It uses two attributes, as an attribute can not be a decl and type attribute
at the same time.

The extract_mem_ref_flags hook is similare to check_extract_mem_ref_flags,
it additionally converts the ref variable into an return value.

The expander check for the EEPROM address space and generate differnt
code, if present. The LORAM space is check by extra_constaints and
causes an other alternative to be selected.

Limitations are:
* If one namespace is part of an other namespace, the conversation
  between them must be a simple move (ie they must have the same 
  addresses).
* All pointer have Pmode size.

mfg Martin Kögler


             reply	other threads:[~2005-06-29  8:48 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-06-29  8:48 Martin Koegler [this message]
2005-06-29 12:18 ` DJ Delorie
2005-06-29 15:38   ` E. Weddington
2005-06-29 13:15 ` Daniel Jacobowitz
2005-06-29 15:37 ` E. Weddington
2005-07-02  1:49 ` James E Wilson
2005-07-03 14:31   ` Martin Koegler
2005-07-07  2:59     ` James E Wilson
2005-07-08  1:55 Paul Schlie
2005-07-10 14:41 ` Martin Koegler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050629084740.GA8315@ahab.auto.tuwien.ac.at \
    --to=mkoegler@auto.tuwien.ac.at \
    --cc=bjoern.m.haase@web.de \
    --cc=gcc@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).