Hi there,
I'm testing the speed optimization in max level for de MSP430 Compiler 4.1, using CCS 5.4.
I coded a simple API pattern to use with GPIO. In the main loop, the code just toggles 3 leds in sequence. So I was hoping that, using max speed optimization level, the assembly code for the loop would be just XORs. But I get also in the assembly some pointer indirection overhead. I've tried to declare "const" as much as possible, but yet the compiler don't optimizes the pointer indirection.
Is there any other thing I should do to guarantee optimization?
The code below is my code example. It can be directly compiled in "main.c". It was intended for the experimenter's board. As you can see, the main loop just call the routines to toggle the leds.
So, the specific question is: Why can't the compiler optimize the function SetPins to an assembly XOR?
#include "msp430xg46x.h" #include <stdint.h> #include <stdlib.h> /* * hal_gpio.h */ typedef struct Pin Pin; typedef struct GPIO8 { void (* ConfigPinsAsGPIOOutput) (const Pin * const pin); void (* SetPins) (const Pin * const pin); } GPIO8; /* * hal_gpio.c */ typedef struct Pin { const void * hiddenPin; } Pin; /* * msp_gpio.h */ struct MSP_GPIO_t { GPIO8 GPIO8; }; const struct MSP_GPIO_t MSP_GPIO; /* * msp_gpio.c */ typedef struct Regs { volatile unsigned char * const dir; volatile unsigned char * const sel; volatile unsigned char * const out; } Regs; const Regs vRegs[] = { { &P2DIR, &P2SEL, &P2OUT}, { &P5DIR, &P5SEL, &P5OUT}, }; typedef struct MspPin{ const Regs * pRegs; uint8_t bitmask; } MspPin; void _ConfigPinsAsGPIOOutput(const MspPin * const pin) { *(pin->pRegs->dir) |= pin->bitmask; *(pin->pRegs->sel) &= ~(pin->bitmask); } void _SetPins(const MspPin * const pin) { *(pin->pRegs->out) ^= pin->bitmask; } void ConfigPinsAsGPIOOutput(const Pin * const args) { _ConfigPinsAsGPIOOutput(args->hiddenPin); } void SetPins(const Pin * const args) { _SetPins(args->hiddenPin); } const struct MSP_GPIO_t MSP_GPIO = { { &ConfigPinsAsGPIOOutput, &SetPins,} }; /* * main.c */ volatile uint16_t i; const GPIO8 * const Porta = &MSP_GPIO.GPIO8; const MspPin mp1 = {&vRegs[0], BIT1}; const MspPin mp2 = {&vRegs[0], BIT2}; const MspPin mp4 = {&vRegs[1], BIT1}; const Pin p1 = {&mp1}; const Pin p2 = {&mp2}; const Pin p4 = {&mp4}; int main(void) { volatile uint16_t j; WDTCTL = WDTPW +WDTHOLD; Porta->ConfigPinsAsGPIOOutput(&p1); Porta->ConfigPinsAsGPIOOutput(&p2); Porta->ConfigPinsAsGPIOOutput(&p4); while(1) { Porta->SetPins(&p1); Porta->SetPins(&p2); Porta->SetPins(&p4); Porta->SetPins(&p1); Porta->SetPins(&p2); Porta->SetPins(&p4); Porta->SetPins(&p1); Porta->SetPins(&p2); Porta->SetPins(&p4); Porta->SetPins(&p1); Porta->SetPins(&p2); Porta->SetPins(&p4); } }
EDIT: I've also tried inlining the functions and setting some advanced optimization options, but with no different results.