Question on aggregates and GIMPLE

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Wed Jun 9 02:21:00 GMT 2004


    Surely these comparisons and copies can be decomposed into simpler
    operations?  After all, you do generate RTL at some point.  The
    expansion into GIMPLE should resemble that.

Well, the RTL generation depends very much on what instructions are available
on the target.  If block move and block compare instructions are available,
they'll be used.  Otherwise, they will be decomposed into a sequence of
instructions depending on what's available on the target and what the
alignment is.

But it seems very wrong to drop down to the level of losing the variable and
operation at tree level.  The whole advantage of tree-level optimization is
that we can do things at a higher semantic level than RTL.  If we basically
write RTL in GIMPLE, we're not gaining anything and probably losing a lot.

Right now, for variable-sized objects, gimplification converts the operation
to an explicit call to a builtin memcpy.  We could do the same thing for
compare and call memcmp.  As I understand it, the reason for that is to avoid
the implicit size.  But we could make it explicit by adding it to MODIFY_EXPR
and the comparisons, though I agree that that's a lot more memory than
ARRAY_REFs.

However, the problem still is the large-but-nonconstant cases.  Right now,
we'll ICE if there's an ARRAY_TYPE since temporaries are forbidden from
having those types for reasons that have never been explained to me.  But if
we allow that (trivial), is it still a good idea to add explicit copies of
aggregates that could be many MB?  And then you have the types for which
copying is not permitted.

    Is this similar to the matrix syntax in Fortran?  During the summit we
    talked about not decomposing things like 'A = B + C', where A, B and C
    are matrices.

No, it's simpler.  I'm just talking about copies.  For example:

	with unchecked_conversion;
	package tuc is
	  type t1 is array (1...250000) of integer;
	  type t2 is array (1...250000) of float;
	  function uc is new unchecked_conversion (t1, t2);
	  type pt1 is access all t1;
          type pt2 is access all t2;
          procedure cpy (p1: pt1; p2: pt2);
        end tuc;
        package body tuc is
          procedure cpy (p1: pt1; p2: pt2);
	  begin
	    pt2.all := uc (pt1.all);
          end cpy;
        end tuc;

I hope this is readable.  The only executable line becomes:

	<MODIFY_EXPR <INDIRECT_EXPR <PARM_DECL pt2>>
		     <VIEW_CONVERT_EXPR <INDIRECT_REF <PARM_DECL pt1>>>>

The programmer expects exactly one copy of this 1 MB array.  However, we'll
do two since the gimplification will make a temporary for the INDIRECT_REF
on the RHS.



More information about the Gcc mailing list