On Mon, Feb 12, 2024 at 5:49 PM Hugh Gleaves via Gcc <gcc@gcc.gnu.org> wrote:
>
> I’m interested in whether it would be feasible to add an optimization that 
> compacted assignments to multiple bit fields.
>
> Today, if I have a 32 bit long struct composed of say, four 8 bit fields and 
> assign constants to them like this:
>
>                 ahb1_ptr->RCC.CFGR.MCO1_PRE = 7;
>                 ahb1_ptr->RCC.CFGR.I2SSC = 0;
>                 ahb1_ptr->RCC.CFGR.MCO1 = 3;
>
> This generates code (on Arm) like this:
>
>                 ahb1_ptr->RCC.CFGR.MCO1_PRE = 7;
> 0x08000230  ldr.w r1, [r3, #2056]              @ 0x808
> 0x08000234  orr.w r1, r1, #117440512     @ 0x7000000
> 0x08000238  str.w r1, [r3, #2056]              @ 0x808
>                 ahb1_ptr->RCC.CFGR.I2SSC = 0;
> 0x0800023c  ldr.w r1, [r3, #2056]              @ 0x808
> 0x08000240  bfc r1, #23, #1
> 0x08000244  str.w r1, [r3, #2056]              @ 0x808
>                 ahb1_ptr->RCC.CFGR.MCO1 = 3;
> 0x08000248  ldr.w r1, [r3, #2056]              @ 0x808
> 0x0800024c  orr.w r1, r1, #6291456          @ 0x600000
> 0x08000250  str.w r1, [r3, #2056]              @ 0x808
>
> It would be an improvement, if the compiler analyzed these assignments and 
> realized they are all modifications to the same 32 bit datum, generate an 
> appropriate OR and AND bitmask and then apply those to the register and do 
> just a single store at the end.
>
> In other words, infer the equivalent of this:
>
>                 RCC->CFGR &= ~0x07E00000;
>                 RCC->CFGR |=    0x07600000;
>
> This strikes me as very feasible, the compiler knows the offset and bit 
> length of the sub fields so all of the information needed seems to be present.

There is the store-merging pass which should already do this when
constraints allow.

Richard.

> Thoughts…
>
>
>

Reply via email to