## register-spilling.api
# Compiled by:
#
src/lib/compiler/back/low/lib/lowhalf.lib# This module manages the spill/reload process.
#
# -- Allen Leung
stipulate
package rkj = registerkinds_junk; # registerkinds_junk is from
src/lib/compiler/back/low/code/registerkinds-junk.pkgherein
api Register_Spilling {
#
package mcf: Machcode_Form; # Machcode_Form is from
src/lib/compiler/back/low/code/machcode-form.api package cig: Codetemp_Interference_Graph # Codetemp_Interference_Graph is from
src/lib/compiler/back/low/regor/codetemp-interference-graph.api = codetemp_interference_graph; # codetemp_interference_graph is from
src/lib/compiler/back/low/regor/codetemp-interference-graph.pkg package rgk: Registerkinds; # Registerkinds is from
src/lib/compiler/back/low/code/registerkinds.api sharing mcf::rgk == rgk; # "rgk" == "registerkinds".
Copy_Instr
=
( (List(rkj::Codetemp_Info), List(rkj::Codetemp_Info)),
mcf::Machine_Op
)
->
List( mcf::Machine_Op );
# Spill the value associated with reg into spill_loc.
# All definitions of instruction should be renamed to a new temporary make_reg.
#
Spill
=
{ instruction: mcf::Machine_Op, # Instruction where spill is to occur
reg: rkj::Codetemp_Info, # Register to spill
spill_loc: cig::Spill_To, # Logical spill location
kill: Bool, # Can we kill the current node?
notes: Ref( note::Notes ) # Annotations
}
->
{ code: List( mcf::Machine_Op ), # instruction + spill code
prohibitions: List( rkj::Codetemp_Info ), # prohibited from future spilling
make_reg: Null_Or( rkj::Codetemp_Info ) # the spilled value is available here
};
# Spill the register src into spill_loc.
# The value is originally from register reg.
Spill_Src
=
{ src: rkj::Codetemp_Info, # Register to spill from
reg: rkj::Codetemp_Info, # The register
spill_loc: cig::Spill_To, # Logical spill location
notes: Ref( note::Notes ) # Annotations
}
->
List( mcf::Machine_Op ); # spill code
# Spill the temporary associated with a copy into spill_loc
#
Spill_Copy_Tmp
=
{ copy: mcf::Machine_Op, # Copy to spill
reg: rkj::Codetemp_Info, # The register
spill_loc: cig::Spill_To, # Logical spill location
notes: Ref( note::Notes ) # Annotations
}
->
mcf::Machine_Op; # Spill code
# Reload the value associated with reg from spill_loc.
# All uses of instruction should be renamed to a new temporary make_reg.
#
Reload
=
{ instruction: mcf::Machine_Op, # Instruction where spill is to occur
reg: rkj::Codetemp_Info, # Register to spill
spill_loc: cig::Spill_To, # Logical spill location
notes: Ref( note::Notes ) # Annotations
}
->
{ code: List( mcf::Machine_Op ), # Instruction + reload code
prohibitions: List( rkj::Codetemp_Info ), # Prohibited from future spilling
make_reg: Null_Or( rkj::Codetemp_Info ) # The reloaded value is here
};
# Rename all uses fromSrc to toSrc
#
Rename_Src
=
{ instruction: mcf::Machine_Op, # Instruction where spill is to occur
from_src: rkj::Codetemp_Info, # Register to rename
to_src: rkj::Codetemp_Info # Register to rename to
}
->
{ code: List( mcf::Machine_Op ), # Renamed instruction
prohibitions: List( rkj::Codetemp_Info ), # Prohibited from future spilling
make_reg: Null_Or( rkj::Codetemp_Info ) # The renamed value is here
};
# Reload the register dst from spill_loc.
# The value is originally from register reg.
#
Reload_Dst
=
{ dst: rkj::Codetemp_Info, # Register to reload to
reg: rkj::Codetemp_Info, # The register
spill_loc: cig::Spill_To, # Logical spill location
notes: Ref( note::Notes ) # Annotations
}
->
List( mcf::Machine_Op ); # Reload code
# The following function rewrites an instruction
# and inserts spill and reload code around it.
#
# The list of spill and reload registers
# may have duplicates.
#
spill_rewrite
:
{ graph: cig::Codetemp_Interference_Graph,
spill: Spill,
spill_src: Spill_Src,
spill_copy_tmp: Spill_Copy_Tmp,
reload: Reload,
reload_dst: Reload_Dst,
rename_src: Rename_Src,
copy_instr: Copy_Instr,
registerkind: rkj::Registerkind,
spill_set: cig::ppt_hashtable::Hashtable( List( rkj::Codetemp_Info ) ),
reload_set: cig::ppt_hashtable::Hashtable( List( rkj::Codetemp_Info ) ),
kill_set: cig::ppt_hashtable::Hashtable( List( rkj::Codetemp_Info ) )
}
->
{ pt: cig::Program_Point, # Starting program pt
notes: Ref( note::Notes ), # Annotations
ops: List( mcf::Machine_Op ) # Instructions to spill
}
->
List( mcf::Machine_Op ); # Instruction sequence after rewriting
# Note that instructions are in reverse order.
};
end;