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

9.3.11.      Read in DEFINE_RESERVATION pattern

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

 

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

130                        + pentium-memory)

131                      | (pentium-firstv,pentium-v,

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

 

This pattern is part of pipe hazards description for construting DFA-based recognizer, this pattern shouldn’t coexist with define_function_unit in 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_reserv generates more organized ones.

 

2106 void

2107 gen_reserv (rtx def)                                                                            in genautomata.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                                                                                 in genautomata.c

846  {

847    char *name;

848    regexp_t regexp;

849 

850    /* The following fields are defined by checker.  */

851 

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

853      regexp.  */

854    char reserv_is_used;

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

856      definition.  */

857    int loop_pass_num;

858  };

 

regexp is designed for regular expression describing the occupation of cpu units for certain instructions. Refer to 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern for detail of the regular expression.

 

990  struct regexp                                                                                      in genautomata.c

991  {

992    /* What node in the union? */

993    enum regexp_mode mode;

994    pos_t pos;

995    union

996    {

997      struct unit_regexp unit;

998      struct reserv_regexp reserv;

999      struct nothing_regexp nothing;

1000     struct sequence_regexp sequence;

1001     struct repeat_regexp repeat;

1002     struct allof_regexp allof;

1003     struct oneof_regexp oneof;

1004   } regexp;

1005 };

 

197  typedef struct regexp *regexp_t;                                                           in genautomata.c

 

This structure is generated by gen_regexp . The regular expression obeys following 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)                                                                        in genautomata.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. For our 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)                                                          in genautomata.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 (struct regexp)

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     return sequence;

2088   }

2089   else

2090     return gen_regexp_oneof (str);

 

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

 

2043 static regexp_t

2044 gen_regexp_oneof (char *str)                                                              in genautomata.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     return oneof;

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, we can get oneof_vect at 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 seen when “(“ balances “)”.

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

 

983  struct oneof_regexp                                                                                     in genautomata.c

984  {

985    int regexps_num;

986    regexp_t regexps [1];

987  };

 

Inside expression of “|”, we may encounter expression of “+”, so we need gen_regexp_allof to handle the separated fragments.

 

2017 static regexp_t

2018 gen_regexp_allof (char *str)                                                                in genautomata.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 (struct regexp)

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     return allof;

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 ‘+’, again the third parameter of it is TRUE, balanced parentheses is wanted.

Now for our example, the regular expression had been split into two parts. For both parts, get_str_vect fails to do further split. Both them enter gen_regexp_repeat at line 2039.

 

1984 static regexp_t

1985 gen_regexp_repeat (char *str)                                                              in genautomata.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     return regexp;

2011   }

2012   else

2013     return gen_regexp_el (str);

2014 }

 

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

 

1955 static regexp_t

1956 gen_regexp_e l (char *str)                                                                    in genautomata.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 ) in reservation `%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 (struct decl));

1972     regexp->mode = rm_nothing;

1973   }

1974   else

1975   {

1976     regexp = create_node (sizeof (struct decl));

1977     regexp->mode = rm_unit;

1978     REGEXP_UNIT (regexp)->name = str;

1979   }

1980   return regexp;

1981 }

 

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

t48

figure 48  : example of regexp object generated for define_ reservation pattern

9.3.12.      Read in DEFINE_INSN_RESERVATION pattern

Section 8.1.3 Overview of DEFINE_INSN_RESERVATION pattern describes the detail of  DEFINE_INSN_RESERVATION pattern. For this pattern, 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 construting DFA-based recognizer, this pattern shouldn’t coexist with define_function_unit in same machine description file. As we have discussed in 9.3.5 Read DEFINE_FUNCTION_UNIT pattern , this pattern describes system from the view-point of instructions instead of the view-point of function units. Commonly, number of instructions is much larger than the number of units, so automaton is the better form for the pipeline hazard recognizer.

After treated by init_md_reader_args , above pattern will be loaded 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 pipeline hazards recognizer. gen_insn_reserv is invoked to pack up the data.

 

2125 void

2126 gen_insn_reserv (rtx def)                                                                    in genautomata.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 definition as following.

 

861  struct insn_reserv_decl                                                                          in genautomata.c

862  {

863    rtx condexp;

864    int default_latency;

865    regexp_t regexp;

866    char *name;

867 

868    /* The following fields are defined by checker.  */

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 of bypasses in which given insn

874      is output insn.  */

875    struct bypass_decl *bypass_list;

876 

877    /* The following fields are defined by automaton generator.  */

878 

879    /* The following field is the insn regexp transformed that

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

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

882      corresponding regexp) and all alternations are the topest level

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

884      insn `cycle advancing'.  */

885    regexp_t transformed_regexp;

886    /* The following field value is list of arcs marked given

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

888    arc_t arcs_marked_by_insn;

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

890      automaton.  */

891    /* The field value is number of equivalence class of state into

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

893      an automaton minimization).  */

894    int equiv_class_num;

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

896      during an automaton minimization) and marked by given insn

897      enters.  */

898    int state_alts;

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

900      changed by the insn issue.  */

901    automata_list_el_t important_automata_list;

902    /* The following member is used to process insn 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_reservation pattern

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值