help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

why unnecessary variable initialization is good with gcc -O3 and bad wit


From: sh . vipin
Subject: why unnecessary variable initialization is good with gcc -O3 and bad with just gcc
Date: Fri, 1 Aug 2008 20:34:58 -0700 (PDT)
User-agent: G2/1.0

Below is a piece of fully compilable bit manipulation code. Let's say
we have two versions of the same code
1. variable "b" in "eval_output_out" is initialized
2. variable "b" in "eval_output_out" is NOT initialized

Code expands such that it is independent of past value of variable
"b", i dumped pre processed output of two versions and there was just
one difference of b initialized in one and not in other.

QUERY IS : why version 1 runs faster than 2 with -O3 option of gcc.

if i just dump the assembly of two versions using "gcc -S" (i.e.
without any optimization) then behavior is expected which is version
#1 (with initialization) has one extra instruction to initialize
variable.

But when i dump the assembly of two versions with "gcc -O3 -S"
assembly of version 2 (without initialization) takes 4 extra
instruction.

Can somebody please explain me why the unnecessary variable
initialization with "0" is good in -O3 option. Though macros never
check the previous value of variables to be "0" or any other value.

I have attached the fully compilable source code and assembly of the
code with two version

ASSEMBLY OF VERSION #1 [ WITH INITIALIZATION]
------------------------------------------------
.globl eval_output_out
        .type   eval_output_out,@function
eval_output_out:
        pushl   %ebp
        movl    width_masks+4, %edx
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        movl    %edx, %ecx
        notl    %edx
        andl    4(%eax), %edx
        andl    (%eax), %ecx
        movl    %edx, 4(%eax)
        sall    $2, %ecx
        andl    width_masks+4, %ecx
        orl     %ecx, %edx
        movl    %edx, 4(%eax)
        leave
        ret


ASSEMBLY OF VERSION #2 [ WITH INITIALIZATION]
------------------------------------------------
.globl eval_output_out
        .type   eval_output_out,@function
eval_output_out:
        movl    width_masks+4, %edx
        pushl   %ebp
        leal    0(,%edx,4), %eax
        movl    %esp, %ebp
        notl    %eax
        pushl   %ebx
        movl    8(%ebp), %ecx
        andl    %eax, %ebx
        movl    %edx, %eax
        andl    (%ecx), %eax
        notl    %edx
        andl    4(%ecx), %edx
        sall    $2, %eax
        movl    %edx, 4(%ecx)
        orl     %eax, %ebx
        andl    width_masks+4, %ebx
        orl     %ebx, %edx
        movl    %edx, 4(%ecx)
        movl    (%esp), %ebx
        leave
        ret

SOURCE CODE
------------------------------------


/* Width Masks*/
static unsigned int WM[32] =
{0x1,0x3,0x7,0xF,0x1F,0x3F,0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF,0x1FFF,
0x3FFF,0x7FFF,0xFFFF,0x1FFFF,0x3FFFF,0x7FFFF,0xFFFFF,0x1FFFFF,0x3FFFFF,
0x7FFFFF,0xFFFFFF,0x1FFFFFF,0x3
FFFFFF,0x7FFFFFF,0xFFFFFFF,0x1FFFFFFF,0x3FFFFFFF,0x7FFFFFFF,
0xFFFFFFFF};


typedef struct _top_test_model{
        unsigned int inputs[1];
        unsigned int outputs[1];
}top_test_model;

/* Logical Right Shift*/
#define LRS(x,y)        ( ((y)>=32)? 0x0: (x)>>(y) )

/* NAMING CONVENTION OF MACRO PARAMETERS
 *   iarr - integer array
 *   idx - index in array of integers
 *   sbp - starting bit position in variable to which operation is
applied
 *   bc - bit count, number of bits to be operated upon
 *   WM - common purpose width mask array defined above
*/


/* get value of "bc" bits starting from bit position "sbp" in variable
"i". variable "i" remains unchanged */
#define get_var_bits(i, sbp, bc) (LRS(((WM[bc-1] << (sbp)) & (i)),
(sbp)))

/* reset "bc" bits in variable "i" starting from bit position "sbp" */
#define rst_bits(i, sbp, bc)    ((i) &= ~(WM[bc-1] << (sbp)))

/* set "bc" bits from variable "val" in variable "i" starting from bit
position "sbp" */
#define set_var_bits(i, sbp, bc, val)   (i = (rst_bits(i, sbp, bc)) |
((val) << (sbp)))


/* same as macros above except that work upon "iaar[idx]" in stead of
variable "i" */
#define get_arr_var_bits(iarr, idx, sbp, bc)    (LRS(((WM[bc-1] << sbp)
& iarr[idx]),(sbp)))
#define rst_arr_var_bits(iarr, idx, sbp, bc)    (iarr[idx] &= ~(WM[bc-1]
<< (sbp)))
#define set_arr_var_bits(iarr, idx, sbp, bc, val)  (iarr[idx] =
rst_arr_var_bits(iarr, idx, sbp, bc) | ((val) << (sbp)))

void eval_output_out(top_test_model *model){
        unsigned int b=0;

        set_var_bits(b,2,2,get_arr_var_bits(model->inputs,0,0,2));
        set_arr_var_bits(model->outputs,0,0,2,get_var_bits(b,0,2));
}


int main (int argc, char *argv){
        top_test_model t;
        eval_output_out(&t);
}

-vipin




reply via email to

[Prev in Thread] Current Thread [Next in Thread]