with Instrument;
use Instrument;

----------------
-- Load Elimination
----------------

--  This test evaluates a code  improvement  potential  that  results
--  from  the  elimination of operations that load expression operand
--  values when the opportunity is offered to propagate their values.

--  The optimized  test  procedure  evaluates  two  expressions  that
--  redefine  Global_1  and  Global_2.   Global_1  and  Global_2  are
--  immediately  used  as  operands  in  expressions  that   redefine
--  Global_4 and Global_5 thereby allowing the values of Global_1 and
--  Global_2 to be propagated rather than explicitly loaded prior  to
--  expression evaluation.

--  The nonoptimized test  procedure  inhibits  the  optimization  by
--  introducing  a  call  to  a  procedure  in  the  basic block that
--  necessitates that the expression operands be loaded from Global_1
--  and   Global_2  since  their  values  can  no  longer  be  safely
--  propagated.

procedure Oplea2 is

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

    Global_1 : T;
    Global_2 : T;
    Global_3 : T;
    Global_4 : T;
    Global_5 : T;

    procedure Break_Basic_Block is
    begin
        Let (Global_1, Ident (Init / Init));
        Let (Global_2, Ident (Init / Init));
        Let (Global_3, Ident (Init / Init));
        Let (Global_4, Ident (Init / Init));
        Let (Global_5, Ident (Init / Init));
    end Break_Basic_Block;

begin

    Start ("OPLEA2", "Optimization Perf., Load Elim. (test)");
    for I in 1 .. 1000 loop

        Let (Global_1, Ident (Init / Init));
        Let (Global_2, Ident (Init / Init));
        Let (Global_3, Ident (Init / Init));
        Let (Global_4, Ident (Init / Init));
        Let (Global_5, Ident (Init / Init));

        Global_1 := Global_4 + Global_5;
        Global_2 := Global_4 - Global_5;

        --  Break_Basic_Block;         -- included in control version

        Global_4 := Global_1 - Global_3;
        Global_5 := Global_2 + Global_3;

        Break_Basic_Block;         -- included in test version

        Let (Global_1, Ident (Init / Init));
        Let (Global_2, Ident (Init / Init));
        Let (Global_3, Ident (Init / Init));
        Let (Global_4, Ident (Init / Init));
        Let (Global_5, Ident (Init / Init));

    end loop;
    Stop;

end Oplea2;