PreviousUpNext

15.4.438  src/lib/compiler/back/low/treecode/operand-table-g.pkg

## operand-table-g.pkg -- derived from  ~/src/sml/nj/smlnj-110.58/new/new/src/MLRISC/mltree/operand-table.sml
#
# A table for storing operands for a compilation unit.
# We give each distinct operand a unique (negative) value number.

# Compiled by:
#     src/lib/compiler/back/low/lib/rtl.lib



#DO set_control "compiler::trap_int_overflow" "TRUE";

stipulate
    package rkj =  registerkinds_junk;                                                  # registerkinds_junk            is from   src/lib/compiler/back/low/code/registerkinds-junk.pkg
    package iht =  int_hashtable;                                                       # int_hashtable                 is from   src/lib/src/int-hashtable.pkg
    package  ht =  hashtable;                                                           # hashtable                     is from   src/lib/src/hashtable.pkg
herein

    # This generic is nowhere invoked, but see the "operand_table" refs in:
    #
    #     src/lib/compiler/back/low/tools/arch/adl-gen-ssaprops.pkg:                    "package operand_table:  OPERAND_TABLE where I = Instr",
    #     src/lib/compiler/back/low/tools/arch/adl-gen-rtlprops.pkg:                    "package operand_table:  OPERAND_TABLE where I = Instr",
    #
    generic package   operand_table_g  (                                                # Nowhere invoked. _g added.
        #             ===============
        #
        mu:  Machcode_Universals                                                        # Machcode_Universals           is from   src/lib/compiler/back/low/code/machcode-universals.api
    )
    : (weak)   Operand_Table
    {
        # Exported to client packages:
        #
        package mcf = mu::mcf;

        Value_Number = rkj::Codetemp_Info;

        Const
          = INT      Int                        # Small integer operands.
          | INTEGER  multiword_int::Int # Large integer operands.
          | OPERAND  mcf::Operand               # Other operand.
          ;

        package integer_map
            =
            red_black_map_g (
                #
                Key = multiword_int::Int;
                #       
                compare = multiword_int::compare;
            );

        Operand_Table
            =
            TABLE
              {  int_table:             iht::Hashtable( Value_Number ),
                 mi_table:              Ref(  integer_map::Map( Value_Number ) ),
                 operand_table:         ht::Hashtable( mcf::Operand, Value_Number ),
                 next_value_number: Ref( Int )
              };

        Value_Number_Methods
            =
            VALUE_NUMBERING
              { int:            Int                 -> Value_Number,
                unt:            Unt                 -> Value_Number,
                #
                one_word_int:   one_word_int::Int   -> Value_Number,
                one_word_unt:   one_word_unt::Unt   -> Value_Number,
                #
                integer:        multiword_int::Int  -> Value_Number,
                operand:        mcf::Operand        -> Value_Number
              };

        exception NO_OPERAND;
        exception NO_CONST;
        exception NO_INT;
        exception NO_MULTIWORD_INT;

        gp =  mcf::rgk::info_for_registerkind  rkj::INT_REGISTER;                               # info_for_registerkind         def in    src/lib/compiler/back/low/code/registerkinds-g.pkg

        exception CONST Const;

        fun make_const (vn, const)
            = 
            rkj::CODETEMP_INFO
              { id      =>  vn,
                notes   =>  REF [CONST const],
                color   =>  REF rkj::CODETEMP,
                kind    =>  gp
              };

        bot      = rkj::CODETEMP_INFO { id=> -9999999, notes=>REF [], color=>REF rkj::CODETEMP, kind=>gp };
        top      = rkj::CODETEMP_INFO { id=> -9999998, notes=>REF [], color=>REF rkj::CODETEMP, kind=>gp };
        volatile = rkj::CODETEMP_INFO { id=> -9999997, notes=>REF [], color=>REF rkj::CODETEMP, kind=>gp };

        fun create  next_value_number
            =
            {   operand_table =   ht::make_hashtable (mu::hash_operand, mu::eq_operand) { size_hint => 32, not_found_exception => NO_OPERAND };
                int_table     =  iht::make_hashtable                                    { size_hint => 32, not_found_exception => NO_INT     };
                mi_table      =   REF integer_map::empty;

                fun make_int i
                    =
                    {   vn =   *next_value_number;                      #  value number 
                        #
                        next_value_number := vn - 1;

                        v  = make_const (vn, INT i);

                        iht::set int_table (i, v);
                    };

                fun init (n, 0) =>  ();
                    init (n, m) =>  { make_int n;  init (n+1, m - 1);  };
                end;

                init (0, 2);

                TABLE {  int_table,  mi_table, operand_table, next_value_number  };
            };

#       fun unt_to_multiword_int            u =  multiword_int::from_int (unt::to_int_x  u);
        fun one_word_unt_to_multiword_int   u =  one_word_unt::to_multiword_int_x   u;
        #
        fun unt_to_int                      u =  unt::to_int_x                      u;
        fun one_word_unt_to_int             u =  one_word_unt::to_int_x             u;
        #
        fun multiword_int_to_int            i =  multiword_int::to_int              i;
        fun multiword_int_to_one_word_int   i =  one_word_int::from_multiword_int   i;
        fun int_to_multiword_int            i =  multiword_int::from_int            i;
        #
        fun int_to_one_word_int             i  =  one_word_int::from_int            i;
        fun one_word_int_to_multiword_int   i  =  one_word_int::to_multiword_int    i;
        fun one_word_int_to_int             i  =  one_word_int::to_int              i;

        #  Look up the value number of a constant 

        fun int (TABLE { int_table, ... } )
            =
            iht::get int_table;

        fun unt (TABLE { int_table, ... } ) w
            =
            iht::get int_table (unt_to_int w);

        fun one_word_unt (TABLE { int_table, mi_table, ... } ) w 
            = 
            iht::get  int_table  (one_word_unt_to_int  w)
            except
                OVERFLOW
                    =
                    case (integer_map::get (*mi_table, one_word_unt_to_multiword_int w))
                        #
                        THE v =>   v;
                        NULL  =>   raise exception NO_MULTIWORD_INT;
                    esac;

        fun one_word_int (TABLE { int_table, mi_table, ... } ) w
            = 
            iht::get  int_table  (one_word_int_to_int  w)
            except
                OVERFLOW
                    =
                    case (integer_map::get (*mi_table, one_word_int_to_multiword_int w))
                        #
                        THE v =>   v;
                        NULL  =>   raise exception NO_MULTIWORD_INT;
                    esac;

        fun integer (TABLE { int_table, mi_table, ... } ) i
            = 
            iht::get int_table (multiword_int_to_int i)
            except
                OVERFLOW
                    =
                    case (integer_map::get (*mi_table, i))
                        #
                        THE v =>  v;
                        NULL  =>  raise exception NO_MULTIWORD_INT;
                    esac;

        fun operand (TABLE { operand_table, ... } )
            =
            ht::look_up  operand_table;

        fun lookup_value_numbers table
            =
            VALUE_NUMBERING
              { int     =>  int     table,
                unt     =>  unt     table,
                one_word_unt   =>  one_word_unt   table,
                one_word_int   =>  one_word_int   table,
                integer  =>  integer  table,
                operand =>  operand table
              };

        # Create new value numbers:
        #
        fun make_new_value_numbers
              #
              (TABLE { operand_table, next_value_number, int_table, mi_table, ... } )
            =
            {   find_operand   =   ht::find   operand_table;
                find_int   =  iht::find   int_table;
                #
                insert_operand =   ht::set  operand_table;
                insert_int =  iht::set  int_table;

                fun new_const  const
                    = 
                    {   vn =   *next_value_number;
                        #
                        next_value_number :=  vn - 1;
                        #
                        make_const (vn, const);
                    };

                fun make_operand  operand
                    = 
                    case (find_operand  operand)
                        #
                        THE v =>    v;
                        NULL  =>    {   v =  new_const (OPERAND operand);
                                        insert_operand (operand, v);
                                        v;
                                    };
                    esac;

                fun make_int  i
                    =
                    case (find_int i)
                        #
                        THE v =>    v;
                        #
                        NULL  =>    {   v =   new_const (INT i);
                                        insert_int (i, v);
                                        v;
                                    };
                    esac;

                fun insert_multiword_int (i, v)
                    =
                    mi_table :=   integer_map::set (*mi_table, i, v);

                fun make_multiword_int' i
                    =
                    case (integer_map::get (*mi_table, i))
                        #
                        THE v =>    v;
                        #
                        NULL  =>    {   v =   new_const (INTEGER i);
                                        insert_multiword_int (i, v);
                                        v;
                                    };
                    esac;

                fun make_multiword_int i
                    =
                    make_int (multiword_int_to_int i)
                    except
                        _ = make_multiword_int'  i;

                fun make_unt w
                    =
                    make_int (unt_to_int w);

                fun make_one_word_int i
                    =
                    make_int (one_word_int_to_int i)
                    except
                        _ =  make_multiword_int' (one_word_int_to_multiword_int  i);

                fun make_one_word_unt w
                    =
                    make_int (one_word_unt_to_int w)
                    except
                        _ = make_multiword_int' (one_word_unt_to_multiword_int w);

                VALUE_NUMBERING
                  {
                    int             =>  make_int,
                    unt             =>  make_unt,
                    #
                    one_word_unt    =>  make_one_word_unt,
                    one_word_int    =>  make_one_word_int,
                    #
                    integer         =>  make_multiword_int,
                    operand         =>  make_operand
                  };
            };                                                  # fun make_new_value_numbers

        # value number -> const 

        fun const (rkj::CODETEMP_INFO { notes, ... } )
            = 
            find *notes
            where
                fun find (CONST c ! _) =>   c;
                    find(_ ! an)       =>   find an;
                    find []            =>   raise exception NO_CONST;
                end;
            end;
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext