PreviousUpNext

15.3.151  src/lib/compiler/back/low/regor/register-spilling.api

## 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.pkg
herein

    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;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext