This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/70676] suboptimal code generation on AVR
- From: "night_ghost at ykoctpa dot ru" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 23 May 2016 06:22:06 +0000
- Subject: [Bug target/70676] suboptimal code generation on AVR
- Auto-submitted: auto-generated
- References: <bug-70676-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70676
--- Comment #2 from night_ghost at ykoctpa dot ru ---
*** testcase for call+ret: (all code from
https://github.com/night-ghost/minimosd-extra/tree/master/MinimOsd_Extra),
compile with -fno-optimize-sibling-calls
#include <Arduino.h>
class SPI
{
public:
SPI(void);
static byte transfer(byte);
};
SPI::SPI()
{
#define SCK_PIN 13
#define MISO_PIN 12
#define MOSI_PIN 11
// initialize the SPI pins
pinMode(SCK_PIN, OUTPUT);
pinMode(MOSI_PIN, OUTPUT);
pinMode(MISO_PIN, INPUT);
}
byte SPI::transfer(byte value){
SPDR = value;
while (!(SPSR & (1<<SPIF))) ;
return SPDR;
}
byte MAX_read(byte addr){
SPI::transfer(addr);
return SPI::transfer(0xff);
}
*** testcase of splitting tail, compile without -fno-optimize-sibling-calls
#include <Arduino.h>
#define NOINLINE __attribute__ ((noinline))
struct Point {
byte x;
byte y;
};
typedef struct Point point;
static boolean inline is_alt(point p){
return (p.y & 0x40);
}
static void NOINLINE osd_printf_1(PGM_P fmt, float f){
Serial.printf_P(fmt, f);
}
static void NOINLINE osd_printf_2(PGM_P fmt, float f, byte c){
Serial.printf_P(fmt, f);
Serial.write(c);
}
static void panBatteryPercent(point p){
float val=2.0;
if (is_alt(p))
osd_printf_1(PSTR("%2.0f%%"),val);
else
osd_printf_2(PSTR("%4.0f\x01"),val,0x15);
}
}
>Provided you use -mrelax (or link with -Wl,--relax), the linker tries to replace [R]CALL+RET by [R]JMP instruction
Thanks for good key, it saves 700bytes of code (from 30642 to 29942)