public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* making aliases into the middle of a structure
@ 1999-04-22 11:13 Zack Weinberg
  1999-04-22 11:25 ` Alexandre Oliva
  1999-04-30 23:15 ` Zack Weinberg
  0 siblings, 2 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-22 11:13 UTC (permalink / raw)
  To: egcs

Consider this bit of code.

struct s
{
  int a, b;
};

struct s x = { 0, 0 };

extern __typeof(x.b) y __attribute__ ((alias("x.b")));

The goal is to have x.b and y refer to the same memory location.  I am
aware that this is somewhat perverse, but there are legitimate reasons
(binary compatibility) for it.

If gcc were to translate this into

.data
.globl x
        .align 4
        .type    x,@object
        .size    x,8
x:
        .zero   8
.globl y
        .set    y, x+4

then the assembler would generate a correct object module, and
references to `x.b' and `y' would indeed operate on the same memory
location.

Unfortunately this is not what gcc produces; instead I get

.data
.globl x
        .align 4
        .type    x,@object
        .size    x,8
x:
        .zero   8
.globl y
        .set    y,x.b


The assembler generates an undefined reference to the symbol `x.b' and
forgets about `y'.

I have experimented with workarounds involving offsetof();
unfortunately, the best this can do is

	.set y,x + ((size_t) &((s *)0)->b)

which is not an expression that the assembler can evaluate.  I do not
want to write a raw assembly module, because that will break if the
padding inside the structure, or the sizes of the component types,
change.

Any suggestions?

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:13 making aliases into the middle of a structure Zack Weinberg
@ 1999-04-22 11:25 ` Alexandre Oliva
  1999-04-22 11:30   ` Zack Weinberg
  1999-04-30 23:15   ` Alexandre Oliva
  1999-04-30 23:15 ` Zack Weinberg
  1 sibling, 2 replies; 36+ messages in thread
From: Alexandre Oliva @ 1999-04-22 11:25 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: egcs

On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:

> extern __typeof(x.b) y __attribute__ ((alias("x.b")));

This can't work.  The alias attribute defines an alias to a *symbol*,
not to an arbitrary expression.  Since you may have to get quite
platform-specific because of the potential need for leading
underscores, why don't you compute the offset, say, in the configure
script, then #define the appropriate alias string?

-- 
Alexandre Oliva http://www.dcc.unicamp.br/~oliva IC-Unicamp, Brasil
{oliva,Alexandre.Oliva}@dcc.unicamp.br  aoliva@{acm.org,computer.org}
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
*** E-mail about software projects will be forwarded to mailing lists

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:25 ` Alexandre Oliva
@ 1999-04-22 11:30   ` Zack Weinberg
  1999-04-22 11:38     ` Alexandre Oliva
  1999-04-30 23:15     ` Zack Weinberg
  1999-04-30 23:15   ` Alexandre Oliva
  1 sibling, 2 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-22 11:30 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: egcs

On 22 Apr 1999 15:24:46 -0300, Alexandre Oliva wrote:
>On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>
>> extern __typeof(x.b) y __attribute__ ((alias("x.b")));
>
>This can't work.  The alias attribute defines an alias to a *symbol*,
>not to an arbitrary expression. 

I don't see that it would be terribly hard to extend alias so it could
handle SYMBOL_REFs and COMPONENT_REFs as well as strings.

>Since you may have to get quite
>platform-specific because of the potential need for leading
>underscores, 

This is already handled in the real framework; the above was a
stripped down example.

>why don't you compute the offset, say, in the configure
>script, then #define the appropriate alias string?

Because the preprocessor can't compute offsetof() all the way down;
I'd have to compile and run a test program.  Which loses when
cross-compiling.

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:30   ` Zack Weinberg
@ 1999-04-22 11:38     ` Alexandre Oliva
  1999-04-22 14:31       ` Zack Weinberg
                         ` (2 more replies)
  1999-04-30 23:15     ` Zack Weinberg
  1 sibling, 3 replies; 36+ messages in thread
From: Alexandre Oliva @ 1999-04-22 11:38 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: egcs

On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:

> On 22 Apr 1999 15:24:46 -0300, Alexandre Oliva wrote:
>> On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>> 
>>> extern __typeof(x.b) y __attribute__ ((alias("x.b")));
>> 
>> This can't work.  The alias attribute defines an alias to a *symbol*,
>> not to an arbitrary expression. 

> I don't see that it would be terribly hard to extend alias so it could
> handle SYMBOL_REFs and COMPONENT_REFs as well as strings.

That would probably be a good idea.  alias could accept an arbitrary
expression.  If it's an lvalue within a global symbol, it will define
an actual alias, otherwise it could just emit an error or ``construct
a temporary and bind the reference to it'', to put it in C++ terms :-) 

>> why don't you compute the offset, say, in the configure
>> script, then #define the appropriate alias string?

> Because the preprocessor can't compute offsetof() all the way down;
> I'd have to compile and run a test program.  Which loses when
> cross-compiling.

Well, you could try to extract this information from the assembly
code, or from some RTL dump (since you're bound to gcc anyway), but I
wouldn't like to be the one to implement it :-)

-- 
Alexandre Oliva http://www.dcc.unicamp.br/~oliva IC-Unicamp, Brasil
{oliva,Alexandre.Oliva}@dcc.unicamp.br  aoliva@{acm.org,computer.org}
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
*** E-mail about software projects will be forwarded to mailing lists

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:38     ` Alexandre Oliva
@ 1999-04-22 14:31       ` Zack Weinberg
  1999-04-23 15:24         ` Richard Henderson
  1999-04-30 23:15         ` Zack Weinberg
  1999-04-23 10:34       ` Jeffrey A Law
  1999-04-30 23:15       ` Alexandre Oliva
  2 siblings, 2 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-22 14:31 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: egcs, egcs-patches

On 22 Apr 1999 15:38:16 -0300, Alexandre Oliva wrote:
>On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>
>> On 22 Apr 1999 15:24:46 -0300, Alexandre Oliva wrote:
>>> On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>>> 
>>>> extern __typeof(x.b) y __attribute__ ((alias("x.b")));
>>> 
>>> This can't work.  The alias attribute defines an alias to a *symbol*,
>>> not to an arbitrary expression. 
>
>> I don't see that it would be terribly hard to extend alias so it could
>> handle SYMBOL_REFs and COMPONENT_REFs as well as strings.
>
>That would probably be a good idea.  alias could accept an arbitrary
>expression.  If it's an lvalue within a global symbol, it will define
>an actual alias, otherwise it could just emit an error or ``construct
>a temporary and bind the reference to it'', to put it in C++ terms :-) 

It turns out to be relatively simple to implement, too (at least if
you don't try to construct temporaries).  The appended patch is
a proof-of-concept; I don't expect it'll make it into 1.2.  I had to
introduce a new MD macro, ASM_OUTPUT_OFFSET_DEF, and the patch does
not modify the relevant tm.h files, only defaults.h (so it works only
with assemblers that use .set).  Any front-end that calls
assemble_alias also needs to be adjusted; none of the ones in current
CVS do.

The subset of this patch that lets attribute alias accept bare
identifiers is trivial, and it'd be nice if that got into 1.2.

[As an aside, get_inner_reference has a rather nonintuitive name...]

zw

1999-04-22 17:22 -0400  Zack Weinberg  <zack@rabi.phys.columbia.edu>

	* c-common.c (decl_attributes: A_ALIAS): Accept an
	IDENTIFIER_NODE or COMPONENT_REF in args.  If we get a
	COMPONENT_REF, sanity-check it (no bitfields, no non-lvalues,
	no variable offsets) and pass the component offset on to
	assemble_alias.
	* varasm.c (assemble_alias): Add `offset' argument.  If it's
	nonzero, use ASM_OUTPUT_OFFSET_DEF to output the alias
	definition with its offset from the base symbol.
	* defaults.h (ASM_OUTPUT_OFFSET_DEF): New macro, for
	outputting alias defns of the form ".set b,a+4".
	* output.h: Update prototype of assemble_alias.

===================================================================
Index: c-common.c
--- c-common.c	1999/04/13 21:04:06	1.56
+++ c-common.c	1999/04/22 21:20:34
@@ -891,20 +891,62 @@
 	  else if (decl_function_context (decl) == 0)
 	    {
 	      tree id;
+	      int offset;
 
 	      id = TREE_VALUE (args);
-	      if (TREE_CODE (id) != STRING_CST)
+	      if (TREE_CODE (id) == STRING_CST)
 		{
-		  error ("alias arg not a string");
+		  id = get_identifier (TREE_STRING_POINTER (id));
+		  offset = 0;
+		}
+	      else if (TREE_CODE (id) == IDENTIFIER_NODE)
+		{
+		  offset = 0;
+		}
+	      else if (TREE_CODE (id) == COMPONENT_REF)
+		{
+		  if (! lvalue_p (TREE_OPERAND (id, 0)))
+		    {
+		      error ("alias arg not an lvalue expression");
+		      break;
+		    }
+		  else if (DECL_C_BIT_FIELD (TREE_OPERAND (id, 1)))
+		    {
+		      error ("cannot set alias to bitfield `%s'",
+			     IDENTIFIER_POINTER (DECL_NAME (
+						      TREE_OPERAND (id, 1))));
+		      break;
+		    }
+		  else
+		    {
+		      int boffset, bsiz, puns, pvol, palign;
+		      tree poff, newid;
+		      enum machine_mode mode;
+		      
+		      newid = get_inner_reference (id, &bsiz, &boffset, &poff,
+						&mode, &puns, &pvol, &palign);
+		      if (poff != NULL_TREE)
+			{
+			  error ("cannot set alias to variably offset field `%s'",
+				 IDENTIFIER_POINTER (DECL_NAME (
+						       TREE_OPERAND (id, 1))));
+			  break;
+			}
+		      id = DECL_NAME (newid);
+		      offset = boffset / BITS_PER_UNIT;
+		    }
+		}
+	      else
+		{
+		  error ("alias arg not a string or lvalue expression");
 		  break;
 		}
-	      id = get_identifier (TREE_STRING_POINTER (id));
 
 	      if (TREE_CODE (decl) == FUNCTION_DECL)
 		DECL_INITIAL (decl) = error_mark_node;
 	      else
 		DECL_EXTERNAL (decl) = 0;
-	      assemble_alias (decl, id);
+	      assemble_alias (decl, id, offset);
 	    }
 	  else
 	    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
===================================================================
Index: varasm.c
--- varasm.c	1999/03/28 15:35:04	1.57
+++ varasm.c	1999/04/22 21:20:36
@@ -4334,8 +4334,9 @@
 }
 
 void
-assemble_alias (decl, target)
+assemble_alias (decl, target, offset)
      tree decl, target ATTRIBUTE_UNUSED;
+     int offset ATTRIBUTE_UNUSED;
 {
   char *name;
 
@@ -4355,14 +4356,26 @@
 	ASM_GLOBALIZE_LABEL (asm_out_file, name);
     }
 
-  ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
+  if (offset == 0)
+    ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
+  else
+#ifdef ASM_OUTPUT_OFFSET_DEF
+    ASM_OUTPUT_OFFSET_DEF (asm_out_file, name,
+			   IDENTIFIER_POINTER (target), offset);
+#else
+  warning ("offset alias definitions not supported in this configuration; ignored");
+#endif
+
   TREE_ASM_WRITTEN (decl) = 1;
 #else
 #ifdef ASM_OUTPUT_WEAK_ALIAS
   if (! DECL_WEAK (decl))
     warning ("only weak aliases are supported in this configuration");
 
-  ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+  if (offset == 0)
+    ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+  else
+    warning ("offset alias definitions not supported in this configuration; ignored");
   TREE_ASM_WRITTEN (decl) = 1;
 #else
   warning ("alias definitions not supported in this configuration; ignored");
===================================================================
Index: defaults.h
--- defaults.h	1999/02/27 22:21:57	1.7
+++ defaults.h	1999/04/22 21:20:36
@@ -116,6 +116,15 @@
 	fprintf (FILE, "\n");						\
   } while (0)
 #endif
+#ifndef ASM_OUTPUT_OFFSET_DEF
+#define ASM_OUTPUT_OFFSET_DEF(FILE,LABEL1,LABEL2,OFFSET)		\
+ do {	fprintf ((FILE), "\t%s\t", SET_ASM_OP);				\
+	assemble_name (FILE, LABEL1);					\
+	fprintf (FILE, ",");						\
+	assemble_name (FILE, LABEL2);					\
+	fprintf (FILE, "+%d\n", OFFSET);				\
+  } while (0)
+#endif
 #endif
 
 /* This is how to output a reference to a user-level label named NAME.  */
===================================================================
Index: output.h
--- output.h	1999/04/18 13:09:18	1.23
+++ output.h	1999/04/22 21:20:36
@@ -207,7 +207,7 @@
 /* Output alignment directive to align for constant expression EXP.  */
 extern void assemble_constant_align	PROTO((tree));
 
-extern void assemble_alias		PROTO((tree, tree));
+extern void assemble_alias		PROTO((tree, tree, int));
 
 /* Output a string of literal assembler code
    for an `asm' keyword used between functions.  */

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:38     ` Alexandre Oliva
  1999-04-22 14:31       ` Zack Weinberg
@ 1999-04-23 10:34       ` Jeffrey A Law
  1999-04-23 10:40         ` Zack Weinberg
                           ` (2 more replies)
  1999-04-30 23:15       ` Alexandre Oliva
  2 siblings, 3 replies; 36+ messages in thread
From: Jeffrey A Law @ 1999-04-23 10:34 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: Zack Weinberg, egcs

  In message < org15s33hj.fsf@lua.lbi.dcc.unicamp.br >you write:
  > > Because the preprocessor can't compute offsetof() all the way down;
  > > I'd have to compile and run a test program.  Which loses when
  > > cross-compiling.
  > 
  > Well, you could try to extract this information from the assembly
  > code, or from some RTL dump (since you're bound to gcc anyway), but I
  > wouldn't like to be the one to implement it :-)
Cygnus implemented a switch to have the compiler dump offsets for fields
within structures in a format intended to be used by assembly code.

It's not something we've used a lot and haven't ever thought it worth
the effort to clean it up and submit it to egcs.

I've been kicking around the idea of using that code to build a testsuite
to look for unexpected changes in structure layouts between releases as
one component of a wider1 ABI compatibility testing plan.

Ie, we build a repository of tests which define a bunch of structs, unions,
classes.  We compile those tests with the magic option which records the
offset for each field within the structure.  We do this for each target we
care about.

Then we can compile a later release and compare the offsets for that target
to ensure they have not changed.

It's not a perfect solution for ABI testing, but it's a small step we can
use as a building block.  Will it actually happen -- I don't know.  It's
still a blue sky project.

Jeff

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 10:34       ` Jeffrey A Law
@ 1999-04-23 10:40         ` Zack Weinberg
  1999-04-23 15:54           ` Richard Henderson
  1999-04-30 23:15           ` Zack Weinberg
  1999-04-23 13:36         ` Jamie Lokier
  1999-04-30 23:15         ` Jeffrey A Law
  2 siblings, 2 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-23 10:40 UTC (permalink / raw)
  To: law; +Cc: egcs

On Fri, 23 Apr 1999 00:14:34 -0600, Jeffrey A Law wrote:
>
>  In message < org15s33hj.fsf@lua.lbi.dcc.unicamp.br >you write:
>  > > Because the preprocessor can't compute offsetof() all the way down;
>  > > I'd have to compile and run a test program.  Which loses when
>  > > cross-compiling.
>  > 
>  > Well, you could try to extract this information from the assembly
>  > code, or from some RTL dump (since you're bound to gcc anyway), but I
>  > wouldn't like to be the one to implement it :-)
>Cygnus implemented a switch to have the compiler dump offsets for fields
>within structures in a format intended to be used by assembly code.
>
>It's not something we've used a lot and haven't ever thought it worth
>the effort to clean it up and submit it to egcs.

This is a cute idea, and I could think of uses in libc, but it doesn't
really solve my current problem (without excessive magic).  I'd much
rather be able to write

extern int var __attribute__ ((alias (structure.field)));

which is what the patch I sent yesterday implements.

Incidentally, I found what I think is a GAS bug: it forgets
aliases to symbols allocated with .comm.  For example:

int common;
extern int alias __attribute__ ((alias("common")));

`alias' will not be defined in the object file.  The assembly dump
looks correct to me.

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 10:34       ` Jeffrey A Law
  1999-04-23 10:40         ` Zack Weinberg
@ 1999-04-23 13:36         ` Jamie Lokier
  1999-04-23 13:49           ` Zack Weinberg
                             ` (2 more replies)
  1999-04-30 23:15         ` Jeffrey A Law
  2 siblings, 3 replies; 36+ messages in thread
From: Jamie Lokier @ 1999-04-23 13:36 UTC (permalink / raw)
  To: law; +Cc: Alexandre Oliva, Zack Weinberg, egcs

Jeffrey A Law wrote:
> Cygnus implemented a switch to have the compiler dump offsets for fields
> within structures in a format intended to be used by assembly code.

Hey, my neuron flickered!

Does the dump include enough type information to generate a decent
non-conservative garbage collector?

-- Jamie

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 13:36         ` Jamie Lokier
@ 1999-04-23 13:49           ` Zack Weinberg
  1999-04-23 15:20             ` Jamie Lokier
                               ` (2 more replies)
  1999-04-24 21:53           ` Jeffrey A Law
  1999-04-30 23:15           ` Jamie Lokier
  2 siblings, 3 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-23 13:49 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Alexandre Oliva, egcs

On Fri, 23 Apr 1999 22:32:36 +0200, Jamie Lokier wrote:
>Jeffrey A Law wrote:
>> Cygnus implemented a switch to have the compiler dump offsets for fields
>> within structures in a format intended to be used by assembly code.
>
>Hey, my neuron flickered!
>
>Does the dump include enough type information to generate a decent
>non-conservative garbage collector?

You'd need stack frame information too, wouldn't you?

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 13:49           ` Zack Weinberg
@ 1999-04-23 15:20             ` Jamie Lokier
  1999-04-30 23:15               ` Jamie Lokier
  1999-04-23 22:58             ` Andi Kleen
  1999-04-30 23:15             ` Zack Weinberg
  2 siblings, 1 reply; 36+ messages in thread
From: Jamie Lokier @ 1999-04-23 15:20 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Alexandre Oliva, egcs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 525 bytes --]

Zack Weinberg wrote:
> >Does the dump include enough type information to generate a decent
> >non-conservative garbage collector?
> 
> You'd need stack frame information too, wouldn't you?

In general yes, but a typed garbage collector that doesn't know about
stack frames would still be very useful.

Of course in my real fantasy it does do stack frames (based on PC à la
exceptions), it moves objects when that is more efficient, and it
efficiently handles polymorphic structures.  But that's fantasy land :-)

-- Jamie

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 14:31       ` Zack Weinberg
@ 1999-04-23 15:24         ` Richard Henderson
  1999-04-23 16:27           ` Zack Weinberg
  1999-04-30 23:15           ` Richard Henderson
  1999-04-30 23:15         ` Zack Weinberg
  1 sibling, 2 replies; 36+ messages in thread
From: Richard Henderson @ 1999-04-23 15:24 UTC (permalink / raw)
  To: Zack Weinberg, Alexandre Oliva; +Cc: egcs, egcs-patches

On Thu, Apr 22, 1999 at 05:31:38PM -0400, Zack Weinberg wrote:
> >That would probably be a good idea.  alias could accept an arbitrary
> >expression.  If it's an lvalue within a global symbol, it will define
> >an actual alias, otherwise it could just emit an error or ``construct
> >a temporary and bind the reference to it'', to put it in C++ terms :-) 
>
> It turns out to be relatively simple to implement, too (at least if
> you don't try to construct temporaries).  The appended patch is
> a proof-of-concept; I don't expect it'll make it into 1.2.  I had to
> introduce a new MD macro, ASM_OUTPUT_OFFSET_DEF...

This is a very bad way to implement this.  You're hiding from the
optimizers the fact that you've got two global symbols that alias.

The only way this will ever work is for you to adjust the DECL_RTL
of `y' such that the aliasing is visible.  You'd have something like

	(const (plus (symbol_ref "x") (const_int 42)))

for a global; something obvious for stack-local objects.  And of 
course this is only going to work without -fno-strict-aliasing if
the programmer makes sure that the types correspond.  But that, I 
think, is not your problem.

If you like to emit `y' as a global symbol too, that's fine. 

BTW, you don't need the ifdef in varasm.c if you have a version
in defaults.h.


r~

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 10:40         ` Zack Weinberg
@ 1999-04-23 15:54           ` Richard Henderson
  1999-04-23 16:19             ` Zack Weinberg
  1999-04-30 23:15             ` Richard Henderson
  1999-04-30 23:15           ` Zack Weinberg
  1 sibling, 2 replies; 36+ messages in thread
From: Richard Henderson @ 1999-04-23 15:54 UTC (permalink / raw)
  To: Zack Weinberg, law; +Cc: egcs

On Fri, Apr 23, 1999 at 01:40:34PM -0400, Zack Weinberg wrote:
> int common;
> extern int alias __attribute__ ((alias("common")));
> 
> `alias' will not be defined in the object file.  The assembly dump
> looks correct to me.

This is not a bug.  This is impossible to represent 
in the object file.  I believe SOM can do it if you
feel like hurting yourself...  ;-)


r~

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 15:54           ` Richard Henderson
@ 1999-04-23 16:19             ` Zack Weinberg
  1999-04-26  1:46               ` Andreas Schwab
  1999-04-30 23:15               ` Zack Weinberg
  1999-04-30 23:15             ` Richard Henderson
  1 sibling, 2 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-23 16:19 UTC (permalink / raw)
  To: Richard Henderson; +Cc: egcs

On Fri, 23 Apr 1999 15:54:17 -0700, Richard Henderson wrote:
>On Fri, Apr 23, 1999 at 01:40:34PM -0400, Zack Weinberg wrote:
>> int common;
>> extern int alias __attribute__ ((alias("common")));
>> 
>> `alias' will not be defined in the object file.  The assembly dump
>> looks correct to me.
>
>This is not a bug.  This is impossible to represent 
>in the object file.  I believe SOM can do it if you
>feel like hurting yourself...  ;-)

I didn't know that.  It'd be nice if the assembler would complain
instead of silently discarding the symbol.

zw


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 15:24         ` Richard Henderson
@ 1999-04-23 16:27           ` Zack Weinberg
  1999-04-23 16:52             ` Richard Henderson
  1999-04-30 23:15             ` Zack Weinberg
  1999-04-30 23:15           ` Richard Henderson
  1 sibling, 2 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-23 16:27 UTC (permalink / raw)
  To: Richard Henderson, Alexandre Oliva; +Cc: egcs, egcs-patches

On Fri, 23 Apr 1999 15:23:59 -0700, Richard Henderson wrote:
>On Thu, Apr 22, 1999 at 05:31:38PM -0400, Zack Weinberg wrote:
>> >That would probably be a good idea.  alias could accept an arbitrary
>> >expression.  If it's an lvalue within a global symbol, it will define
>> >an actual alias, otherwise it could just emit an error or ``construct
>> >a temporary and bind the reference to it'', to put it in C++ terms :-) 
>>
>> It turns out to be relatively simple to implement, too (at least if
>> you don't try to construct temporaries).  The appended patch is
>> a proof-of-concept; I don't expect it'll make it into 1.2.  I had to
>> introduce a new MD macro, ASM_OUTPUT_OFFSET_DEF...
>
>This is a very bad way to implement this.  You're hiding from the
>optimizers the fact that you've got two global symbols that alias.

Huh.  Why isn't this a problem for the existing symbol-alias
mechanism?  And what am I to do about references from another source
file?  The intended use of this feature is isolated in a file that
does nothing but export `x' and `y'.

>The only way this will ever work is for you to adjust the DECL_RTL
>of `y' such that the aliasing is visible.  You'd have something like
>
>	(const (plus (symbol_ref "x") (const_int 42)))
>
>for a global; something obvious for stack-local objects.  

Ok, if you don't mind my asking the dumb question, how do I do that?
The tree->rtl conversion isn't exactly documented.

>And of course this is only going to work without -fno-strict-aliasing
>if the programmer makes sure that the types correspond.  But that, I
>think, is not your problem.

Maybe I should verify that the types correspond inside decl_attributes.

>If you like to emit `y' as a global symbol too, that's fine. 

In this context, it's kinda necessary.

>BTW, you don't need the ifdef in varasm.c if you have a version
>in defaults.h.

The defaults.h version is only defined if SET_ASM_OP is available.

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 16:27           ` Zack Weinberg
@ 1999-04-23 16:52             ` Richard Henderson
  1999-04-30 23:15               ` Richard Henderson
  1999-04-30 23:15             ` Zack Weinberg
  1 sibling, 1 reply; 36+ messages in thread
From: Richard Henderson @ 1999-04-23 16:52 UTC (permalink / raw)
  To: Zack Weinberg, Alexandre Oliva; +Cc: egcs, egcs-patches

On Fri, Apr 23, 1999 at 07:27:32PM -0400, Zack Weinberg wrote:
> Huh.  Why isn't this a problem for the existing symbol-alias
> mechanism? 

Um.. maybe it is?  I havn't looked.

> And what am I to do about references from another source
> file?  The intended use of this feature is isolated in a file that
> does nothing but export `x' and `y'.

Well, as long as you don't reference both `x' and `y' in the
same function, you don't care really.

> Ok, if you don't mind my asking the dumb question, how do I do that?
> The tree->rtl conversion isn't exactly documented.

Lets see..  you'd get the offset with get_inner_reference or
something.  You'd take that and the base symbol and do something like

  // For a global, DECL_RTL is of the form (mem (symbol_ref))

  DECL_RTL (alias) = gen_rtx_MEM (TREE_MODE (alias),
				  plus_constant (XEXP (DECL_RTL (base), 0),
						 offset));
  MEM_ALIAS_SET (DECL_RTL (alias)) = get_alias_set (TREE_TYPE (alias));

I think.  This is off the top of my head.


r~

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 13:49           ` Zack Weinberg
  1999-04-23 15:20             ` Jamie Lokier
@ 1999-04-23 22:58             ` Andi Kleen
  1999-04-30 23:15               ` Andi Kleen
  1999-04-30 23:15             ` Zack Weinberg
  2 siblings, 1 reply; 36+ messages in thread
From: Andi Kleen @ 1999-04-23 22:58 UTC (permalink / raw)
  To: egcs; +Cc: zack

zack@rabi.columbia.edu (Zack Weinberg) writes:

> On Fri, 23 Apr 1999 22:32:36 +0200, Jamie Lokier wrote:
> >Jeffrey A Law wrote:
> >> Cygnus implemented a switch to have the compiler dump offsets for fields
> >> within structures in a format intended to be used by assembly code.
> >
> >Hey, my neuron flickered!
> >
> >Does the dump include enough type information to generate a decent
> >non-conservative garbage collector?
> 
> You'd need stack frame information too, wouldn't you?

Can't you extract that information from the dwarf2 exception unwinding tables?


-Andi


PS: I was a bit disappointed that -g -gdwarf2 -fomit-frame-pointer debugging 
still does not work with gdb 4.18 (although objdump shows that the executable
contains lots of frame description)

-- 
This is like TV. I don't like TV.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 13:36         ` Jamie Lokier
  1999-04-23 13:49           ` Zack Weinberg
@ 1999-04-24 21:53           ` Jeffrey A Law
  1999-04-30 23:15             ` Jeffrey A Law
  1999-04-30 23:15           ` Jamie Lokier
  2 siblings, 1 reply; 36+ messages in thread
From: Jeffrey A Law @ 1999-04-24 21:53 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Alexandre Oliva, Zack Weinberg, egcs

  In message < 19990423223236.A5686@pcep-jamie.cern.ch >you write:
  > Jeffrey A Law wrote:
  > > Cygnus implemented a switch to have the compiler dump offsets for fields
  > > within structures in a format intended to be used by assembly code.
  > 
  > Hey, my neuron flickered!
  > 
  > Does the dump include enough type information to generate a decent
  > non-conservative garbage collector?
I don't believe so (it's been a couple years since we did that work).

