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… > > >