GCC's bacl-end & assemble emission (20)

来源:互联网 发布:如何查看淘宝排名 编辑:程序博客网 时间:2024/04/30 11:03

9.3.11.     Readin DEFINE_RESERVATION pattern

Section 8.1.3Overview of DEFINE_INSN_RESERVATION pattern describes the detail of  DEFINE_RESERVATION pattern. For this patternwe use following example:

 

129  (define_reservation "pentium-firstuvboth""(pentium-load + pentium-firstuv   inpentium.md

130                        + pentium-memory)

131                      |(pentium-firstv,pentium-v,

132                        (pentium-load+pentium-firstv))")

 

This pattern is part of pipe hazards description for construtingDFA-based recognizer, this pattern shouldn’t coexist with define_function_unitin same machine description file.

After treated by init_md_reader_args,above pattern will be loaded into memory as rtx object as following.

t47

figure 47 : example of DEFINE_RESERVATION pattern

Obviously, this primitive form isn’t what we want. gen_reservgenerates more organized ones.

 

2106 void

2107 gen_reserv (rtx def)                                                                            ingenautomata.c

2108 {

2109   decl_t decl;

2110

2111   decl = create_node (sizeof(struct decl));

2112   decl->mode = dm_reserv;

2113   decl->pos = 0;

2114   DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0),decl->pos);

2115   DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));

2116   VLA_PTR_ADD (decls, decl);

2117   num_dfa_decls++;

2118 }

 

DECL_RESERV accesses reserv field of decl.

 

845  struct reserv_decl                                                                                ingenautomata.c

846  {

847   char *name;

848   regexp_t regexp;

849 

850    /* The following fields are defined bychecker.  */

851 

852    /* The following field value is nonzero ifthe unit is used in an

853      regexp. */

854   char reserv_is_used;

855    /* The following field is used to check upcycle in expression

856      definition. */

857   int loop_pass_num;

858  };

 

regexp is designed for regular expression describing the occupation of cpuunits for certain instructions. Refer to 8.1.3 Overview of DEFINE_INSN_RESERVATIONpattern for detail of the regularexpression.

 

990  struct regexp                                                                                      ingenautomata.c

991  {

992    /* What node in theunion? */

993    enum regexp_mode mode;

994   pos_t pos;

995    union

996    {

997      structunit_regexp unit;

998      structreserv_regexp reserv;

999      structnothing_regexp nothing;

1000     structsequence_regexp sequence;

1001     structrepeat_regexp repeat;

1002     structallof_regexp allof;

1003     struct oneof_regexponeof;

1004   } regexp;

1005 };

 

197  typedef struct regexp *regexp_t;                                                           ingenautomata.c

 

This structure is generated by gen_regexp. The regular expression obeysfollowing sytanx:

regexp = regexp "," oneof

       | oneof

oneof = oneof"|" allof

       | allof

allof = allof"+" repeat

      | repeat

repeat = element"*" number

      | element

element = cpu_function_unit_name

        | reservation_name

        | result_name

        | "nothing"

        | "(" regexp")"

gen_regexp forms the regexp object from the expression string in above figure.

 

2094 static regexp_t

2095 gen_regexp (char *str)                                                                        ingenautomata.c

2096 {

2097   reserv_str = str;

2098   return gen_regexp_sequence (str);;

2099 }

 

gen_regexp generates the structure by parsing the expression from top-down. Forour example, the expression is "(pentium-load + pentium-firstuv +pentium-memory) | (pentium-firstv, pentium-v, (pentium-load + pentium-firstv))".

 

2069 static regexp_t

2070 gen_regexp_sequence (char *str)                                                          ingenautomata.c

2071 {

2072   regexp_t sequence;

2073  char **sequence_vect;

2074  int els_num;

2075  int i;

2076

2077   sequence_vect = get_str_vect (str,&els_num, ',', TRUE);

2078   if (els_num > 1)

2079   {

2080     sequence = create_node (sizeof (structregexp)

2081                        + sizeof(regexp_t) * (els_num - 1));

2082     sequence->mode = rm_sequence;

2083     REGEXP_SEQUENCE(sequence)->regexps_num = els_num;

2084     for (i = 0; i < els_num; i++)

2085       REGEXP_SEQUENCE (sequence)->regexps[i]

2086                = gen_regexp_oneof (sequence_vect [i]);

2087     returnsequence;

2088   }

2089   else

2090     return gen_regexp_oneof (str);

 

In regular expression `,' is used for indicating the start of thenext cycle in the units reservation. At line 2077, get_str_vect tries toseparate the regular expression into cycles. Notice that the third parameter ofthe funciton is TRUE, the separation will be done only the left and right parenthesesare balanced. At both sides of “,” maybe the expression of “|”, so gen_regexp_oneofis invoked to handle both sides.

 

2043 static regexp_t

2044 gen_regexp_oneof (char *str)                                                              ingenautomata.c

2045 {

2046   regexp_t oneof;

2047   char **oneof_vect;

2048  int els_num;

2049  int i;

2050

2051   oneof_vect = get_str_vect (str, &els_num,'|', TRUE);

2052   if (oneof_vect == NULL)

2053     fatal ("invalid `%s' in reservation`%s'", str, reserv_str);

2054   if (els_num > 1)

2055   {

2056     oneof = create_node (sizeof (struct regexp)

2057                     + sizeof (regexp_t) *(els_num - 1));

2058     oneof->mode = rm_oneof;

2059     REGEXP_ONEOF (oneof)->regexps_num =els_num;

2060     for (i = 0; i < els_num; i++)

2061       REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);

2062     returnoneof;

2063   }

