decl.c: Do not emit a variable for a object that has an address representation clause...
authorTristan Gingold <gingold@adacore.com>
Tue, 20 May 2008 12:44:43 +0000 (14:44 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Tue, 20 May 2008 12:44:43 +0000 (14:44 +0200)
2008-05-20  Tristan Gingold  <gingold@adacore.com>

* decl.c: Do not emit a variable for a object that has an address
representation clause whose value is known at compile time.
When a variable has an address clause whose value is known at compile
time, refer to this variable by using directly the address instead of
dereferencing a pointer.

From-SVN: r135618

gcc/ada/decl.c

index 8565305c2d5ff6c4dd36feedd0675d80796c13bf..8f29ca77dfc37b558631daadc3b214541baaddf8 100644 (file)
@@ -122,6 +122,17 @@ static void check_ok_for_atomic (tree, Entity_Id, bool);
 static int compatible_signatures_p (tree ftype1, tree ftype2);
 static void rest_of_type_decl_compilation_no_defer (tree);
 
+/* Return true if GNAT_ADDRESS is a compile time known value.
+   In particular catch System'To_Address.  */
+
+static bool
+compile_time_known_address_p (Node_Id gnat_address)
+{
+  return ((Nkind (gnat_address) == N_Unchecked_Type_Conversion
+          && Compile_Time_Known_Value (Expression (gnat_address)))
+         || Compile_Time_Known_Value (gnat_address));
+}
+
 /* Given GNAT_ENTITY, an entity in the incoming GNAT tree, return a
    GCC type corresponding to that entity.  GNAT_ENTITY is assumed to
    refer to an Ada type.  */
@@ -1026,7 +1037,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
              = build_reference_type_for_mode (gnu_type, ptr_mode, true);
            gnu_address = convert (gnu_type, gnu_address);
            used_by_ref = true;
-           const_flag = !Is_Public (gnat_entity);
+           const_flag = !Is_Public (gnat_entity)
+             || compile_time_known_address_p (Expression (Address_Clause
+                                                          (gnat_entity)));
 
            /* If we don't have an initializing expression for the underlying
               variable, the initializing expression for the pointer is the
@@ -1058,9 +1071,24 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
              = build_reference_type_for_mode (gnu_type, ptr_mode, true);
            gnu_size = NULL_TREE;
 
-           gnu_expr = NULL_TREE;
            /* No point in taking the address of an initializing expression
               that isn't going to be used.  */
+           gnu_expr = NULL_TREE;
+
+           /* If it has an address clause whose value is known at compile
+              time, make the object a CONST_DECL.  This will avoid a
+              useless dereference.  */
+           if (Present (Address_Clause (gnat_entity)))
+             {
+               Node_Id gnat_address
+                 = Expression (Address_Clause (gnat_entity));
+
+               if (compile_time_known_address_p (gnat_address))
+                 {
+                   gnu_expr = gnat_to_gnu (gnat_address);
+                   const_flag = true;
+                 }
+             }
 
            used_by_ref = true;
          }
@@ -1258,7 +1286,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
           for these.  */
        if (TREE_CODE (gnu_decl) == CONST_DECL
            && (definition || Sloc (gnat_entity) > Standard_Location)
-           && (Is_Public (gnat_entity)
+           && ((Is_Public (gnat_entity)
+                && !Present (Address_Clause (gnat_entity)))
                || optimize == 0
                || Address_Taken (gnat_entity)
                || Is_Aliased (gnat_entity)
@@ -1271,6 +1300,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                                      gnat_entity);
 
            SET_DECL_CONST_CORRESPONDING_VAR (gnu_decl, gnu_corr_var);
+
+           /* As debugging information will be generated for the variable,
+              do not generate information for the constant.  */
+           DECL_IGNORED_P (gnu_decl) = true;
          }
 
        /* If this is declared in a block that contains a block with an