If I remember correctly it just spit out name/offset information, not true
type information.

You could get true type information out of debug symbols though.  We did this
when I was at the UofU to implement link time parameter type checking across
modules.    It wasn't fun though :-)

jeff

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 16:19             ` Zack Weinberg
@ 1999-04-26  1:46               ` Andreas Schwab
  1999-04-30 23:15                 ` Andreas Schwab
  1999-04-30 23:15               ` Zack Weinberg
  1 sibling, 1 reply; 36+ messages in thread
From: Andreas Schwab @ 1999-04-26  1:46 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Richard Henderson, egcs

Zack Weinberg <zack@rabi.columbia.edu> writes:

|> On Fri, 23 Apr 1999 15:54:17 -0700, Richard Henderson wrote:
|> >On Fri, Apr 23, 1999 at 01:40:34PM -0400, Zack Weinberg wrote:
|> >> int common;
|> >> extern int alias __attribute__ ((alias("common")));
|> >> 
|> >> `alias' will not be defined in the object file.  The assembly dump
|> >> looks correct to me.
|> >
|> >This is not a bug.  This is impossible to represent 
|> >in the object file.  I believe SOM can do it if you
|> >feel like hurting yourself...  ;-)
|> 
|> I didn't know that.  It'd be nice if the assembler would complain
|> instead of silently discarding the symbol.

Compile with -fno-common.  Common symbols are evil anyway.

Andreas.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 13:36         ` Jamie Lokier
  1999-04-23 13:49           ` Zack Weinberg
  1999-04-24 21:53           ` Jeffrey A Law
