diff mbox

Regimplification enhancements 1/3

Message ID 539ECD65.40405@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt June 16, 2014, 10:56 a.m. UTC
For the ptx port, I've needed to write a new pass which ensures all 
objects go into address spaces as required by the machine. This uses the 
regimplification code in gimplify-me.c, and that requires some fixes and 
upgrades.

Here's the first. When address spaces change, an ADDR_EXPR may have to 
be changed to ADDR_SPACE_CONVERT_EXPR, and these two have different 
representations in gimple. This patch stops the regimplification code 
from creating invalid gimple in such a case.

Bootstrapped and tested on x86_64-linux, ok?


Bernd

Comments

Richard Biener June 16, 2014, 11:24 a.m. UTC | #1
On Mon, Jun 16, 2014 at 12:56 PM, Bernd Schmidt <bernds@codesourcery.com> wrote:
> For the ptx port, I've needed to write a new pass which ensures all objects
> go into address spaces as required by the machine. This uses the
> regimplification code in gimplify-me.c, and that requires some fixes and
> upgrades.

Can you explain how and why you need re-gimplification here?  IMHO
you should apply the necessary steps yourself, not put in GENERIC
into GIMPLE and rely on the gimplifier.

> Here's the first. When address spaces change, an ADDR_EXPR may have to be
> changed to ADDR_SPACE_CONVERT_EXPR, and these two have different
> representations in gimple. This patch stops the regimplification code from
> creating invalid gimple in such a case.
>
> Bootstrapped and tested on x86_64-linux, ok?

+      if (is_gimple_assign (stmt)
+         && num_ops == 2
+         && (get_gimple_rhs_class (gimple_expr_code (stmt))
+             == GIMPLE_SINGLE_RHS)
+         && (get_gimple_rhs_class (TREE_CODE (gimple_op (stmt, 1)))
+             != GIMPLE_SINGLE_RHS))

err ... that's a very crappy gimple condition that isn't going to reliably work.

You can't turn a x = &foo; into x = (convert)&foo; this way abusing
the re-gimplification routines.

The re-gimplification routines do _not_ accept random GENERIC
operands.  They were written to handle registers becoming non-registers
and nothing more.

Richard.

>
> Bernd
Bernd Schmidt June 16, 2014, 11:45 a.m. UTC | #2
On 06/16/2014 01:24 PM, Richard Biener wrote:
> On Mon, Jun 16, 2014 at 12:56 PM, Bernd Schmidt <bernds@codesourcery.com> wrote:
>> For the ptx port, I've needed to write a new pass which ensures all objects
>> go into address spaces as required by the machine. This uses the
>> regimplification code in gimplify-me.c, and that requires some fixes and
>> upgrades.
>
> Can you explain how and why you need re-gimplification here?  IMHO
> you should apply the necessary steps yourself, not put in GENERIC
> into GIMPLE and rely on the gimplifier.

That's not actually what's happening - the pass modifies the address 
spaces of all objects (local & global vars etc.) and I have one 
additional patch in gimplify.c that recognizes address space mismatches 
on an ADDR_EXPR (also testing a new TYPE_QUAL_AS_IMPLICIT bit to ensure 
it only triggers in situations it's intended to) and inserts the 
necessary ADDR_SPACE_CONVERT_EXPR. With that I can pass all statements 
through regimplification to get a consistent view of the world again.

> You can't turn a x = &foo; into x = (convert)&foo; this way abusing
> the re-gimplification routines.
> The re-gimplification routines do _not_ accept random GENERIC
> operands.  They were written to handle registers becoming non-registers
> and nothing more.

It seems to work fine is all I can say. What it was written for and what 
it can be useful for are two different things.


Bernd
Richard Biener June 16, 2014, 12:40 p.m. UTC | #3
On Mon, Jun 16, 2014 at 1:45 PM, Bernd Schmidt <bernds@codesourcery.com> wrote:
> On 06/16/2014 01:24 PM, Richard Biener wrote:
>>
>> On Mon, Jun 16, 2014 at 12:56 PM, Bernd Schmidt <bernds@codesourcery.com>
>> wrote:
>>>
>>> For the ptx port, I've needed to write a new pass which ensures all
>>> objects
>>> go into address spaces as required by the machine. This uses the
>>> regimplification code in gimplify-me.c, and that requires some fixes and
>>> upgrades.
>>
>>
>> Can you explain how and why you need re-gimplification here?  IMHO
>> you should apply the necessary steps yourself, not put in GENERIC
>> into GIMPLE and rely on the gimplifier.
>
>
> That's not actually what's happening - the pass modifies the address spaces
> of all objects (local & global vars etc.) and I have one additional patch in
> gimplify.c that recognizes address space mismatches on an ADDR_EXPR (also
> testing a new TYPE_QUAL_AS_IMPLICIT bit to ensure it only triggers in
> situations it's intended to) and inserts the necessary
> ADDR_SPACE_CONVERT_EXPR. With that I can pass all statements through
> regimplification to get a consistent view of the world again.

Uh.  So what do you do?  You'd place an object in a different address-space
and when seeing &foo then simply lie to GIMPLE and say the address
is really not in that address space?  What you you do when such
pointer is dereferenced then?

It looks wrong to me to do such semantic changing transforms in
gimplification.

Richard.

>> You can't turn a x = &foo; into x = (convert)&foo; this way abusing
>> the re-gimplification routines.
>> The re-gimplification routines do _not_ accept random GENERIC
>> operands.  They were written to handle registers becoming non-registers
>> and nothing more.
>
>
> It seems to work fine is all I can say. What it was written for and what it
> can be useful for are two different things.
>
>
> Bernd
>
Mike Stump June 16, 2014, 5:26 p.m. UTC | #4
On Jun 16, 2014, at 3:56 AM, Bernd Schmidt <bernds@codesourcery.com> wrote:
> For the ptx port, I've needed to write a new pass which ensures all objects go into address spaces as required by the machine.

I have such a machine and I’ve always approached the problem from the front end side.  I ensure the right space up front, and if someone doesn’t get the right space, I add code to let the port choose the space for that object (literal constants I wanna play around with some for example).  On my port there is no changing spaces once one is selected.

I’m curious if your port needs to change a space (and why, I’m wondering if I can improve my port by changing spaces)?

One known issue for my port is if I run out of memory in one space, I don’t magically fall over to another space, but rather just fail.  The other is space selection for the stack.  I let it default, and then during operand printing I select the space I’ve chosen for the default.  The scheduling is complicated as I have to handle two spaces (normal, plus default), instead of just one.
Bernd Schmidt June 16, 2014, 5:49 p.m. UTC | #5
On 06/16/2014 07:26 PM, Mike Stump wrote:
> On Jun 16, 2014, at 3:56 AM, Bernd Schmidt <bernds@codesourcery.com>
> wrote:
>> For the ptx port, I've needed to write a new pass which ensures all
>> objects go into address spaces as required by the machine.
>
> I have such a machine and I’ve always approached the problem from the
> front end side.  I ensure the right space up front, and if someone
> doesn’t get the right space, I add code to let the port choose the
> space for that object (literal constants I wanna play around with
> some for example).  On my port there is no changing spaces once one
> is selected.

There are two reasons why I can't do this in the frontends - one, Joseph 
has already rejected a C frontend patch, and two, this needs to work 
with OpenACC offloading - i.e. code is initially compiled by an x86 host 
compiler, then a ptx lto1 reads it in and needs to make it valid for 
that target.

> I’m curious if your port needs to change a space (and why, I’m
> wondering if I can improve my port by changing spaces)?

No, address spaces are fixed for globals, locals, and rodata. But in the 
early stages of the compiler, for the above reasons we need to pretend 
that there aren't any address spaces involved, and only the 
lower-addr-spaces pass moves everything to the right place.


Bernd
Mike Stump June 16, 2014, 9:52 p.m. UTC | #6
On Jun 16, 2014, at 10:49 AM, Bernd Schmidt <bernds@codesourcery.com> wrote:
> 
> There are two reasons why I can't do this in the frontends - one, Joseph has already rejected a C frontend patch,

I’d like to think there is an acceptable way to get the right memory space on things...

> and two, this needs to work with OpenACC offloading - i.e. code is initially compiled by an x86 host compiler, then a ptx lto1 reads it in and needs to make it valid for that target.

Ah yes, that would do it, thanks.  I can see my port as an offload target…  I’ll have to keep on eye on OpenACC and gcc.
Richard Biener June 17, 2014, 8:02 a.m. UTC | #7
On Mon, Jun 16, 2014 at 11:52 PM, Mike Stump <mikestump@comcast.net> wrote:
> On Jun 16, 2014, at 10:49 AM, Bernd Schmidt <bernds@codesourcery.com> wrote:
>>
>> There are two reasons why I can't do this in the frontends - one, Joseph has already rejected a C frontend patch,
>
> I’d like to think there is an acceptable way to get the right memory space on things...
>
>> and two, this needs to work with OpenACC offloading - i.e. code is initially compiled by an x86 host compiler, then a ptx lto1 reads it in and needs to make it valid for that target.
>
> Ah yes, that would do it, thanks.  I can see my port as an offload target…  I’ll have to keep on eye on OpenACC and gcc.

But then IMHO using the gimplifier to do this fixup is wrong.  Please add
those required ADDR_SPACE_CONVERT_EXPRs in your pass manually.
After all you also have to adjust types of MEM_REFs and possibly
types of pointer variables (and pointer sizes?).

Richard.
diff mbox

Patch

commit 00edd2d382d406b2f729885f08aa16928552d9d0
Author: Bernd Schmidt <bernds@codesourcery.com>
Date:   Wed Jun 11 18:41:09 2014 +0200

    Fix an issue with regimplification.
    
    This is in preparation for the lower-address-spaces pass for the ptx port. We
    need to teach the regimplifier how to handle the case when an ADDR_EXPR turns
    into something else, like an ADDR_SPACE_CONVERT_EXPR.
    
    	gcc/
    	* gimplify-me.c (gimple_regimplify_operands): Handle case where a
    	GIMPLE_SINGLE_RHS is turned into something else.

diff --git a/gcc/gimplify-me.c b/gcc/gimplify-me.c
index 05e986a..467ec6c 100644
--- a/gcc/gimplify-me.c
+++ b/gcc/gimplify-me.c
@@ -248,6 +248,22 @@  gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
 	    gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
 	  gimple_set_op (stmt, i - 1, op);
 	}
+      if (is_gimple_assign (stmt)
+	  && num_ops == 2
+	  && (get_gimple_rhs_class (gimple_expr_code (stmt))
+	      == GIMPLE_SINGLE_RHS)
+	  && (get_gimple_rhs_class (TREE_CODE (gimple_op (stmt, 1)))
+	      != GIMPLE_SINGLE_RHS))
+	{
+	  tree rhs = gimple_assign_rhs1 (stmt);
+	  tree temp = create_tmp_reg (TREE_TYPE (rhs), NULL);
+	  if (gimple_in_ssa_p (cfun))
+	    temp = make_ssa_name (temp, NULL);
+	  gimple_assign_set_rhs1 (stmt, temp);
+	  gimple_assign_set_rhs_code (stmt, TREE_CODE (temp));
+	  gimple pre_stmt = gimple_build_assign (temp, rhs);
+	  gimple_seq_add_stmt_without_update (&pre, pre_stmt);
+	}
 
       lhs = gimple_get_lhs (stmt);
       /* If the LHS changed it in a way that requires a simple RHS,