Removing a constant from function's argument list

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is it possible to tell the GCC compiler/optimizer to remove constant arguments from the function's argument list? That is, if I define a function:

void
send_byte(uint8_t UART_number	/**<= This is a parameter, not an argument */
			,char data				/**<= This one is a true argument	*/
			){
 
 switch(UART_number){
 
 case UART_number_0:
   UDR0=data;
 break;
 
 case UART_number_1:
   UDR1=data;
 break;
 case ....

 }
return;
}

and this time in my program I only use UART1:

send_byte(UART_number_1, my_data);
...
send_byte(UART_number_1, another_data);
...
send_byte(UART_number_1, and_more);

with the same and known at compile time first argument value, can a compiler change the prototype from:

void send_byte(uint8_t , char);

into:

void send_byte(char);

and remove the dead code from inside of send_byte() this time?

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No.

But if the function is in the same file as where it is being called and the function is defined as static inline, you will probably get optimization.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brutte wrote:
can a compiler change the prototype from:
void send_byte (uint8_t, char);

into:

void send_byte (char);

and remove the dead code from inside of send_byte() this time?

Yes, but the compile must see the callers' and the calle's code at the same time; either because they reside in the same source module or by using link time optimization (LTO).

The respective optimization technique is inter procedural constant propagation. The compiler may clone the callee dependent on the constant(s) provided by the caller and build callee-copies with on-the-fly parameter lists as needed.

See GCC options -fipa-cp and -fipa-cp-clone for more details on these and other inter-procedural analysis (IPA) optimizations.

If GCC clones a function, you'll see ".cprop" as a part of the cloned function's name.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Another way is to use C++ templates
UART number will be template parameter, compiler will generate separate copy for each template instance with constant expressions optimized out:

#include 

enum uart_number { UART_0, UART_1};

template
__attribute__((__noinline__))   // <------------------(1)
void send_byte(char data)
{
        switch(uart) {
        case UART_0:  UDR0 = data; break;
        case UART_1:  UDR1 = data; break;
        }
}

void foo()
{
        send_byte('a');
        send_byte('b');
}

void foo1()
{
        send_byte('A');
        send_byte('B');
}

avr-gcc -O2 -S -mmcu=atmega128 tmpl.cpp
(1) uncommented:

// send_byte()
_Z9send_byteIL11uart_number0EEvc:
	out 44-32,r24
	ret

// send_byte()
_Z9send_byteIL11uart_number1EEvc:
	sts 156,r24
	ret

// foo1()
_Z4foo1v:
	ldi r24,lo8(65)
	call _Z9send_byteIL11uart_number0EEvc
	ldi r24,lo8(66)
	call _Z9send_byteIL11uart_number1EEvc
	ret

// foo()
_Z3foov:
	ldi r24,lo8(97)
	call _Z9send_byteIL11uart_number0EEvc
	ldi r24,lo8(98)
	call _Z9send_byteIL11uart_number1EEvc
	ret

(1) commented:

// foo()
_Z3foov:
	ldi r24,lo8(97)
	out 44-32,r24
	ldi r24,lo8(98)
	sts 156,r24
	ret

// foo1()
_Z4foo1v:
	ldi r24,lo8(65)
	out 44-32,r24
	ldi r24,lo8(66)
	sts 156,r24
	ret

wbr, ReAl

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the hints freaks!

Here is what I have found:

General idea:
http://en.wikipedia.org/wiki/Con...

And specifically the Interprocedural Constant Propagation (IPA) is the name I wanted to know.

An old article (1986) about IPA(pdf,1MB) with decent explanation:
http://citeseerx.ist.psu.edu/vie...

The GCC I use is 4.3.3:
http://gcc.gnu.org/onlinedocs/gc...
and it does not have -fipa-cp-clone option implemented.

But newer GCC version 4.7.0 has:
http://gcc.gnu.org/onlinedocs/gc...

And actually, for -Os it would be great to perform ipa-cp, but avoid cloning at all costs!

One of the implementations:
http://www.open64.net/doc/d0/d46...

No RSTDISBL, no fun!