GCC后端及汇编发布(20)

  DEFINE_INSN_RESERVATION模式的概览一节描述了DEFINE_RESERVATION模式的细节。对于这个模式,我们使用以下的例子:
  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))") 这个模式是构建基于DFA识别器的流水线危险描述的一部分,该模式不应该与define_function_unit共存于同一个机器描述文件里。 在经过init_md_reader_args的处理后,上面的模式将作为以下的rtx对象载入内存。
  
  图47:DEFINE_RESERVATION模式的例子 显然这个原始的形式不是我们想要的。gen_reserv产生更有序的对象。 2106void 2107gen_reserv (rtx def) in genautomata.c 2108{ 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访问decl的reserv域。 845 structreserv_decl in genautomata.c 846 { 847 char *name; 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设计用于描述指令对cpu单元占据的正则表达式。正则表达式的细节参考DEFINE_INSN_RESERVATION模式的概览一节。 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; 1004 } regexp; 1005}; 197 typedefstruct regexp *regexp_t; in genautomata.c 这个结构体由gen_regexp生成。正则表达式遵循以下的语法: 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根据上图中的正则表达式,构成regexp对象。 2095gen_regexp (char *str) in genautomata.c 2096{ 2097 reserv_str = str; 2099} gen_regexp通过从顶向下解析表达式来生成这个结构体。对于我们的例子,这个表达式是"(pentium-load + pentium-firstuv + pentium-memory) | (pentium-firstv, pentium-v, (pentium-load + pentium-firstv))"。 2070gen_regexp_sequence (char *str) in genautomata.c 2071{ 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 regexps [i] 2086 = gen_regexp_oneof (sequence_vect [i]); 2087 return sequence; 2088 } 2089 else 在正则表达式中,','用于表示在单元预订中下一个周期的开始。在2077行,get_str_vect尝试把这个正则表达式分解成周期。注意到该函数的第三个参数是TRUE,表示这个分解,仅当左右括号数目匹配时,才被执行。在","的两边可能是"|"表达式,因此调用gen_regexp_oneof来处理这两边。 2044gen_regexp_oneof (char *str) in genautomata.c 2045{ 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 (structregexp) 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 regexps [i] = gen_regexp_allof (oneof_vect [i]); 2062 return oneof; 2063 } 2064 else 2066} 这次get_str_vect尝试根据'|'来分解字符串。再次,get_str_vect的第三个参数是TRUE,因此对于我们的例子,我们可以在2051行得到具有两个元素的oneof_vect: "(pentium-load + pentium-firstuv + pentium-memory)" "(pentium-firstv, pentium-v, (pentium-load + pentium-firstv))" 第二个不能被get_str_vect根据","来分解,因为当"("的数目匹配")"时,没有","可见。 上面在2059行,宏REGEXP_ONEOF访问regexp的oneof域,它具有如下的定义,其中regexps域是一个可变长度数组,其大小依赖于"|"操作符的数目(参见上面的2056行)。 983 structoneof_regexp in genautomata.c 984 { 985 int regexps_num; 987 }; 在"|"表达式中,我们可能遇到"+"表达式,因此我们需要gen_regexp_allof来处理这些分解的片段。 2018gen_regexp_allof (char *str) in genautomata.c 2019{ 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 regexps [i] = gen_regexp_repeat (allof_vect [i]); 2036 return allof; 2037 } 2038 else 2040} 在2025行的get_str_vect这次尝试找出由'+'连接的部分,再次第三个参数是TRUE,只有匹配的括号对才被考虑。 现在对于我们的例子,正则表达式已经被分解为两部分。对于这两部分get_str_vect不能进一步分解。这两者都在2039行进入gen_regexp_repeat。 1985gen_regexp_repeat (char *str) in genautomata.c 1986{ 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 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 正则表达式重复NUMBER次,同时伴随周期的推进。例如,*5表示重复5次。在我们的例子中,这两部分都不包含'*',它们只是在2013行进入gen_regexp_el。 1956gen_regexp_el (char *str) in genautomata.c 1957{ 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'; 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} 在这个例子中,这两部分都被括号所包围,括号之间应该被视为一个序列。因此gen_regexp_sequence将在1967行被递归。最后这个例子被转换到如下的结构。
  
  图48:为define_ reservation模式所产生的regexp对象的例子 DEFINE_INSN_RESERVATION模式的概览一节描述了DEFINE_INSN_RESERVATION模式的细节。对于这个模式,我们使用如下的例子:
  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") 这个模式是构建基于DFA识别器的流水线危险描述的一部分,该模式不应该与define_function_unit共存于同一个机器描述文件里。正如我们在读入 DEFINE_FUNCTION_UNIT模式已经所讨论的,这个模式以指令的角度来描述系统,而不是从功能单元的角度。通常,指令的数目要远远多于功能单元的数目,因此自动机,对于流水线危险识别器来说,是一个更好的形式。 在经过init_md_reader_args的处理后,上面的模式将作为以下的rtx对象载入内存。
  
  图49:DEFINE_INSN_RESERVATION模式的例子 这个rtx对象对于构建基于DFA的流水线危险识器起重要作用。gen_insn_reserv被调用来收集数据。 2125void 2126gen_insn_reserv (rtx def) in genautomata.c 2127{ 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} 宏DECL_INSN_RESERV访问decl的insn_reserv域,它具有如下的定义。 861 structinsn_reserv_decl in genautomata.c 862 { 863 rtx condexp; 864 int default_latency; 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. */ 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'. */ 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 }; 在gen_insn_reserv中的2138行,gen_regexp的参数是"(pentium-fp+pentium-np)*3"。这部分在gen_regexp处理后,产生以下的数据。
  
  图50:为define_insn_reservation模式产生的regexp的例子
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值