2064   else

2065     return gen_regexp_allof (str);

2066 }

 

This time get_str_vect tries to split the string by ‘|’.Again the third parameter of get_str_vect is TRUE, so for our example, wecan get oneof_vectat line 2051 with two elements:

"(pentium-load + pentium-firstuv + pentium-memory)"

"(pentium-firstv, pentium-v, (pentium-load + pentium-firstv))"

The second one can’t be split by get_str_vect with “,” because no “,” can be seenwhen “(“ balances “)”.

Above at line 2059, macro REGEXP_ONEOF accesses oneof field of regexp, whichhas definition as following, in which regexps field is a variable array, the size of itdepends on the number of operants of “|” (see line 2056 above).

 

983  struct oneof_regexp                                                                                    ingenautomata.c

984  {

985   int regexps_num;

986   regexp_t regexps [1];

987  };

 

Inside expression of “|”, we may encounter expression of “+”, so weneed gen_regexp_allofto handle the separated fragments.

 

2017 static regexp_t

2018 gen_regexp_allof (char *str)                                                                ingenautomata.c

2019 {

2020   regexp_t allof;

2021   char **allof_vect;

2022   int els_num;

2023   int i;

2024

2025   allof_vect = get_str_vect (str, &els_num,'+', TRUE);

2026   if (allof_vect == NULL)

2027     fatal ("invalid `%s' in reservation`%s'", str, reserv_str);

2028   if (els_num > 1)

2029   {

2030     allof = create_node (sizeof (structregexp)

2031                    + sizeof(regexp_t) * (els_num - 1));

2032     allof->mode = rm_allof;

2033    REGEXP_ALLOF (allof)->regexps_num = els_num;

2034     for (i = 0; i < els_num; i++)

2035       REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);

2036     returnallof;

2037   }

2038   else

2039     return gen_regexp_repeat (str);

2040 }

 

get_str_vect at line 2025 now tries to find out the parts joined by ‘+’, againthe third parameter of it is TRUE, balanced parentheses is wanted.

Now for our example, the regular expression had been split into twoparts. For both parts, get_str_vect failsto do furthersplit. Both them enter gen_regexp_repeat at line 2039.

 

1984 static regexp_t

1985 gen_regexp_repeat (char *str)                                                              ingenautomata.c

1986 {

1987   regexp_t regexp;

1988   regexp_t repeat;

1989   char **repeat_vect;

1990   int els_num;

1991   int i;

1992

1993   repeat_vect = get_str_vect (str,&els_num, '*', TRUE);

1994   if (repeat_vect == NULL)

1995     fatal ("invalid `%s' in reservation`%s'", str, reserv_str);

1996   if(els_num > 1)

1997   {

1998    regexp = gen_regexp_el (repeat_vect [0]);

1999     for (i = 1; i < els_num; i++)

2000     {

2001       repeat = create_node (sizeof (struct regexp));

2002       repeat->mode= rm_repeat;

2003       REGEXP_REPEAT (repeat)->regexp = regexp;

2004       REGEXP_REPEAT (repeat)->repeat_num = atoi(repeat_vect [i]);

2005       if (REGEXP_REPEAT (repeat)->repeat_num<= 1)

2006         fatal ("repetition `%s' <= 1 in reservation `%s'",

2007             str, reserv_str);

2008       regexp = repeat;

2009     }

2010     returnregexp;

2011   }

2012   else

2013     return gen_regexp_el (str);

2014 }

 

Remember that `*' is used for convenience and simply means asequence in which the regular expression are repeated NUMBER times with cycleadvancing. For example, *5 means repeating for 5 times. In our example, bothparts don’t contain ‘*’, they just enter gen_regexp_el at line 2013.

 

1955 static regexp_t

1956 gen_regexp_el (char *str)                                                                    ingenautomata.c

1957 {

1958   regexp_t regexp;

1959  int len;

1960

1961   if (*str == '(')

1962   {

1963     len = strlen (str);

1964     if (str [len - 1] != ')')

1965       fatal ("garbage after ) inreservation `%s'", reserv_str);

1966     str [len - 1] = '/0';

1967     regexp = gen_regexp_sequence (str + 1);

1968   }

1969   else if (strcmp (str, NOTHING_NAME) == 0)

1970   {

1971     regexp = create_node (sizeof (structdecl));

1972     regexp->mode = rm_nothing;

1973   }

1974   else

1975   {

1976     regexp = create_node (sizeof (structdecl));

1977     regexp->mode = rm_unit;

1978     REGEXP_UNIT (regexp)->name = str;

1979   }

1980   returnregexp;

1981 }

 

For our example, both two parts are enclosed by parentheses withinwhich should be regarded as a sequence. So gen_regexp_sequence will be recursed at line1967. In the end the example is transformed to following structure.

t48

figure 48 : example of regexp object generated for define_ reservationpattern

9.3.12.     Read inDEFINE_INSN_RESERVATION pattern

Section 8.1.3Overview of DEFINE_INSN_RESERVATION pattern describes the detail of  DEFINE_INSN_RESERVATION pattern. For thispattern, we use following example.

 

166  (define_insn_reservation"pent_fpmovxf" 3                                            in pentium.md

167   (and (eq_attr "cpu" "pentium")

168        (and (eq_attr "type" "fmov")

169             (and (eq_attr "memory""load,store")

170                (eq_attr"mode" "XF"))))

171   "(pentium-fp+pentium-np)*3")

 

This pattern is part of pipe hazards description for construtingDFA-based recognizer, this pattern shouldn’t coexist with define_function_unitin same machine description file. As we have discussed in 9.3.5 Read DEFINE_FUNCTION_UNITpattern, this pattern describes system from the view-point of instructionsinstead of the view-point of function units. Commonly, number of instructionsis much larger than the number of units, so automaton is the better form forthe pipeline hazard recognizer.

After treated by init_md_reader_args, above pattern will beloaded into memory as rtx object as following.

t49

figure 148 : example of DEFINE_INSN_RESERVATION pattern

This rtx object is not eligible for constructing DFA-based pipelinehazards recognizer. gen_insn_reserv isinvoked to pack up the data.

 

2125 void

2126 gen_insn_reserv (rtx def)                                                                    ingenautomata.c

2127 {

2128   decl_t decl;

2129

2130   decl = create_node (sizeof(struct decl));

2131   decl->mode= dm_insn_reserv;

2132   decl->pos = 0;

2133   DECL_INSN_RESERV (decl)->name

2134     = check_name ((char *) XSTR (def, 0),decl->pos);

2135   DECL_INSN_RESERV (decl)->default_latency =XINT (def, 1);

2136   DECL_INSN_RESERV (decl)->condexp = XEXP (def,2);

2137   DECL_INSN_RESERV (decl)->regexp = gen_regexp((char *) XSTR (def, 3));

2138   VLA_PTR_ADD (decls, decl);

2139   num_dfa_decls++;

2140 }

 

Macro DECL_INSN_RESERV accesses insn_reserv field of decl, which has definitionas following.

 

861  struct insn_reserv_decl                                                                         ingenautomata.c

862  {

863   rtx condexp;

864   int default_latency;

865   regexp_t regexp;

866   char *name;

867 

868    /* The following fields are defined bychecker.  */

869 

870    /* The following field value is order number(0, 1, ...) of given

871      insn. */

872   int insn_num;

873    /* The following field value is list ofbypasses in which given insn

874      is output insn.  */

875   struct bypass_decl*bypass_list;

876 

877    /* The following fields are defined by automatongenerator.  */

878 

879    /* The following field is the insn regexptransformed that

880      the regexp has not optional regexp,repetition regexp, and an

881      reservation name (i.e. reservationidentifiers are changed by the

882      corresponding regexp) and all alternationsare the topest level

883      of the regexp. The value can be NULL onlyif it is special

884      insn `cycle advancing'.  */

885   regexp_t transformed_regexp;

886    /* The following field value is list of arcsmarked given

887      insn. The field is used in transformationNDFA -> DFA.  */

888   arc_t arcs_marked_by_insn;

889    /* The two following fields are used duringminimization of a finite state

890      automaton. */

891    /* The field value is number of equivalenceclass of state into

892      which arc marked by given insn enters froma state (fixed during

893      an automaton minimization).  */

894   int equiv_class_num;

895    /* The field value is state_alts of arcleaving a state (fixed

896      during an automaton minimization) andmarked by given insn

897      enters. */

898   int state_alts;

899   /* The following member value is the list toautomata which can be

900      changed by the insn issue.  */

901   automata_list_el_t important_automata_list;

902   /* The following member is used to processinsn once for output.  */

903   int processed_p;

904  };

 

In gen_insn_reserv,at line 2138 the parameter of gen_regexp is "(pentium-fp+pentium-np)*3".This part after handled by gen_regexp producing following data.

t50

figure 50 : example of regexp generated for define_insn_reservationpattern