## 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.pkgherein
# 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;