with Instrument;
use Instrument;

---------------
-- Boolean Folding
---------------

--  This test evaluates a code  improvement  potential  that  results
--  from  the elimination of code when the opportunity is provided to
--  perform compile-time evaluation of conditional expressions.  This
--  is   the   standard   Ada   facility  for  achieving  conditional
--  compilation.

--  The test procedures consist of a conditional statement  enclosing
--  a   camouflaged  redefinition  of  global  information.   In  the
--  optimized test procedure the if conditional  expression  consists
--  of  constant  operands,  while in the nonoptimized test procedure
--  the  operands  consist  of  global  variables  and  a   constant.
--  Consequently,   the   compile-time  evaluation  of  the  constant
--  conditional expression should result in a difference in both  the
--  size   and  execution  time  of  the  two  procedures  since  the
--  conditional  statement  can  be   eliminated   except   for   the
--  redefinition of Global_1.  In the nonoptimized test procedure the
--  evaluation of the elsif conditional expression may  be  performed
--  at  compile-time  but  will  not result in the elimination of the
--  conditional statement.  Camouflaged  redefinitions  of  different
--  global   variables   are   used   to   prevent  other  unexpected
--  optimizations that would invalidate the benchmark.

--  If there are no differences in the execution time and  space  for
--  the   two   procedures,  the  optimization  opportunity  was  not
--  recognized by the compiler.

procedure Opbfa1 is

    package New_Procs is new Procs (Boolean);
    use New_Procs;

    Constant_1 : constant T := Init;
    Constant_2 : constant T := Init;

    Global_1 : T;
    Global_2 : T;

begin

    Start ("OPBFA1", "Optimization Perf., Bool. Folding (control)");
    for I in 1 .. 1000 loop

        Let (Global_1, Ident (Init));
        Let (Global_2, Ident (Init));

        ------------------optimize-------------
        if
--      Constant_1 = Init and Constant_2 = Init         -- inc. in test ver.
           Constant_1 = Global_1 and
           Constant_2 = Global_2 -- inc. in control ver.
            then

            Let (Global_1, Ident (Init));

        elsif Global_1 = Init and Global_2 = Init then

            Let (Global_2, Ident (Init));

        end if;

        Let (Global_1, Ident (Init));
        Let (Global_2, Ident (Init));

    end loop;
    Stop;

end Opbfa1;