PreviousUpNext

15.4.397  src/lib/compiler/back/low/tools/arch/adl-gen-ssaprops.pkg

## adl-gen-ssaprops.pkg -- derived from ~/src/sml/nj/smlnj-110.60/MLRISC/Tools/ADL/mdl-gen-ssaprops.sml
#
# Generate the <architecture>SSAProps generic.
# This package extracts semantics and dependence 
# information about the instruction set needed for SSA optimizations.

# Compiled by:
#     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-packages.lib



###                 "Common sense is genius in homespun."
###
###                             -- Alfred North Whitehead



stipulate
    package ard =  architecture_description;                            # architecture_description                              is from   src/lib/compiler/back/low/tools/arch/architecture-description.pkg
    package err =  adl_error;                                           # adl_error                                             is from   src/lib/compiler/back/low/tools/line-number-db/adl-error.pkg
    package smj =  sourcecode_making_junk;                              # sourcecode_making_junk                                is from   src/lib/compiler/back/low/tools/arch/sourcecode-making-junk.pkg
#   package mst =  adl_symboltable;                                     # adl_symboltable                                       is from   src/lib/compiler/back/low/tools/arch/adl-symboltable.pkg
    package raw =  adl_raw_syntax_form;                                 # adl_raw_syntax_form                                   is from   src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-form.pkg
    package rkj =  registerkinds_junk;                                  # registerkinds_junk                                    is from   src/lib/compiler/back/low/code/registerkinds-junk.pkg
    package rsj =  adl_raw_syntax_junk;                                 # adl_raw_syntax_junk                                   is from   src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-junk.pkg
    package rst =  adl_raw_syntax_translation;                          # adl_raw_syntax_translation                            is from   src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-translation.pkg
