Wild execution of instructions happen when optimization set to high in IAR MSP430 compiler
Please refer to my code below. When optimization in IAR MSP430 compiler is set high, I am having the following issue. Code works fine when optimization is low.
Issue: If the condition statement at (B) returns false, statement (A) is executed instead of statement (C).
int16_t cpu_flash_read_setting (void * setting, const uint8_t offset, const uint8_t num_of_bytes) { int16_t returnable_status = PASS; uint16_t flash_copy_one_address = FLASH_INFO_SEG_C_ADDR + offset; uint16_t flash_copy_two_address = FLASH_INFO_SEG_D_ADDR + offset; if (0U == (num_of_bytes % sizeof(uint16_t))) { uint16_t *setting_copy_one = (uint16_t *) flash_copy_one_address开发者_JAVA百科; uint16_t *setting_copy_two = (uint16_t *) flash_copy_two_address; if (*setting_copy_one == *setting_copy_two) { setting = setting_copy_one; } else { (A) returnable_status = FAIL; } } else if (0U == (num_of_bytes % sizeof(uint8_t))) { uint8_t *setting_copy_one = (uint8_t *) flash_copy_one_address; uint8_t *setting_copy_two = (uint8_t *) flash_copy_two_address; (B) if (*setting_copy_one == *setting_copy_two) { setting = setting_copy_one; } else { (C) returnable_status = FAIL; } } else { /* No Action */ } return returnable_status; }
That looks entirely reasonable to me. When you have optimisation turned up high, the compiler can and usually will re-order statements wildly. Your two main clauses are identical apart from their typing - so it's entirely plausible for the compiler to merge the execution paths and have them differ only where it actually matters.
This is only a problem if the actual observable effect differs from what was intended.
In any event, optimised code is always difficult to follow with a debugger, precisely because of the re-ordering effects.
By the way, if your code is talking to actual hardware you may want to declare the flash_copy_*_address
variables as volatile
. This is a hint to the compiler that the memory they point to doesn't necessarily behave in the normal way, and forces it be more conservative with its optimisations.
The two lines of code A
and C
are identical, and the execution paths merge after those two lines (the next line to be executed in both cases is return returnable_status;
.
Thus the compiler is performing tail-merging optimisation, using the same block of assembly code for both source code lines. This optimisation is expected and perfectly valid, and should not cause a problem.
精彩评论