This is the mail archive of the gcc@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]

powerpc back end silly moves


I'm testing code to make the powerpc back end do structure returns the
way the SVR4 ABI says it's supposed to: if the structure is <= 8
bytes, load it into r3 and r4 instead of flushing it to memory.
While doing this I noticed that it generates unnecessary moves.  If
you feed cc1 with my patch (coming soon) this input:

struct x { int a, b; };
struct x X (int a, int b) { struct x r; r.a = a; r.b = b; return r; }

you get (-O2 -mregnames):

X:
        mr %r9,%r3
        mr %r10,%r4
        mr %r3,%r9
        mr %r4,%r10
        blr

All four moves are unnecessary.

Here's what the RTL looks like right before register allocation
(patterns only):

	(set (reg/v:SI 116)
	     (reg:SI 3 r3))
	
	(set (reg/v:SI 117)
	     (reg:SI 4 r4))

	(set (subreg:SI (reg/v:DI 118) 0)
	     (reg/v:SI 116))

	(set (subreg:SI (reg/v:DI 118) 4)
	     (reg/v:SI 117))

	(set (reg/i:DI 3 r3)
	     (reg/v:DI 118))

	(use (reg/i:DI 3 r3))

I hear you scream, wait, this is a 32-bit target, why does it think it
can put a DImode value into r3?  Well, it's short-hand for the r3/r4
register pair, you see.

Register allocation sensibly figures out it can equate pseudos 116 and
117 with hard registers 3 and 4, but it does _not_ realize that the
subreg sets can be done in place.  The .greg dump looks like

	(set (reg/v:SI 3 r3 [116])
	     (reg:SI 3 r3))

	(set (reg/v:SI 4 r4 [117])
	     (reg:SI 4 r4))

	(set (reg:SI 9 r9)
	     (reg/v:SI 3 r3 [116]))

	(set (reg:SI 10 r10 [118])
	     (reg/v:SI 4 r4 [117]))

	(set (reg/i:DI 3 r3)
	     (reg/v:DI 9 r9 [118]))

	(use (reg/i:DI 3 r3))

Post-reload cleanup zaps the first two moves, but no more.

The very similar code

struct x { int a; };
struct x X (int a) { struct x r; r.a = a; return r; }

gets crushed all the way down to just

	(use (reg/i:SI 3 r3))

by the very first CSE pass.  I'm therefore inclined to blame this on
poor high-level handling of these register pairs and/or of SUBREG
operations.

zw


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