herein

    # This generic is invoked (only) in:
    #
    #     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-pwrpc32.pkg
    #     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-intel32.pkg
    #     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-sparc32.pkg
    #     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-packages.pkg
    #
    generic package   adl_gen_ssa_props   (
        #             =================
        #
        arc:  Adl_Rtl_Comp                                              # Adl_Rtl_Comp                                          is from   src/lib/compiler/back/low/tools/arch/adl-rtl-comp.api
    )
    : (weak)   Adl_Gen_Module2                                          # Adl_Gen_Module2                                       is from   src/lib/compiler/back/low/tools/arch/adl-gen-module2.api
    {
        # Export to client packages:
        #
        package arc = arc;                                              # "arc" == "adl_rtl_compiler".

        stipulate
            package rtl =  arc::rtl;                                    # "rtl" == "register transfer language".
            package tcf =  rtl::tcf;                                    # "tcf" == "treecode_form".
#           package lct =  arc::lct;                                    # "lct" == "lowhalf_types".
            #
            nonfix my in ;
            #
            include package   rsj;
            include package   err;
        herein

              #  Insert copies 

            fun copy_funs has_impl
                = 
                {   my (impl_init, impl_pattern, impl_copy)
                        = 
                        if has_impl   ("impl=REF NULL, ", "impl, ", "impl=impl, ");
                        else      ("", "", "");
                        fi;

                    raw::VERBATIM_CODE  [ "fun copies fps =",
                            "stipulate fun f ([], id, is, fd, fs) = (id, is, fd, fs)",
                            "      | f( { dst, src } . fps, id, is, fd, fs) =",
                            "        if rkj::codetemps_are_same_color (dst, src) then f (fps, id, is, fd, fs)",
                            "        else case rkj::registerkind_of dst of",
                            "             rkj::GP   => f (fps, dst . id, src . is, fd, fs)",
                            "          |  rkj::FP   => f (fps, id, is, dst . fd, src . fs)",
                            "          |  rkj::MEM  => f (fps, id, is, fd, fs)",
                            "          |  rkj::CTRL => f (fps, id, is, fd, fs)",
                            "          |  kind   => error(\"copies: \"$rkj::name_of_registerkind kind$",
                            "                             \" dst=\"$rkj::register_to_string dst$",
                            "                             \" src=\"$rkj::register_to_string src)",
                            " my (id, is, fd, fs) = f (fps,[],[],[],[])",
                            " icopy = case id of",
                            "               []  => []",
                            "             | [_] => [i::COPY { src=is, dst=id, " + impl_init + "tmp=NULL } ]",
                            "             | _   => [i::COPY { src=is, dst=id, " + impl_init,
                            "                              tmp=THE (i::DIRECT (rkj::make_reg())) } ]",
                            " fcopy = case fd of",
                            "               []  => []",
                            "             | [_] => [i::FCOPY { src=fs, dst=fd, " + impl_init + "tmp=NULL } ]",
                            "             | _   => [i::FCOPY { src=fs, dst=fd, " + impl_init,
                            "                               tmp=THE (i::FDIRECT (rkj::new_freg())) } ]",
                            "herein icopy @ fcopy end"
                          ];
                };

            # Expressions building utilities 
            #
            fun consexp (x, raw::LIST_IN_EXPRESSION (a, b)) =>  raw::LIST_IN_EXPRESSION (x ! a, b);
                consexp (x,                   y) =>  raw::LIST_IN_EXPRESSION([x], THE y);
            end;

            nilexp =  raw::LIST_IN_EXPRESSION ([], NULL);

            fun conspat (x, raw::LISTPAT (a, b)) =>  raw::LISTPAT (x ! a, b);
                conspat (x, y)                   =>  raw::LISTPAT ([x], THE y);
            end;

            nilpat =  raw::LISTPAT ([], NULL);

            fun gen compiled_rtls
                =
                smj::write_sourcecode_file
                  {
                    architecture_description,
                    created_by_package =>  "src/lib/compiler/back/low/tools/arch/adl-gen-ssaprops.pkg",
                    #
                    subdir        =>  "static-single-assignment",                                                                               # Relative to file containing architecture description.
                    make_filename =>  \\ architecture_name = sprintf "SSAProps-%s.pkg" architecture_name,                                       # architecture_name can be "pwrpc32" | "sparc32" | "intel32".
                    code          =>  [ smj::make_generic
                                            architecture_description
                                            (\\ architecture_name = sprintf "ssa_props_%s_g" architecture_name)
                                            args
                                            smj::STRONG_SEAL
                                            sig_name
                                            str_body
                                      ]                                 # (map rst::simplify_declaration str_body)
                  }
                where

                    architecture_description = arc::architecture_description_of  compiled_rtls;

                    # Name of the package/api:
                    #
                    str_name =  smj::make_package_name  architecture_description  "SSAProps";
                    sig_name =  "LOWHALF_SSA_PROPERTIES";

                    make_query =  arc::make_query  compiled_rtls;                                                                       # Query function.

                    fun in  x =  "in_"  + x;
                    fun out x =  "out_" + x;


                    # Function for extracting naming constraints from an RTL:
                    #
                    naming_constraints
                        =
                        make_query
                          { name            =>  "namingConstraints",   
                            named_arguments =>  TRUE,
                            args            =>  [ ["instruction", "src", "dst" ] ],
                            case_args       =>  ["dst_list", "src_list"],
                            decls           =>  decls,
                            body            =>  body
                          }
                        where
                            fun body { instruction, rtl, const }
                                =
                                { expression =>  raw::LIST_IN_EXPRESSION (c, NULL),
                                  case_pats  =>  [d, u]
                                }
                                where
                                    fun ignore p
                                        =
                                        conspat (raw::WILDCARD_PATTERN, p);

                                    fun cell (k, r)
                                        = 
                                        const
                                          (
                                            raw::APPLY_EXPRESSION
                                              ( raw::APPLY_EXPRESSION
                                                  ( raw::ID_IN_EXPRESSION (raw::IDENT (["C"], "Reg")),
                                                    raw::ID_IN_EXPRESSION (raw::IDENT (["C"], rkj::name_of_registerkind k))
                                                  ),
                                                integer_constant_in_expression (multiword_int::to_int r)
                                              )
                                          );

                                    fun add_src (id, r, (d, u, c))
                                        = 
                                        ( d,
                                          conspat (raw::IDPAT (in id), u),
                                          rsj::app ("USE", raw::RECORD_IN_EXPRESSION [("var", rsj::id (in id)), ("color", r)]) ! c
                                        );

                                    fun add_dst (id, r, (d, u, c))
                                        = 
                                        ( conspat (raw::IDPAT (out id), d),
                                          u,
                                          rsj::app ("DEF", raw::RECORD_IN_EXPRESSION [("var", rsj::id (out id)), ("color", r)]) ! c
                                        );

                                    fun add_dst_src (id, (d, u, c))
                                        = 
                                        ( conspat (raw::IDPAT (out id), d),
                                          conspat (raw::IDPAT (in id), u),
                                          rsj::app ("SAME", raw::RECORD_IN_EXPRESSION [("x", rsj::id (out id)), ("y", rsj::id (in id))]) ! c
                                        );

                                    fun ignore_use (d, u, c)
                                        =
                                        (d, conspat (raw::WILDCARD_PATTERN, u), c);

                                    fun ignore_def (d, u, c)
                                        =
                                        (conspat (raw::WILDCARD_PATTERN, d), u, c);

                                    fun f (id, type, tcf::ATATAT(_, k, tcf::LITERAL r), rtl::IN  _, x) =>   add_src (id, cell (k, r), x);
                                        f (id, type, tcf::ATATAT(_, k, tcf::LITERAL r), rtl::OUT _, x) =>   add_dst (id, cell (k, r), x);
                                        #
                                        f (id, type, _, rtl::IO _,  x) =>  add_dst_src (id, x);
                                        f (id, type, _, rtl::IN _,  x) =>  ignore_use x;
                                        f (id, type, _, rtl::OUT _, x) =>  ignore_def x;
                                    end;

                                    fun g (id, type, x)
                                        =
                                        x;

                                    my (d, u, c)
                                        = 
                                        arc::forall_args
                                          {  instruction,  rtl,  rtl_arg =>f,  non_rtl_arg =>g }
                                          (nilpat, nilpat, []);
                                end;

                            decls = [ arc::complex_error_handler "namingConstraints",
                                      raw::VERBATIM_CODE [ "dst_list = dst and src_list = src" ]
                                    ];
                        end;                                                            # naming_constraints

                    # Function for rewriting the operands of a
                    # register transfer level expression ("rtl"):
                    #
                    substitute_operands
                        =
                        make_query
                          { name            =>  "substituteOperands",
                            named_arguments =>  TRUE,
                            args            =>  [["const"],["instruction", "dst", "src"]],
                            case_args        =>  ["dst_list", "src_list"],
                            decls           =>  decls,
                            body            =>  body
                          }
                        where
                            fun body { instruction, rtl, const }
                                = 
                                { expression,   case_pats => [d, u] }
                                where
                                    fun ignore p
                                        =
                                        conspat (raw::WILDCARD_PATTERN, p);

                                    fun add (rtl::IN _,  x, d, u) =>  (d, conspat (raw::IDPAT (in x), u));
                                        add (rtl::OUT _, x, d, u) =>     (conspat (raw::IDPAT (out x), d), u);
                                        add (rtl::IO _,  x, d, u) =>     (conspat (raw::IDPAT (out x), d), ignore u);
                                    end;

                                    fun nochange (d, u)
                                        =
                                        ( ignore d,
                                          ignore u
                                        );

                                    fun f (id, type, tcf::ATATAT(_, k, tcf::LITERAL r), pos, (d, u)) =>  nochange (d, u);
                                        f (id, type, expression,                    pos, (d, u)) =>  add (pos, id, d, u);
                                    end;

                                    fun g (id, type, (d, u))
                                        =
                                        ( ignore d,
                                          ignore u
                                        );

                                    fun arg (tcf::ATATAT (_, k, _), name)
                                            =>
                                            if (rkj::name_of_registerkind k == "REGISTERSET")   NULL;
                                            else                                                THE (rsj::id name);
                                            fi;

                                        arg (tcf::ARG _, name)
                                            =>
                                            THE (rsj::app ("get_operand", rsj::id name));

                                        arg _ =>   raise exception DIE "Bug: Unsupported case in gen/body/arg";
                                    end;

                                    fun f' (id, type, tcf::ATATAT(_, k, tcf::LITERAL r), pos       ) =>  NULL;
                                        f' (id, type, expression,                    rtl::IN _ ) =>  arg (expression, in id);
                                        f' (id, type, expression,                    rtl::OUT _) =>  arg (expression, out id);
                                        f' (id, type, expression,                    rtl::IO _ ) =>  arg (expression, out id);
                                    end;

                                    fun g' _ =   NULL;

                                    my (d, u)
                                        =
                                        arc::forall_args
                                            { instruction, rtl, rtl_arg=>f, non_rtl_arg=>g }
                                            (nilpat, nilpat);

                                    expression
                                        =
                                        arc::map_instr { instruction, rtl, rtl_arg=>f', non_rtl_arg=>g' };
                                end;

                            decls = [ arc::complex_error_handler "substituteOperands",
                                       raw::VERBATIM_CODE [ "fun get_operand x = error \"get_operand\"",
                                             "dst_list = dst and src_list = src"
                                           ]
                                    ];
                        end;

                    # Arguments to the instruction generic:
                    #
                    args =
                      [ "package instruction:  " + smj::make_api_name architecture_description "INSTR",
                        "package region_props:  REGION_PROPERTIES ",
                        "package gc_rtl_props:  RTL_PROPERTIES where I = Instr",
                        "package machcode_universals:  Machcode_Universals where I = Instr",
                        "package asm_emitter:  Machcode_Codebuffer where I = Instr", 
                        "package operand_table:  OPERAND_TABLE where I = Instr",
                        "  sharing RegionProps::Region = Instr::Region",
                        "my volatile:      Instr::C.cell List",
                        "my pinnedDef:     Instr::C.cell List",
                        "my pinnedUse:     Instr::C.cell List",
                        "my globalDef:  Instr::C.cell List",
                        "my globalUse:  Instr::C.cell List"
                      ];

                    # The generic:
                    #
                    str_body
                        = 
                        [ raw::VERBATIM_CODE [ "package i         = Instr",
                                "package c         = i::C",
                                "package gc_rtl_props  = RTLProps",
                                "package machcode_universals = machcode_universals",
                                "package rtl       = RTLProps::RTL",
                                "package t         = RTL::T",
                                "package ot        = OperandTable",
                                "package rp        = RegionProps",
                                "",
                                "enum const = enum ot::const",
                                "enum constraint =",
                                "  DEF  of { var: rkj::cell, color: rkj::cell }",
                                "| USE  of { var: rkj::cell, color: rkj::cell }",
                                "| SAME of { x: rkj::cell, y: rkj::cell }",
                                ""
                              ],

                          smj::error_handler architecture_description (\\ architecture_name = "SSAProps"),

                          arc::complex_error_handler_def (),

                          raw::VERBATIM_CODE [ "",
                                "volatile = volatile",
                                "globalDef = globalDef",
                                "globalUse = globalUse",
                                "pinnedDef  = pinnedDef",
                                "pinnedUse  = pinnedUse",
                                "source = i::SOURCE {}",
                                "sink   = i::SINK {}",
                                "phi    = i::PHI {}",
                                ""
                              ],
                          naming_constraints,
                          substitute_operands,
                          copy_funs  (ard::has_copy_impl  architecture_description),
                          ard::decl_of architecture_description "SSA"
                        ];
                end;
        end;                                                                            # stipulate
    };                                                                                  # generic package   adl_gen_ssa_props
end;                                                                                    # stipulate




Comments and suggestions to: bugs@mythryl.org

PreviousUpNext