This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] for PR 18040


kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

>     > ... actually, it's not good enough because it doesn't handle the
>     > 	((cast) var).field
>     > case and that's an expensive one.
>
>     My gut feeling is that needing this cast means there's something wrong
>     with the static type of VAR.  Could you show an example of source code
>     that needs this cast, and the type tree generated for VAR?
>
> Well, in Ada you can get it with an explicit Unchecked_Conversion to a
> composite type.  For example:
>
> 	with unchecked_conversion;
> 	function foo return integer is
> 	    type arr is array (1..100_000) of integer;
> 	    type r is record
> 		f1: length;
> 		f2: array (1..99_999) of integer;
> 	    end record;
>
> 	    var: foo;
> 	begin
> 	    return uc (foo).f1 + foo (2000);
> 	end foo;

This example has problems.  It only makes any sense at all if I assume
you meant to write 'var' instead of 'foo' in both places inside the
body of the function.  Also, you left out the declaration of uc, which
meant I had to go look up how unchecked_conversion works.  And my copy
of GNAT (from GCC 3.3) doesn't like the record declaration.  After
some bludgeoning I have managed to produce an example that compiles
and still, I believe, captures what you intended to demonstrate:

with unchecked_conversion;
function foo return integer is
    type arr is array (1..100_000) of integer;
    type arr2 is array (1..99_999) of integer;
    type r is record
        f1: integer;
        f2: arr2;
    end record;
    function uc is new unchecked_conversion (source => arr, target => r);
    var : arr;
begin
    return uc(var).f1 + var(2000);
end foo;

If I have understood correctly, then my suggestion would be that you
should have Gigi translate this code to GENERIC equivalent to the
following C example:

int foo(void)
{
  typedef int arr[100000];
  typedef struct { int f1; int f2[999999]; } r;

  arr var;

  return ((r *) &var)->f1 + var[2000];
}

This does not look very different from what you are generating now,
but sandwiching the cast inside an address-of and dereference means
that the gimplifier can break it down without needing to create an
aggregate temporary, producing something like this:

int foo(void)
{
  typedef int arr[100000];
  typedef struct { int f1; int f2[999999]; } r;

  arr var;
  r *var0;

  int v1, v2, rv;

  var0 = (r *) &var;

  v1 = var0->f1;
  v2 = var[2000];
  rv = v1 + v2;

  return rv;
}

You would do this any time either side of the unchecked_conversion is
not a scalar type.

The only catch is that alias analysis must understand that rp aliases
var.  This may require some adjustment to GNAT's alias set logic.

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]