with Instrument;
use Instrument;

---------------
-- Numeric Folding
---------------

--  This test evaluates a code  improvement  potential  that  results
--  from  the elimination of operations to compute an expression when
--  the  opportunity  is  provided  to  perform  the  computation  at
--  compile-time.

--  The test procedures  define  global  and  local  information.   A
--  conditional  statement encloses an optimizable and nonoptimizable
--  redefinition of Global_1 using an expression  consisting  of  two
--  numeric  operands.  In the optimized test procedure the evaluated
--  operands are both constants in the executed statement,  while  in
--  the  nonoptimized  test  procedure  the  evaluated operands are a
--  constant  and  a  local  variable  in  the  executed   statement.
--  Consequently,  no  difference  in  the  size of the procedures is
--  expected but the effect of the  compile-time  evaluation  of  the
--  constant operand expression should be evident from the difference
--  in execution time  for  the  two  procedures.   Camouflaging  the
--  conditional  expression  and  the  executed statements redefining
--  Global_1  prevent  other  unexpected  optimizations  that   would
--  invalidate  the benchmark;  e.g., eliminating the unreachable arm
--  of the conditional statement.

procedure Opnfa1 is

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

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

    Local : T;

begin

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

        Let (Global, Ident (Init));

        Let (Local, Ident (Constant_2));

        if Ident (Init) = Init then

            --------optimize-------
            --    Let(Global, Constant_1 + Constant_2);      -- included in test version
            Let (Global, Constant_1 +
                            Local);           -- included in control version

        else

            Let (Global, Constant_1 + Local);

        end if;

        Let (Global, Ident (Init));

    end loop;
    Stop;

end Opnfa1;