@ 1999-04-30 23:15           ` Jamie Lokier
  2 siblings, 0 replies; 36+ messages in thread
From: Jamie Lokier @ 1999-04-30 23:15 UTC (permalink / raw)
  To: law; +Cc: Alexandre Oliva, Zack Weinberg, egcs

Jeffrey A Law wrote:
> Cygnus implemented a switch to have the compiler dump offsets for fields
> within structures in a format intended to be used by assembly code.

Hey, my neuron flickered!

Does the dump include enough type information to generate a decent
non-conservative garbage collector?

-- Jamie

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 16:27           ` Zack Weinberg
  1999-04-23 16:52             ` Richard Henderson
@ 1999-04-30 23:15             ` Zack Weinberg
  1 sibling, 0 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Richard Henderson, Alexandre Oliva; +Cc: egcs, egcs-patches

On Fri, 23 Apr 1999 15:23:59 -0700, Richard Henderson wrote:
>On Thu, Apr 22, 1999 at 05:31:38PM -0400, Zack Weinberg wrote:
>> >That would probably be a good idea.  alias could accept an arbitrary
>> >expression.  If it's an lvalue within a global symbol, it will define
>> >an actual alias, otherwise it could just emit an error or ``construct
>> >a temporary and bind the reference to it'', to put it in C++ terms :-) 
>>
>> It turns out to be relatively simple to implement, too (at least if
>> you don't try to construct temporaries).  The appended patch is
>> a proof-of-concept; I don't expect it'll make it into 1.2.  I had to
>> introduce a new MD macro, ASM_OUTPUT_OFFSET_DEF...
>
>This is a very bad way to implement this.  You're hiding from the
>optimizers the fact that you've got two global symbols that alias.

Huh.  Why isn't this a problem for the existing symbol-alias
mechanism?  And what am I to do about references from another source
file?  The intended use of this feature is isolated in a file that
does nothing but export `x' and `y'.

>The only way this will ever work is for you to adjust the DECL_RTL
>of `y' such that the aliasing is visible.  You'd have something like
>
>	(const (plus (symbol_ref "x") (const_int 42)))
>
>for a global; something obvious for stack-local objects.  

Ok, if you don't mind my asking the dumb question, how do I do that?
The tree->rtl conversion isn't exactly documented.

>And of course this is only going to work without -fno-strict-aliasing
>if the programmer makes sure that the types correspond.  But that, I
>think, is not your problem.

Maybe I should verify that the types correspond inside decl_attributes.

>If you like to emit `y' as a global symbol too, that's fine. 

In this context, it's kinda necessary.

>BTW, you don't need the ifdef in varasm.c if you have a version
>in defaults.h.

The defaults.h version is only defined if SET_ASM_OP is available.

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 14:31       ` Zack Weinberg
  1999-04-23 15:24         ` Richard Henderson
@ 1999-04-30 23:15         ` Zack Weinberg
  1 sibling, 0 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: egcs, egcs-patches

On 22 Apr 1999 15:38:16 -0300, Alexandre Oliva wrote:
>On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>
>> On 22 Apr 1999 15:24:46 -0300, Alexandre Oliva wrote:
>>> On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>>> 
>>>> extern __typeof(x.b) y __attribute__ ((alias("x.b")));
>>> 
>>> This can't work.  The alias attribute defines an alias to a *symbol*,
>>> not to an arbitrary expression. 
>
>> I don't see that it would be terribly hard to extend alias so it could
>> handle SYMBOL_REFs and COMPONENT_REFs as well as strings.
>
>That would probably be a good idea.  alias could accept an arbitrary
>expression.  If it's an lvalue within a global symbol, it will define
>an actual alias, otherwise it could just emit an error or ``construct
>a temporary and bind the reference to it'', to put it in C++ terms :-) 

It turns out to be relatively simple to implement, too (at least if
you don't try to construct temporaries).  The appended patch is
a proof-of-concept; I don't expect it'll make it into 1.2.  I had to
introduce a new MD macro, ASM_OUTPUT_OFFSET_DEF, and the patch does
not modify the relevant tm.h files, only defaults.h (so it works only
with assemblers that use .set).  Any front-end that calls
assemble_alias also needs to be adjusted; none of the ones in current
CVS do.

The subset of this patch that lets attribute alias accept bare
identifiers is trivial, and it'd be nice if that got into 1.2.

[As an aside, get_inner_reference has a rather nonintuitive name...]

zw

1999-04-22 17:22 -0400  Zack Weinberg  <zack@rabi.phys.columbia.edu>

	* c-common.c (decl_attributes: A_ALIAS): Accept an
	IDENTIFIER_NODE or COMPONENT_REF in args.  If we get a
	COMPONENT_REF, sanity-check it (no bitfields, no non-lvalues,
	no variable offsets) and pass the component offset on to
	assemble_alias.
	* varasm.c (assemble_alias): Add `offset' argument.  If it's
	nonzero, use ASM_OUTPUT_OFFSET_DEF to output the alias
	definition with its offset from the base symbol.
	* defaults.h (ASM_OUTPUT_OFFSET_DEF): New macro, for
	outputting alias defns of the form ".set b,a+4".
	* output.h: Update prototype of assemble_alias.

===================================================================
Index: c-common.c
--- c-common.c	1999/04/13 21:04:06	1.56
+++ c-common.c	1999/04/22 21:20:34
@@ -891,20 +891,62 @@
 	  else if (decl_function_context (decl) == 0)
 	    {
 	      tree id;
+	      int offset;
 
 	      id = TREE_VALUE (args);
-	      if (TREE_CODE (id) != STRING_CST)
+	      if (TREE_CODE (id) == STRING_CST)
 		{
-		  error ("alias arg not a string");
+		  id = get_identifier (TREE_STRING_POINTER (id));
+		  offset = 0;
+		}
+	      else if (TREE_CODE (id) == IDENTIFIER_NODE)
+		{
+		  offset = 0;
+		}
+	      else if (TREE_CODE (id) == COMPONENT_REF)
+		{
+		  if (! lvalue_p (TREE_OPERAND (id, 0)))
+		    {
+		      error ("alias arg not an lvalue expression");
+		      break;
+		    }
+		  else if (DECL_C_BIT_FIELD (TREE_OPERAND (id, 1)))
+		    {
+		      error ("cannot set alias to bitfield `%s'",
+			     IDENTIFIER_POINTER (DECL_NAME (
+						      TREE_OPERAND (id, 1))));
+		      break;
+		    }
+		  else
+		    {
+		      int boffset, bsiz, puns, pvol, palign;
+		      tree poff, newid;
+		      enum machine_mode mode;
+		      
+		      newid = get_inner_reference (id, &bsiz, &boffset, &poff,
+						&mode, &puns, &pvol, &palign);
+		      if (poff != NULL_TREE)
+			{
+			  error ("cannot set alias to variably offset field `%s'",
+				 IDENTIFIER_POINTER (DECL_NAME (
+						       TREE_OPERAND (id, 1))));
+			  break;
+			}
+		      id = DECL_NAME (newid);
+		      offset = boffset / BITS_PER_UNIT;
+		    }
+		}
+	      else
+		{
+		  error ("alias arg not a string or lvalue expression");
 		  break;
 		}
-	      id = get_identifier (TREE_STRING_POINTER (id));
 
 	      if (TREE_CODE (decl) == FUNCTION_DECL)
 		DECL_INITIAL (decl) = error_mark_node;
 	      else
 		DECL_EXTERNAL (decl) = 0;
-	      assemble_alias (decl, id);
+	      assemble_alias (decl, id, offset);
 	    }
 	  else
 	    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
===================================================================
Index: varasm.c
--- varasm.c	1999/03/28 15:35:04	1.57
+++ varasm.c	1999/04/22 21:20:36
@@ -4334,8 +4334,9 @@
 }
 
 void
