Possible Optimization of C99 _Bool Initialization with Function Lifetime


01/13/2010:  The version of the Cosmic compiler used was:

--------------------------------
COSMIC STM8 C Compiler
Version: 4.2.10 Date: 07 May 2009
--------------------------------
COSMIC Software STM8 C Cross Compiler V4.2.10 - 07 May 2009 - Win32-F
COSMIC Software STM8 C Parser V4.8.15 - 07 May 2009 - Win32-F
COSMIC Software STM8 Code Generator V4.2.10 - 07 May 2009 - Win32-F
COSMIC Software STM8 Optimizer V4.2.10 - 07 May 2009 - Win32
COSMIC Software STM8 Macro-Assembler V4.5.9 - 06 May 2009 - Win32-F
COSMIC Software Linker V4.7.6 - 07 May 2009 - Win32-F
COSMIC Software Hexa Translator V4.3.14 - 03 Mar 2009 - Win32
COSMIC Software Absolute Listing V4.3.14 - 03 Mar 2009 - Win32
COSMIC Software Librarian V4.3.14 - 03 Mar 2009 - Win32
COSMIC Software Absolute C Listing V4.3.14 - 03 Mar 2009 - Win32
COSMIC Software Object Inspector V4.3.14 - 03 Mar 2009 - Win32
COSMIC Software Print Debug Info V4.3.14 - 03 Mar 2009 - Win32
COSMIC Software ELF/DWARF Converter V4.5.28 - 22 Apr 2009 - Win32

The command-line options used that might affect optimization were:

cxstm8 +modsl0 +debug -pxp -pp -l

The test code used is reproduced below.

volatile unsigned char testvar;
//Convince the compiler that it can't predict the value of this variable.

void testfunc(void)
{
  _Bool b0;
  _Bool b1 = TRUE;
  _Bool b2 = FALSE;
  _Bool b3 = TRUE;
  _Bool b4 = FALSE;
  _Bool b5;

  //The goal of the code below is to prevent the compiler from optimizing.
  if (testvar == 38)
    {
      b0 = TRUE;
      b5 = FALSE;
      b1 = !b2;
      b2 = !b1;
      b3 = !b4;
      b4 = !b3;
    }


  if (testvar == 39)
    {
      b0 = !b0;
      b1 = !b1;
      b2 = !b2;
      b3 = !b3;
      b4 = !b4;
      b5 = !b5;
    }

  if (b0 && b1 && b2 && b3 && b4 && b5)
    testvar++;
}

The assembly-language output of the compiler is reproduced below.

4784                     ; 1035 void testfunc(void)
4784                     ; 1036 {
4785                     switch.text
4786  02e1               _testfunc:
4788  02e1 88            pusha
4789       00000001      OFST:set1
4792                     ; 1038    _Bool b1 = TRUE;
4794  02e2 7b01          ld a,(OFST+0,sp)
4795                     ; 1039    _Bool b2 = FALSE;
4797                     ; 1040    _Bool b3 = TRUE;
4799  02e4 a4fa          and a,#250
4800  02e6 aa0a          or a,#10
4801                     ; 1041    _Bool b4 = FALSE;
4803  02e8 6b01          ld (OFST+0,sp),a
4804                     ; 1045    if (testvar == 38)
4806  02ea c60000        ld a,_testvar
4807  02ed a126          cp a,#38
4808  02ef 2608          jrne L1103
4809                     ; 1047       b0 = TRUE;
4811  02f1 7b01          ld a,(OFST+0,sp)
4812                     ; 1048       b5 = FALSE;
4814                     ; 1049       b1 = !b2;
4816                     ; 1050       b2 = !b1;
4818                     ; 1051       b3 = !b4;
4820  02f3 a4ea          and a,#234
4821  02f5 aa2a          or a,#42
4822                     ; 1052       b4 = !b3;
4824  02f7 6b01          ld (OFST+0,sp),a
4825  02f9               L1103:
4826                     ; 1056    if (testvar == 39)
4828  02f9 c60000        ld a,_testvar
4829  02fc a127          cp a,#39
4830  02fe 2610          jrne L3103
4831                     ; 1058       b0 = !b0;
4833  0300 7b01          ld a,(OFST+0,sp)
4834  0302 a820          xor a,#32
4835                     ; 1059       b1 = !b1;
4837  0304 a808          xor a,#8
4838                     ; 1060       b2 = !b2;
4840  0306 a804          xor a,#4
4841                     ; 1061       b3 = !b3;
4843  0308 a802          xor a,#2
4844                     ; 1062       b4 = !b4;
4846  030a a801          xor a,#1
4847                     ; 1063       b5 = !b5;
4849  030c a810          xor a,#16
4850  030e 6b01          ld (OFST+0,sp),a
4851  0310               L3103:
4852                     ; 1066    if (b0 && b1 && b2 && b3 && b4 && b5)
4854  0310 7b01          ld a,(OFST+0,sp)
4860                     ; 1067       testvar++;
4862  0312 a43f          and a,#63
4863  0314 a13f          cp a,#63
4864  0316 2604          jrne L5103
4865  0318 725c0000      inc _testvar
4866  031c               L5103:
4867                     ; 1068 }
4870  031c 84            pop a
4871  031d 81            ret

My observation in the code above is that the variables are initialized using more instructions than necessary (load, and, or, store).  For variables that are automatic, since the value of uninitialized variables should be undefined, it seems the compiler would probably be within the C standards by simply assigning the value of the byte, i.e. ld a, #10, ld (OFST+0,sp),a.


This web page is maintained by webmaster@dtashley.com.  Sound credit: Star Trek VI: The Undiscovered Country.  This sound is #98, randomly selected from the 76 sounds that are suitable for this page.  A list of all 113 sounds in the database (some unsuitable for this page) can be found here.  Local time on this server (at the time the page was served) is 12:24:49 am on May 21, 2012.