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]

RE: Understand BLKmode and returning structure in register.


I found that compiling for mips with -mabi=n32 produces such inefficient code. When -mabi=n32, mips_return_in_memory returns 0 if size is small regardless BLKmode or not. 

	.type	foo, @function
foo:
	.frame	$sp,16,$31		# vars= 16, regs= 0/0, args= 0, gp= 0

	addiu	$sp,$sp,-16
	li	$2,-7			# 0xfffffffffffffff9
	sh	$2,0($sp)
	sh	$2,2($sp)
	ld	$3,0($sp)
	addiu	$sp,$sp,16
	dsrl	$4,$3,32
	andi	$4,$4,0xffff
	dsrl	$3,$3,48
	dsll	$4,$4,32
	dsll	$2,$3,48
	j	$31
	or	$2,$2,$4

	.ent	main
	.type	main, @function
main:
	
	addiu	$sp,$sp,-48
	sd	$31,40($sp)
	jal	foo
	nop

	dsra	$3,$2,32
	dsrl	$2,$2,48
	sh	$3,18($sp)
	sh	$2,16($sp)
	lw	$2,16($sp)
	sll	$3,$2,16
	sw	$2,0($sp)
	sra	$3,$3,16
	li	$2,-7			# 0xfffffffffffffff9
	bne	$3,$2,$L8
	ld	$31,40($sp)

	j	$31
	addiu	$sp,$sp,48

$L8:
	jal	abort
	nop


With old ABI, produced code is much simpler but the structure is returned through memory. mips_retrun_in_memory returns 1 because the structure type is BLKmode.

foo:
	li	$3,-7			# 0xfffffffffffffff9
	move	$2,$4
	sh	$3,0($4)
	j	$31
	sh	$3,2($4)

	.ent	main
	.type	main, @function
main:
	.frame	$sp,32,$31		# vars= 8, regs= 1/0, args= 16, gp= 0
	
	addiu	$sp,$sp,-32
	sw	$31,28($sp)
	jal	foo
	addiu	$4,$sp,16

	lh	$3,18($sp)
	li	$2,-7			# 0xfffffffffffffff9
	bne	$3,$2,$L8
	nop

	lw	$31,28($sp)
	nop
	j	$31
	addiu	$sp,$sp,32

$L8:
	jal	abort
	nop

> -----Original Message-----
> From: gcc-owner@gcc.gnu.org [mailto:gcc-owner@gcc.gnu.org] On 
> Behalf Of Bingfeng Mei
> Sent: 13 March 2009 16:35
> To: gcc@gcc.gnu.org
> Cc: Adrian Ashley
> Subject: Understand BLKmode and returning structure in register.
> 
> Hello,
> I came across an issue regarding BLKmode and returning 
> structure in register.  For following code,  I try to return 
> the structure in register instead of memory. 
>  
> extern void abort();
> typedef struct {
>   short x;
>   short y;
> } COMPLEX;
>  
> COMPLEX foo (void) __attribute__ ((noinline));
> COMPLEX foo (void)
> {
>   COMPLEX  x;  
>  
>   x.x = -7;
>   x.y = -7;
>  
>   return x;
> }
>  
> 
> int main(){
>   COMPLEX x = foo();
>   if(x.y != -7)
>     abort();
> }
> 
>  
> In foo function, compute_record_mode function will set the 
> mode for struct COMPLEX as BLKmode partly because 
> STRICT_ALIGNMENT is 1 on my target. In 
> TARGET_RETURN_IN_MEMORY hook, I return 1 for BLKmode type and 
> 0 otherwise for small size (<8) (like MIPS). Thus, this 
> structure is still returned through memory, which is not very 
> efficient. More importantly, ABI is NOT FIXED under such 
> situation. If an assembly code programmer writes a function 
> returning a structure. How does he know the structure will be 
> treated as BLKmode or otherwise? So he doesn't know whether 
> to pass result through memory or register. Do I understand correctly?
> 
> On the other hand, if I return 0 only according to struct 
> type's size regardless BLKmode or not, GCC will produces very 
> inefficient code. For example, stack setup code in foo is 
> still generated even it is totally unnecessary.
> 
> Only when I set STRICT_ALIGNMENT to 0, the structure can be 
> passed through register in an efficient way. Unfortunately, 
> our machine is strictly aligned and I cannot really do that. 
> 
> Any suggestion? 
> 
> Thanks,
> Bingfeng Mei
> Broadcom UK 
> 
> 
> 


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