-assemble_alias (decl, target)
+assemble_alias (decl, target, offset)
      tree decl, target ATTRIBUTE_UNUSED;
+     int offset ATTRIBUTE_UNUSED;
 {
   char *name;
 
@@ -4355,14 +4356,26 @@
 	ASM_GLOBALIZE_LABEL (asm_out_file, name);
     }
 
-  ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
+  if (offset == 0)
+    ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
+  else
+#ifdef ASM_OUTPUT_OFFSET_DEF
+    ASM_OUTPUT_OFFSET_DEF (asm_out_file, name,
+			   IDENTIFIER_POINTER (target), offset);
+#else
+  warning ("offset alias definitions not supported in this configuration; ignored");
+#endif
+
   TREE_ASM_WRITTEN (decl) = 1;
 #else
 #ifdef ASM_OUTPUT_WEAK_ALIAS
   if (! DECL_WEAK (decl))
     warning ("only weak aliases are supported in this configuration");
 
-  ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+  if (offset == 0)
+    ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+  else
+    warning ("offset alias definitions not supported in this configuration; ignored");
   TREE_ASM_WRITTEN (decl) = 1;
 #else
   warning ("alias definitions not supported in this configuration; ignored");
===================================================================
Index: defaults.h
--- defaults.h	1999/02/27 22:21:57	1.7
+++ defaults.h	1999/04/22 21:20:36
@@ -116,6 +116,15 @@
 	fprintf (FILE, "\n");						\
   } while (0)
 #endif
+#ifndef ASM_OUTPUT_OFFSET_DEF
+#define ASM_OUTPUT_OFFSET_DEF(FILE,LABEL1,LABEL2,OFFSET)		\
+ do {	fprintf ((FILE), "\t%s\t", SET_ASM_OP);				\
+	assemble_name (FILE, LABEL1);					\
+	fprintf (FILE, ",");						\
+	assemble_name (FILE, LABEL2);					\
+	fprintf (FILE, "+%d\n", OFFSET);				\
+  } while (0)
+#endif
 #endif
 
 /* This is how to output a reference to a user-level label named NAME.  */
===================================================================
Index: output.h
--- output.h	1999/04/18 13:09:18	1.23
+++ output.h	1999/04/22 21:20:36
@@ -207,7 +207,7 @@
 /* Output alignment directive to align for constant expression EXP.  */
 extern void assemble_constant_align	PROTO((tree));
 
-extern void assemble_alias		PROTO((tree, tree));
+extern void assemble_alias		PROTO((tree, tree, int));
 
 /* Output a string of literal assembler code
    for an `asm' keyword used between functions.  */

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:25 ` Alexandre Oliva
  1999-04-22 11:30   ` Zack Weinberg
@ 1999-04-30 23:15   ` Alexandre Oliva
  1 sibling, 0 replies; 36+ messages in thread
From: Alexandre Oliva @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: egcs

On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:

> extern __typeof(x.b) y __attribute__ ((alias("x.b")));

This can't work.  The alias attribute defines an alias to a *symbol*,
not to an arbitrary expression.  Since you may have to get quite
platform-specific because of the potential need for leading
underscores, why don't you compute the offset, say, in the configure
script, then #define the appropriate alias string?

-- 
Alexandre Oliva http://www.dcc.unicamp.br/~oliva IC-Unicamp, Brasil
{oliva,Alexandre.Oliva}@dcc.unicamp.br  aoliva@{acm.org,computer.org}
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
*** E-mail about software projects will be forwarded to mailing lists


^ permalink raw reply	[flat|nested] 36+ messages in thread

* making aliases into the middle of a structure
  1999-04-22 11:13 making aliases into the middle of a structure Zack Weinberg
  1999-04-22 11:25 ` Alexandre Oliva
@ 1999-04-30 23:15 ` Zack Weinberg
  1 sibling, 0 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-30 23:15 UTC (permalink / raw)
  To: egcs

Consider this bit of code.

struct s
{
  int a, b;
};

struct s x = { 0, 0 };

extern __typeof(x.b) y __attribute__ ((alias("x.b")));

The goal is to have x.b and y refer to the same memory location.  I am
aware that this is somewhat perverse, but there are legitimate reasons
(binary compatibility) for it.

If gcc were to translate this into

.data
.globl x
        .align 4
        .type    x,@object
        .size    x,8
x:
        .zero   8
.globl y
        .set    y, x+4

then the assembler would generate a correct object module, and
references to `x.b' and `y' would indeed operate on the same memory
location.

Unfortunately this is not what gcc produces; instead I get

.data
.globl x
        .align 4
        .type    x,@object
        .size    x,8
x:
        .zero   8
.globl y
        .set    y,x.b


The assembler generates an undefined reference to the symbol `x.b' and
forgets about `y'.

I have experimented with workarounds involving offsetof();
unfortunately, the best this can do is

	.set y,x + ((size_t) &((s *)0)->b)

which is not an expression that the assembler can evaluate.  I do not
want to write a raw assembly module, because that will break if the
padding inside the structure, or the sizes of the component types,
change.

Any suggestions?

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 15:54           ` Richard Henderson
  1999-04-23 16:19             ` Zack Weinberg
@ 1999-04-30 23:15             ` Richard Henderson
  1 sibling, 0 replies; 36+ messages in thread
From: Richard Henderson @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Zack Weinberg, law; +Cc: egcs

On Fri, Apr 23, 1999 at 01:40:34PM -0400, Zack Weinberg wrote:
> int common;
> extern int alias __attribute__ ((alias("common")));
> 
> `alias' will not be defined in the object file.  The assembly dump
> looks correct to me.

This is not a bug.  This is impossible to represent 
in the object file.  I believe SOM can do it if you
feel like hurting yourself...  ;-)


r~

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:38     ` Alexandre Oliva
  1999-04-22 14:31       ` Zack Weinberg
  1999-04-23 10:34       ` Jeffrey A Law
@ 1999-04-30 23:15       ` Alexandre Oliva
  2 siblings, 0 replies; 36+ messages in thread
From: Alexandre Oliva @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: egcs

On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:

> On 22 Apr 1999 15:24:46 -0300, Alexandre Oliva wrote:
>> On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>> 
>>> extern __typeof(x.b) y __attribute__ ((alias("x.b")));
>> 
>> This can't work.  The alias attribute defines an alias to a *symbol*,
>> not to an arbitrary expression. 

> I don't see that it would be terribly hard to extend alias so it could
> handle SYMBOL_REFs and COMPONENT_REFs as well as strings.

That would probably be a good idea.  alias could accept an arbitrary
expression.  If it's an lvalue within a global symbol, it will define
an actual alias, otherwise it could just emit an error or ``construct
a temporary and bind the reference to it'', to put it in C++ terms :-) 

>> why don't you compute the offset, say, in the configure
>> script, then #define the appropriate alias string?

> Because the preprocessor can't compute offsetof() all the way down;
> I'd have to compile and run a test program.  Which loses when
> cross-compiling.

Well, you could try to extract this information from the assembly
code, or from some RTL dump (since you're bound to gcc anyway), but I
wouldn't like to be the one to implement it :-)

-- 
Alexandre Oliva http://www.dcc.unicamp.br/~oliva IC-Unicamp, Brasil
{oliva,Alexandre.Oliva}@dcc.unicamp.br  aoliva@{acm.org,computer.org}
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
*** E-mail about software projects will be forwarded to mailing lists


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 16:52             ` Richard Henderson
@ 1999-04-30 23:15               ` Richard Henderson
  0 siblings, 0 replies; 36+ messages in thread
From: Richard Henderson @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Zack Weinberg, Alexandre Oliva; +Cc: egcs, egcs-patches

On Fri, Apr 23, 1999 at 07:27:32PM -0400, Zack Weinberg wrote:
> Huh.  Why isn't this a problem for the existing symbol-alias
> mechanism? 

Um.. maybe it is?  I havn't looked.

> And what am I to do about references from another source
> file?  The intended use of this feature is isolated in a file that
> does nothing but export `x' and `y'.

Well, as long as you don't reference both `x' and `y' in the
same function, you don't care really.

> Ok, if you don't mind my asking the dumb question, how do I do that?
> The tree->rtl conversion isn't exactly documented.

Lets see..  you'd get the offset with get_inner_reference or
something.  You'd take that and the base symbol and do something like

  // For a global, DECL_RTL is of the form (mem (symbol_ref))

  DECL_RTL (alias) = gen_rtx_MEM (TREE_MODE (alias),
				  plus_constant (XEXP (DECL_RTL (base), 0),
						 offset));
  MEM_ALIAS_SET (DECL_RTL (alias)) = get_alias_set (TREE_TYPE (alias));

I think.  This is off the top of my head.


r~

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-26  1:46               ` Andreas Schwab
@ 1999-04-30 23:15                 ` Andreas Schwab
  0 siblings, 0 replies; 36+ messages in thread
From: Andreas Schwab @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Richard Henderson, egcs

Zack Weinberg <zack@rabi.columbia.edu> writes:

|> On Fri, 23 Apr 1999 15:54:17 -0700, Richard Henderson wrote:
|> >On Fri, Apr 23, 1999 at 01:40:34PM -0400, Zack Weinberg wrote:
|> >> int common;
|> >> extern int alias __attribute__ ((alias("common")));
|> >> 
|> >> `alias' will not be defined in the object file.  The assembly dump
|> >> looks correct to me.
|> >
|> >This is not a bug.  This is impossible to represent 
|> >in the object file.  I believe SOM can do it if you
|> >feel like hurting yourself...  ;-)
|> 
|> I didn't know that.  It'd be nice if the assembler would complain
|> instead of silently discarding the symbol.

Compile with -fno-common.  Common symbols are evil anyway.

Andreas.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-24 21:53           ` Jeffrey A Law
@ 1999-04-30 23:15             ` Jeffrey A Law
  0 siblings, 0 replies; 36+ messages in thread
From: Jeffrey A Law @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Alexandre Oliva, Zack Weinberg, egcs

  In message < 19990423223236.A5686@pcep-jamie.cern.ch >you write:
  > Jeffrey A Law wrote:
  > > Cygnus implemented a switch to have the compiler dump offsets for fields
  > > within structures in a format intended to be used by assembly code.
  > 
  > Hey, my neuron flickered!
  > 
  > Does the dump include enough type information to generate a decent
  > non-conservative garbage collector?
I don't believe so (it's been a couple years since we did that work).

If I remember correctly it just spit out name/offset information, not true
type information.

You could get true type information out of debug symbols though.  We did this
when I was at the UofU to implement link time parameter type checking across
modules.    It wasn't fun though :-)

jeff

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 10:34       ` Jeffrey A Law
  1999-04-23 10:40         ` Zack Weinberg
  1999-04-23 13:36         ` Jamie Lokier
@ 1999-04-30 23:15         ` Jeffrey A Law
  2 siblings, 0 replies; 36+ messages in thread
From: Jeffrey A Law @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: Zack Weinberg, egcs

  In message < org15s33hj.fsf@lua.lbi.dcc.unicamp.br >you write:
  > > Because the preprocessor can't compute offsetof() all the way down;
  > > I'd have to compile and run a test program.  Which loses when
  > > cross-compiling.
  > 
  > Well, you could try to extract this information from the assembly
  > code, or from some RTL dump (since you're bound to gcc anyway), but I
  > wouldn't like to be the one to implement it :-)
Cygnus implemented a switch to have the compiler dump offsets for fields
within structures in a format intended to be used by assembly code.

It's not something we've used a lot and haven't ever thought it worth
the effort to clean it up and submit it to egcs.

I've been kicking around the idea of using that code to build a testsuite
to look for unexpected changes in structure layouts between releases as
one component of a wider1 ABI compatibility testing plan.

Ie, we build a repository of tests which define a bunch of structs, unions,
classes.  We compile those tests with the magic option which records the
offset for each field within the structure.  We do this for each target we
care about.

Then we can compile a later release and compare the offsets for that target
to ensure they have not changed.

It's not a perfect solution for ABI testing, but it's a small step we can
use as a building block.  Will it actually happen -- I don't know.  It's
still a blue sky project.

Jeff

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 13:49           ` Zack Weinberg
  1999-04-23 15:20             ` Jamie Lokier
  1999-04-23 22:58             ` Andi Kleen
@ 1999-04-30 23:15             ` Zack Weinberg
  2 siblings, 0 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Alexandre Oliva, egcs

On Fri, 23 Apr 1999 22:32:36 +0200, Jamie Lokier wrote:
>Jeffrey A Law wrote:
>> Cygnus implemented a switch to have the compiler dump offsets for fields
>> within structures in a format intended to be used by assembly code.
>
>Hey, my neuron flickered!
>
>Does the dump include enough type information to generate a decent
>non-conservative garbage collector?

You'd need stack frame information too, wouldn't you?

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 22:58             ` Andi Kleen
@ 1999-04-30 23:15               ` Andi Kleen
  0 siblings, 0 replies; 36+ messages in thread
From: Andi Kleen @ 1999-04-30 23:15 UTC (permalink / raw)
  To: egcs; +Cc: zack

zack@rabi.columbia.edu (Zack Weinberg) writes:

> On Fri, 23 Apr 1999 22:32:36 +0200, Jamie Lokier wrote:
> >Jeffrey A Law wrote:
> >> Cygnus implemented a switch to have the compiler dump offsets for fields
> >> within structures in a format intended to be used by assembly code.
> >
> >Hey, my neuron flickered!
> >
> >Does the dump include enough type information to generate a decent
> >non-conservative garbage collector?
> 
> You'd need stack frame information too, wouldn't you?

Can't you extract that information from the dwarf2 exception unwinding tables?


-Andi


PS: I was a bit disappointed that -g -gdwarf2 -fomit-frame-pointer debugging 
still does not work with gdb 4.18 (although objdump shows that the executable
contains lots of frame description)

-- 
This is like TV. I don't like TV.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 15:20             ` Jamie Lokier
@ 1999-04-30 23:15               ` Jamie Lokier
  0 siblings, 0 replies; 36+ messages in thread
From: Jamie Lokier @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Alexandre Oliva, egcs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 525 bytes --]

Zack Weinberg wrote:
> >Does the dump include enough type information to generate a decent
> >non-conservative garbage collector?
> 
> You'd need stack frame information too, wouldn't you?

In general yes, but a typed garbage collector that doesn't know about
stack frames would still be very useful.

Of course in my real fantasy it does do stack frames (based on PC à la
exceptions), it moves objects when that is more efficient, and it
efficiently handles polymorphic structures.  But that's fantasy land :-)

-- Jamie

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 16:19             ` Zack Weinberg
  1999-04-26  1:46               ` Andreas Schwab
@ 1999-04-30 23:15               ` Zack Weinberg
  1 sibling, 0 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Richard Henderson; +Cc: egcs

On Fri, 23 Apr 1999 15:54:17 -0700, Richard Henderson wrote:
>On Fri, Apr 23, 1999 at 01:40:34PM -0400, Zack Weinberg wrote:
>> int common;
>> extern int alias __attribute__ ((alias("common")));
>> 
>> `alias' will not be defined in the object file.  The assembly dump
>> looks correct to me.
>
>This is not a bug.  This is impossible to represent 
>in the object file.  I believe SOM can do it if you
>feel like hurting yourself...  ;-)

I didn't know that.  It'd be nice if the assembler would complain
instead of silently discarding the symbol.

zw



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-22 11:30   ` Zack Weinberg
  1999-04-22 11:38     ` Alexandre Oliva
@ 1999-04-30 23:15     ` Zack Weinberg
  1 sibling, 0 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: egcs

On 22 Apr 1999 15:24:46 -0300, Alexandre Oliva wrote:
>On Apr 22, 1999, Zack Weinberg <zack@rabi.columbia.edu> wrote:
>
>> extern __typeof(x.b) y __attribute__ ((alias("x.b")));
>
>This can't work.  The alias attribute defines an alias to a *symbol*,
>not to an arbitrary expression. 

I don't see that it would be terribly hard to extend alias so it could
handle SYMBOL_REFs and COMPONENT_REFs as well as strings.

>Since you may have to get quite
>platform-specific because of the potential need for leading
>underscores, 

This is already handled in the real framework; the above was a
stripped down example.

>why don't you compute the offset, say, in the configure
>script, then #define the appropriate alias string?

Because the preprocessor can't compute offsetof() all the way down;
I'd have to compile and run a test program.  Which loses when
cross-compiling.

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 15:24         ` Richard Henderson
  1999-04-23 16:27           ` Zack Weinberg
@ 1999-04-30 23:15           ` Richard Henderson
  1 sibling, 0 replies; 36+ messages in thread
From: Richard Henderson @ 1999-04-30 23:15 UTC (permalink / raw)
  To: Zack Weinberg, Alexandre Oliva; +Cc: egcs, egcs-patches

On Thu, Apr 22, 1999 at 05:31:38PM -0400, Zack Weinberg wrote:
> >That would probably be a good idea.  alias could accept an arbitrary
> >expression.  If it's an lvalue within a global symbol, it will define
> >an actual alias, otherwise it could just emit an error or ``construct
> >a temporary and bind the reference to it'', to put it in C++ terms :-) 
>
> It turns out to be relatively simple to implement, too (at least if
> you don't try to construct temporaries).  The appended patch is
> a proof-of-concept; I don't expect it'll make it into 1.2.  I had to
> introduce a new MD macro, ASM_OUTPUT_OFFSET_DEF...

This is a very bad way to implement this.  You're hiding from the
optimizers the fact that you've got two global symbols that alias.

The only way this will ever work is for you to adjust the DECL_RTL
of `y' such that the aliasing is visible.  You'd have something like

	(const (plus (symbol_ref "x") (const_int 42)))

for a global; something obvious for stack-local objects.  And of 
course this is only going to work without -fno-strict-aliasing if
the programmer makes sure that the types correspond.  But that, I 
think, is not your problem.

If you like to emit `y' as a global symbol too, that's fine. 

BTW, you don't need the ifdef in varasm.c if you have a version
in defaults.h.


r~

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: making aliases into the middle of a structure
  1999-04-23 10:40         ` Zack Weinberg
  1999-04-23 15:54           ` Richard Henderson
@ 1999-04-30 23:15           ` Zack Weinberg
  1 sibling, 0 replies; 36+ messages in thread
From: Zack Weinberg @ 1999-04-30 23:15 UTC (permalink / raw)
  To: law; +Cc: egcs

On Fri, 23 Apr 1999 00:14:34 -0600, Jeffrey A Law wrote:
>
>  In message < org15s33hj.fsf@lua.lbi.dcc.unicamp.br >you write:
>  > > Because the preprocessor can't compute offsetof() all the way down;
>  > > I'd have to compile and run a test program.  Which loses when
>  > > cross-compiling.
>  > 
>  > Well, you could try to extract this information from the assembly
>  > code, or from some RTL dump (since you're bound to gcc anyway), but I
>  > wouldn't like to be the one to implement it :-)
>Cygnus implemented a switch to have the compiler dump offsets for fields
>within structures in a format intended to be used by assembly code.
>
>It's not something we've used a lot and haven't ever thought it worth
>the effort to clean it up and submit it to egcs.

This is a cute idea, and I could think of uses in libc, but it doesn't
really solve my current problem (without excessive magic).  I'd much
rather be able to write

extern int var __attribute__ ((alias (structure.field)));

which is what the patch I sent yesterday implements.

Incidentally, I found what I think is a GAS bug: it forgets
aliases to symbols allocated with .comm.  For example:

int common;
extern int alias __attribute__ ((alias("common")));

`alias' will not be defined in the object file.  The assembly dump
looks correct to me.

zw

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~1999-04-30 23:15 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-04-22 11:13 making aliases into the middle of a structure Zack Weinberg
1999-04-22 11:25 ` Alexandre Oliva
1999-04-22 11:30   ` Zack Weinberg
1999-04-22 11:38     ` Alexandre Oliva
1999-04-22 14:31       ` Zack Weinberg
1999-04-23 15:24         ` Richard Henderson
1999-04-23 16:27           ` Zack Weinberg
1999-04-23 16:52             ` Richard Henderson
1999-04-30 23:15               ` Richard Henderson
1999-04-30 23:15             ` Zack Weinberg
1999-04-30 23:15           ` Richard Henderson
1999-04-30 23:15         ` Zack Weinberg
1999-04-23 10:34       ` Jeffrey A Law
1999-04-23 10:40         ` Zack Weinberg
1999-04-23 15:54           ` Richard Henderson
1999-04-23 16:19             ` Zack Weinberg
1999-04-26  1:46               ` Andreas Schwab
1999-04-30 23:15                 ` Andreas Schwab
1999-04-30 23:15               ` Zack Weinberg
1999-04-30 23:15             ` Richard Henderson
1999-04-30 23:15           ` Zack Weinberg
1999-04-23 13:36         ` Jamie Lokier
1999-04-23 13:49           ` Zack Weinberg
1999-04-23 15:20             ` Jamie Lokier
1999-04-30 23:15               ` Jamie Lokier
1999-04-23 22:58             ` Andi Kleen
1999-04-30 23:15               ` Andi Kleen
1999-04-30 23:15             ` Zack Weinberg
1999-04-24 21:53           ` Jeffrey A Law
1999-04-30 23:15             ` Jeffrey A Law
1999-04-30 23:15           ` Jamie Lokier
1999-04-30 23:15         ` Jeffrey A Law
1999-04-30 23:15       ` Alexandre Oliva
1999-04-30 23:15     ` Zack Weinberg
1999-04-30 23:15   ` Alexandre Oliva
1999-04-30 23:15 ` Zack Weinberg

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).