This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: reliably telling whether a data object is in a RO, RW or ?? section
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: 01 Oct 2003 18:44:54 -0300
- Subject: Re: reliably telling whether a data object is in a RO, RW or ?? section
- Organization: GCC Team, Red Hat
- References: <orisnbs0ei.fsf@free.redhat.lsd.ic.unicamp.br><20031001173842.GG10000@redhat.com>
On Oct 1, 2003, Richard Henderson <rth@redhat.com> wrote:
> On Mon, Sep 29, 2003 at 07:19:33PM -0300, Alexandre Oliva wrote:
>> * varasm.c (output_addressed_constants): Add boolean argument to
>> control whether to actually output the constant or just compute
>> reloc. Adjust all callers.
> I think I'd much prefer that the two functions be split apart.
How about this? Bootstrapped on i686-pc-linux-gnu
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* output.h (compute_reloc_for_constant): Declare.
* varasm.c (compute_reloc_for_constant): Extract from...
(output_addressed_constants): ... here. Adjust all callers.
* config/frv/frv.h (PREDICATE_CODES): Added
Index: gcc/output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.132
diff -u -p -r1.132 output.h
--- gcc/output.h 29 Sep 2003 22:07:39 -0000 1.132
+++ gcc/output.h 1 Oct 2003 21:41:55 -0000
@@ -437,6 +437,10 @@ extern rtx this_is_asm_operands;
extern bool decl_readonly_section (tree, int);
extern bool decl_readonly_section_1 (tree, int, int);
+/* This can be used to compute RELOC for the function above, when
+ given a constant expression. */
+extern int compute_reloc_for_constant (tree);
+
/* User label prefix in effect for this compilation. */
extern const char *user_label_prefix;
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.388
diff -u -p -r1.388 varasm.c
--- gcc/varasm.c 29 Sep 2003 21:29:11 -0000 1.388
+++ gcc/varasm.c 1 Oct 2003 21:41:58 -0000
@@ -154,7 +154,7 @@ static struct pool_constant *find_pool_c
static void mark_constant_pool (void);
static void mark_constants (rtx);
static int mark_constant (rtx *current_rtx, void *data);
-static int output_addressed_constants (tree);
+static void output_addressed_constants (tree);
static unsigned HOST_WIDE_INT array_size_for_constructor (tree);
static unsigned min_align (unsigned, unsigned);
static void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int);
@@ -1459,7 +1459,10 @@ assemble_variable (tree decl, int top_le
if (DECL_INITIAL (decl) == error_mark_node)
reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0;
else if (DECL_INITIAL (decl))
- reloc = output_addressed_constants (DECL_INITIAL (decl));
+ {
+ reloc = compute_reloc_for_constant (DECL_INITIAL (decl));
+ output_addressed_constants (DECL_INITIAL (decl));
+ }
resolve_unique_section (decl, reloc, flag_data_sections);
/* Handle uninitialized definitions. */
@@ -2501,7 +2504,7 @@ output_constant_def_contents (rtx symbol
/* Make sure any other constants whose addresses appear in EXP
are assigned label numbers. */
- int reloc = output_addressed_constants (exp);
+ int reloc = compute_reloc_for_constant (exp);
/* Align the location counter as required by EXP's data type. */
int align = TYPE_ALIGN (TREE_TYPE (exp));
@@ -2509,6 +2512,8 @@ output_constant_def_contents (rtx symbol
align = CONSTANT_ALIGNMENT (exp, align);
#endif
+ output_addressed_constants (exp);
+
/* We are no longer deferring this constant. */
TREE_ASM_WRITTEN (exp) = 1;
@@ -3329,12 +3334,10 @@ mark_constant (rtx *current_rtx, void *d
return 0;
}
-/* Find all the constants whose addresses are referenced inside of EXP,
- and make sure assembler code with a label has been output for each one.
- Indicate whether an ADDR_EXPR has been encountered. */
+/* Determine what kind of relocations EXP may need. */
-static int
-output_addressed_constants (tree exp)
+int
+compute_reloc_for_constant (tree exp)
{
int reloc = 0, reloc2;
tree tem;
@@ -3354,10 +3357,6 @@ output_addressed_constants (tree exp)
tem = TREE_OPERAND (tem, 0))
;
- if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c'
- || TREE_CODE (tem) == CONSTRUCTOR)
- output_constant_def (tem, 0);
-
if (TREE_PUBLIC (tem))
reloc |= 2;
else
@@ -3365,13 +3364,13 @@ output_addressed_constants (tree exp)
break;
case PLUS_EXPR:
- reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
- reloc |= output_addressed_constants (TREE_OPERAND (exp, 1));
+ reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
+ reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1));
break;
case MINUS_EXPR:
- reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
- reloc2 = output_addressed_constants (TREE_OPERAND (exp, 1));
+ reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
+ reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1));
/* The difference of two local labels is computable at link time. */
if (reloc == 1 && reloc2 == 1)
reloc = 0;
@@ -3382,13 +3381,13 @@ output_addressed_constants (tree exp)
case NOP_EXPR:
case CONVERT_EXPR:
case NON_LVALUE_EXPR:
- reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
+ reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
break;
case CONSTRUCTOR:
for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
if (TREE_VALUE (tem) != 0)
- reloc |= output_addressed_constants (TREE_VALUE (tem));
+ reloc |= compute_reloc_for_constant (TREE_VALUE (tem));
break;
@@ -3396,6 +3395,58 @@ output_addressed_constants (tree exp)
break;
}
return reloc;
+}
+
+/* Find all the constants whose addresses are referenced inside of EXP,
+ and make sure assembler code with a label has been output for each one.
+ Indicate whether an ADDR_EXPR has been encountered. */
+
+static void
+output_addressed_constants (tree exp)
+{
+ tree tem;
+
+ /* Give the front-end a chance to convert VALUE to something that
+ looks more like a constant to the back-end. */
+ exp = (*lang_hooks.expand_constant) (exp);
+
+ switch (TREE_CODE (exp))
+ {
+ case ADDR_EXPR:
+ case FDESC_EXPR:
+ /* Go inside any operations that get_inner_reference can handle and see
+ if what's inside is a constant: no need to do anything here for
+ addresses of variables or functions. */
+ for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem);
+ tem = TREE_OPERAND (tem, 0))
+ ;
+
+ if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c'
+ || TREE_CODE (tem) == CONSTRUCTOR)
+ output_constant_def (tem, 0);
+ break;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ output_addressed_constants (TREE_OPERAND (exp, 1));
+ /* Fall through. */
+
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
+ output_addressed_constants (TREE_OPERAND (exp, 0));
+ break;
+
+ case CONSTRUCTOR:
+ for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
+ if (TREE_VALUE (tem) != 0)
+ output_addressed_constants (TREE_VALUE (tem));
+
+ break;
+
+ default:
+ break;
+ }
}
/* Return nonzero if VALUE is a valid constant-valued expression
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer