anchao commented on PR #21340:
URL: https://github.com/apache/nuttx/pull/21340#issuecomment-6731449770

   > On these boards, this PR makes printf larger and uses more stack. The 
split is easier to read, but I think the community prefers the flash and the 
stack.
   > 
   > Measured on the head 
[521f515](https://github.com/apache/nuttx/commit/521f515584cf02f3e5e195ecea9b47fecd2d2f44)
 against its base 
[9ffe762](https://github.com/apache/nuttx/commit/9ffe7625cb187004cf209f113b3cd96472c92ab2),
 `size nuttx`, with `-fstack-usage`. Boards: nucleo-f072rb:nsh (Cortex-M0), 
nucleo-f103rb:nsh (Cortex-M3), rv-virt:nsh (rv32), qemu-armv8a:nsh (arm64), 
each with its defconfig optimization (-Os); numbered arguments, locale and 
print extensions off.
   > 
   > Image text:
   > 
   > M0 M3      rv32    arm64
   > float off  +212    +200    +208    +332
   > float on   +232    +320    +264    +584
   > float off, `vsprintf_put_field()` and `vsprintf_put_char()` plain `static` 
+84     +104    +114    +204
   > float on, the same two `static`    +96     +160    +160    +368
   > Deepest stack from `lib_vsprintf()`, in bytes, base / head / the two 
helpers `static`:
   > 
   > M0 M3      rv32    arm64
   > float off  128 / 128 / 168 104 / 104 / 144 128 / 144 / 160 160 / 208 / 272
   > float on   160 / 168 / 184 144 / 152 / 160 208 / 208 / 208 192 / 240 / 304
   > So `static` removes 37% to 60% of the added flash, but then the stack 
grows more. The flash does not get back to the base on any board.
   > 
   > The drop of the `vsprintf_internal()` frame shows only without 
optimization. On qemu-armv8a:nsh with float, numbered arguments, locale and 
print extensions on: 400 to 192 bytes at -O0, 224 to 224 at -Os, 256 to 272 at 
-O2.
   > 
   > The printf series (#21493 and the PRs after it) changes most of this file. 
Fix: put this PR on hold until that series merges, then do the split on top of 
it, with no growth of image text and of the deepest stack on these boards. I 
can share the measurement scripts.
   
   @casaroli  Thanks for checking this.                                         
               
                                                                                
    
   I looked into this again, and I think the stack increase is related to the   
    
   forced inlining. In NuttX, inline_function is defined as always_inline when  
    
   optimization is enabled:                                                     
    
                                                                                
    
     #define inline_function __attribute__((always_inline)) inline              
    
                                                                                
    
   So using static inline_function here forces GCC to inline all of these split 
    
   helpers back into vsprintf_internal(). That can increase both the generated  
    
   text and the caller's stack frame, because the local state from multiple 
helper  
   paths is now combined in the same function.                                  
    
                                                                                
    
   I tested this with GCC by removing inline_function from all of the split     
    
   vsprintf helpers and keeping them as plain static functions. On my test 
config   
   (gd32f450zk-eval / GCC, with CONFIG_LIBC_FLOATINGPOINT=n,                    
    
   CONFIG_LIBC_NUMBERED_ARGS=n and CONFIG_LIBC_LOCALE=n), the result was:       
    
                                                                                
    
     nuttx.elf text:                                                            
    
       173218 -> 171802  (-1416 bytes)                                          
    
                                                                                
    
     lib_libvsprintf.o text:                                                    
    
       4921 -> 3505      (-1416 bytes)                                          
    
                                                                                
    
     stack usage:                                                               
    
       vsprintf_internal:                                                       
    
         424 -> 192 bytes                                                       
    
                                                                                
    
       added helper frames:                                                     
    
         vsprintf_scan_literal     48 bytes                                     
    
         vsprintf_put_field        40 bytes                                     
    
         vsprintf_put_char         40 bytes                                     
    
         vsprintf_put_integer      40 bytes                                     
    
         vsprintf_pointer_flags     8 bytes                                     
    
                                                                                
    
   So for this GCC configuration, removing forced inline is a net win: text 
size is 
   smaller, and the deepest observed non-floating-point paths are also below 
the    
   previous 424-byte vsprintf_internal frame.                                   
    
                                                                                
    
   I updated the PR to drop inline_function from these helpers. Other           
    
   configurations, especially floating-point / locale / numbered-args builds, 
may   
   still have different call chains, so I am happy to re-check additional 
configs   
   if needed.                                                                   
    
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to