The gcc-arm compiler creates a different object file for the same source file

Using the GCC Compiler for ARM (windows):

arm-none-eabi-gcc.exe (Sourcery CodeBench Lite 2012.09-63) 4.7.2 version

I have another object file created every ~ 5 times, I compiled the same source file.

Optimization level 3 (aggressive) is used, compiler parameters used:

-O3 -mcpu = cortex-a8 -mfpu = neon -mfloat-abi = softfp -fshort-wchar -fshort-enums -funsafe-math-optimizations -mvectorize-with-neon-quad

A dump of different object files (using objdump) shows too many differences in the assembly instructions, the registers and addresses used.

  • Is it normal that the compiler optimizes / compiles the exact same source file in different ways and creates different object files ?! Is this a compiler error?

  • How to avoid this behavior without disabling aggressive optimization?

EDIT: fragment of object fragments:

object_file_dump_A:

0000350 <PreInit>: 350: e3003000 movw r3, #0 354: e3403000 movt r3, #0 358: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} 35c: e1a09000 mov r9, r0 360: e24dd034 sub sp, sp, #52 ; 0x34 /*some identical ASM for both files */ 388: e1a0700b mov r7, fp 38c: e1a0600b mov r6, fp 390: e300a000 movw sl, #0 394: e340a000 movt sl, #0 398: e5911004 ldr r1, [r1, #4] 39c: e8ae0003 stmia lr!, {r0, r1} 

object_file_dump_B:

 00000350 <PreInit>: 350: e3003000 movw r3, #0 354: e3403000 movt r3, #0 358: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr} 35c: e1a08000 mov r8, r0 360: e24dd034 sub sp, sp, #52 ; 0x34 /*some identical ASM for both files */ 388: e1a0700b mov r7, fp 38c: e3009000 movw r9, #0 390: e3409000 movt r9, #0 394: e5911004 ldr r1, [r1, #4] 398: e8ae0003 stmia lr!, {r0, r1} 39c: e5b30010 ldr r0, [r3, #16]! 

EDIT:

source:

 void PreInit(init_T *f_params, results_T *results) { u8 i, j, k, idx; const u8 cr_index[4] = {0, 1, 2, 7}; const u8 minVal[] = {2, 4, 6, 0, 0, 0, 0, 19}; const u8 maxVal[] = {0, 3, 5, 0, 0, 0, 0, 18}; memset(f_params, 0, sizeof(init_T)); _ASSERT(CONF_NUM_X_LIMITS == CST_NbSLi); _ASSERT(CONF_NUM_CRITERIA == CST_NbIdxCriteria); for (i = 0; i < CST_NbSLi; ++i) { f_params->_sli[i].x = s_limits[i]; for (j = 0; j < CST_NbIdxCriteria; ++j) { f_params->_sli[i].criteria[j] = conf_criterias[i][j]; } } /*some code*/ } 
+4
source share
1 answer

As mentioned by others, assembler codes are equivalent. If you look at them carefully, the team

e1a0600b mov r6, fp

It moves fp to r6, but the r6 register is not used later. So, if we look at randomization tactics for register allocation and code generation, the variations are small, and in the second part, the optimization deleted the line.

0
source

Source: https://habr.com/ru/post/1485820/


All Articles