GCC后端及汇编发布(38)

来源:互联网 发布:梁边妖 知乎 编辑:程序博客网 时间:2024/05/14 10:32
9.6.4.2.8.           输出函数internal_state_dead_lock_p与state_dead_lock_p

这两个函数是对表dead_lock_x(参考输出锁定状态表)的封装。

 

8568 static void

8569 output_internal_dead_lock_func (void)                                                 ingenautomata.c

8570 {

8571   automaton_tautomaton;

8572

8573   fprintf (output_file, "static int\n%s (struct %s*%s)\n",

8574          INTERNAL_DEAD_LOCK_FUNC_NAME,CHIP_NAME, CHIP_PARAMETER_NAME);

8575   fprintf (output_file, "{\n");

8576   for(automaton = description->first_automaton;

8577       automaton != NULL;

8578       automaton = automaton->next_automaton)

8579   {

8580     fprintf (output_file, "  if (");

8581     output_dead_lock_vect_name (output_file,automaton);

8582     fprintf (output_file, " [%s->",CHIP_PARAMETER_NAME);

8583     output_chip_member_name (output_file,automaton);

8584     fprintf (output_file, "])\n    return 1/* TRUE */;\n");

8585   }

8586   fprintf (output_file, "  return 0/* FALSE */;\n}\n\n");

8587 }

 

1     static int

2     internal_state_dead_lock_p (structDFA_chip *chip)

3     {

4       if(dead_lock_0 [chip->automaton_state_0])

5         return 1/*TRUE */;

6       return0/* FALSE */;

7     }

 

8590 static void

8591 output_dead_lock_func (void)                                                             ingenautomata.c

8592 {

8593   fprintf (output_file, "int\n%s (%s %s)\n",

8594          DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);

8595   fprintf (output_file, "{\n  return %s (%s);\n}\n\n",

8596          INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);

8597 }

 

1     int

2     state_dead_lock_p (state_t state)

3     {

4       return internal_state_dead_lock_p (state);

5     }

9.6.4.2.9.           输出函数state_size,internal_reset,state_reset

这些是DFA_chip(参考定义伪芯片)的辅助函数。

 

8610 static void

8611 output_size_func (void)                                                                       ingenautomata.c

8612 {

8613   fprintf (output_file, "int\n%s (void)\n",SIZE_FUNC_NAME);

8614   fprintf (output_file, "{\n  return sizeof (struct %s);\n}\n\n",CHIP_NAME);

8615 }

 

1     int

2     state_size (void)

3     {

4       returnsizeof (struct DFA_chip));

5     }

 

8600 static void

8601 output_internal_reset_func (void)                                                        ingenautomata.c

8602 {

8603   fprintf (output_file, "static inline void\n%s (struct%s *%s)\n",

8604        INTERNAL_RESET_FUNC_NAME, CHIP_NAME,CHIP_PARAMETER_NAME);

8605   fprintf (output_file, "{\n  memset (%s, 0, sizeof (struct%s));\n}\n\n",

8606        CHIP_PARAMETER_NAME, CHIP_NAME);

8607 }

 

1     static inline void

2     internal_reset (structDFA_chip *chip)

3     {

4       memset(chip, 0, sizeof (struct DFA_chip));

5     }

 

8618 static void

8619 output_reset_func (void)                                                                      ingenautomata.c

8620 {

8621   fprintf (output_file, "void\n%s (%s %s)\n",

8622          RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);

8623   fprintf (output_file, "{\n  %s (%s);\n}\n\n",INTERNAL_RESET_FUNC_NAME,

8624          STATE_NAME);

8625 }

 

1    void

2    state_reset (state_t state)

3    {

4      internal_reset(state);

5    }

9.6.4.2.10.       输出函数min_insn_conflict_delay

min_insn_conflict_delay找出两条给定指令间的最小冲突延迟。

 

8628 static void

8629 output_min_insn_conflict_delay_func (void)                                         ingenautomata.c

8630 {

8631   fprintf (output_file,

8632          "int\n%s (%s %s, rtx %s, rtx %s)\n",

8633           MIN_INSN_CONFLICT_DELAY_FUNC_NAME,STATE_TYPE_NAME,

8634          STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);

8635   fprintf (output_file, "{\n  struct %s %s;\n  int %s, %s;\n",

8636          CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,

8637          INTERNAL_INSN2_CODE_NAME);

8638   output_internal_insn_code_evaluation(INSN_PARAMETER_NAME,

8639                                    INTERNAL_INSN_CODE_NAME,0);

8640   output_internal_insn_code_evaluation(INSN2_PARAMETER_NAME,

8641                                    INTERNAL_INSN2_CODE_NAME,0);

8642   fprintf (output_file, "  memcpy (&%s, %s, sizeof (%s));\n",

8643          CHIP_NAME, STATE_NAME, CHIP_NAME);

8644   fprintf (output_file, "  %s (&%s);\n", INTERNAL_RESET_FUNC_NAME,CHIP_NAME);

8645   fprintf (output_file, "  if (%s (%s, &%s) > 0)\n    abort ();\n",

8646    INTERNAL_TRANSITION_FUNC_NAME,INTERNAL_INSN_CODE_NAME, CHIP_NAME);

8647   fprintf (output_file, "  return %s (%s, &%s);\n",

8648   INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME,INTERNAL_INSN2_CODE_NAME,

8649          CHIP_NAME);

8650   fprintf (output_file, "}\n\n");

8651 }

 

1     int

2     min_insn_conflict_delay(state_t state, rtx insn, rtx insn2)

3     {

4       structDFA_chip DFA_chip;

5       int insn_code, insn2_code;

6       if (insn!= 0)

7       {

8        insn_code = dfa_insn_code (insn);

9         if(insn_code > DFA__ADVANCE_CYCLE)

10          return 0;

11      }

12      else

13        insn_code = DFA__ADVANCE_CYCLE;

14   

15      if (insn2 != 0)

16      {

17        insn2_code = dfa_insn_code(insn2);

18        if (insn2_code > DFA__ADVANCE_CYCLE)

19          return 0;

20      }

21      else

22        insn2_code = DFA__ADVANCE_CYCLE;

23   

24      memcpy (&DFA_chip, state, sizeof(DFA_chip));

25      internal_reset(&DFA_chip);

26      if (internal_state_transition(insn_code, &DFA_chip) > 0)

27        abort ();

28      return internal_min_issue_delay(insn2_code, &DFA_chip);

29    }

 

看到在25行,在DFA_chip里,该自动机的状态被清0,这表示所有自动机的起始状态。因此在26行的internal_state_transition应该返回-1,作为看可以发布指令insn的结果。在这个函数内部,自动机的状态被相应更新,而internal_min_issue_delay被调用来查找跟在insninsn2的发布代价。

9.6.4.2.11.       输出函数internal_insn_latency与insn_latency

休眠表示指令开始后到其结果可用的延时。除了define_insn_reservation的default_latency域描述了通常情形下的休眠,还有define_bypass定义了特殊的休眠。

 

8654 static void

8655 output_internal_insn_latency_func (void)                                              ingenautomata.c

8656 {

8657   decl_t decl;

8658   struct bypass_decl *bypass;

8659   int i, j, col;

8660   const char*tabletype = "unsigned char";

8661

8662   /* Find thesmallest integer type that can hold all the default

8663     latency values.  */

8664   for (i = 0; i< description->decls_num;i++)

8665     if (description->decls[i]->mode ==dm_insn_reserv)

8666     {

8667       decl = description->decls[i];

8668       if (DECL_INSN_RESERV(decl)->default_latency > UCHAR_MAX

8669            && tabletype[0] != 'i')  /* Don't shrinkit.  */

8670         tabletype = "unsigned short";

8671       if (DECL_INSN_RESERV(decl)->default_latency > USHRT_MAX)

8672         tabletype = "int";

8673     }

8674

8675         fprintf (output_file,"static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %sATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %sATTRIBUTE_UNUSED)\n",

8676          INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,

8677          INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,

8678          INSN2_PARAMETER_NAME);

8679   fprintf (output_file, "{\n");

8680

8681   if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num== 0)

8682   {

8683     fputs ("  return 0;\n}\n\n", output_file);

8684     return;

8685   }

8686

8687   fprintf (output_file, "  static const %s default_latencies[] =\n    {",

8688         tabletype);

8689

8690   for (i = 0, j= 0, col = 7; i < description->decls_num; i++)

8691     if (description->decls[i]->mode ==dm_insn_reserv

8692        && description->decls[i] != advance_cycle_insn_decl)

8693     {

8694       if ((col = (col+1) % 8) == 0)

8695         fputs ("\n     ", output_file);

8696       decl = description->decls[i];

8697       if (j++ != DECL_INSN_RESERV(decl)->insn_num)

8698         abort ();

8699       fprintf (output_file, "% 4d,",

8700             DECL_INSN_RESERV(decl)->default_latency);

8701     }

8702   if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)

8703     abort ();

8704   fputs ("\n    };\n", output_file);

8705

8706   fprintf (output_file, "  if (%s >= %s || %s >= %s)\n    return 0;\n",

8707          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,

8708          INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);

8709

8710   fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);

8711   for (i = 0; i < description->decls_num; i++)

8712     if (description->decls[i]->mode ==dm_insn_reserv

8713        && DECL_INSN_RESERV (description->decls[i])->bypass_list)

8714     {

8715       decl = description->decls [i];

8716       fprintf (output_file,

8717             "    case %d:\n      switch (%s)\n        {\n",

8718             DECL_INSN_RESERV(decl)->insn_num,

8719             INTERNAL_INSN2_CODE_NAME);

8720       for(bypass = DECL_INSN_RESERV (decl)->bypass_list;

8721           bypass != NULL;

8722           bypass = bypass->next)

8723       {

8724         if(bypass->in_insn_reserv->insn_num

8725            == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)

8726           abort ();

8727         fprintf (output_file, "        case %d:\n",

8728              bypass->in_insn_reserv->insn_num);

8729         if (bypass->bypass_guard_name ==NULL)

8730           fprintf (output_file, "          return %d;\n",

8731                 bypass->latency);

8732         else

8733         {

8734           fprintf (output_file,

8735                 "          if (%s (%s, %s))\n",

8736                 bypass->bypass_guard_name,INSN_PARAMETER_NAME,

8737                 INSN2_PARAMETER_NAME);

8738           fprintf (output_file,

8739                  "            return %d;\n          break;\n",

8740                  bypass->latency);

8741         }

8742       }

8743       fputs ("        }\n     break;\n", output_file);

8744     }

8745

8746   fprintf (output_file, "    }\n return default_latencies[%s];\n}\n\n",

8747          INTERNAL_INSN_CODE_NAME);

8748 }

 

define_bypass定义了指定指令对之间特定的休眠,否则我们应该使用在define_insn_reservation中给出的default_latency,正如所生成函数所显示的(红色部分不是工具输出的)。define_bypass与define_insn_reservation之间的关系,可以参考处理decl的第三个循环 –DECL_BYPASS。

 

1    staticint

2    internal_insn_latency (intinsn_code ATTRIBUTE_UNUSED,

3                      int insn2_codeATTRIBUTE_UNUSED,

4                      rtx insn ATTRIBUTE_UNUSED,

5                      rtx insn2 ATTRIBUTE_UNUSED)

6    {

7      static const unsigned char default_latencies[]=

8      {

9        `default_latency`            // defaultlatency defined by insn reserv pattern

10     }

11  

12     if (insn_code > DFA__ADVANCE_CYCLE ||insn2_code > DFA__ADVANCE_CYCLE)

13       return 0;

14     switch (insn_code)

15     {

16       case `insn_num`:

17         switch (insn2_code)

18         {

19           case `bypass1-insn-num`:       // insn num of in_insn_reserv of bypass

20             return `bypass1-latency`;    // latency defined by bypass

21           case `bypass2-insn-num`:

22             if (`bypass2-guard (insn, insn2))        // if guard is define in bypass

23               return `bypass2-latency;

24           …                                        // other bypass

25         }

26         break;

27     }

28     return default_latency [insn_code];

29   }

 

 

internal_insn_latency是一个辅助函数。我们需要一个接受两条指令的接口,一条指令是候选,另一条是正在执行的指令,并返回这两条指令间的休眠时间。这就是这里输出的insn_latency

 

8751 static void

8752 output_insn_latency_func (void)                                                           ingenautomata.c

8753 {

8754   fprintf (output_file, "int\n%s (rtx %s, rtx%s)\n",

8755     INSN_LATENCY_FUNC_NAME,INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);

8756   fprintf (output_file, "{\n  int %s, %s;\n",

8757         INTERNAL_INSN_CODE_NAME,INTERNAL_INSN2_CODE_NAME);

8758   output_internal_insn_code_evaluation(INSN_PARAMETER_NAME,

8759                                  INTERNAL_INSN_CODE_NAME, 0);

8760   output_internal_insn_code_evaluation(INSN2_PARAMETER_NAME,

8761                                   INTERNAL_INSN2_CODE_NAME, 0);

8762   fprintf (output_file, "  return %s (%s, %s, %s, %s);\n}\n\n",

8763         INTERNAL_INSN_LATENCY_FUNC_NAME,

8764         INTERNAL_INSN_CODE_NAME,INTERNAL_INSN2_CODE_NAME,

8765         INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);

8766 }

 

输出的insn_latency具有以下定义。

 

1     int

2     insn_latency (rtx insn, rtx insn2)

3     {

4       int insn_code, insn2_code;

5       if (insn!= 0)

6       {

7        insn_code = dfa_insn_code (insn);

8         if(insn_code > DFA__ADVANCE_CYCLE)

9           return 0;

10      }

11      else

12        insn_code = DFA__ADVANCE_CYCLE;

13   

14      if (insn2 != 0)

15      {

16        insn2_code = dfa_insn_code(insn2);

17        if (insn2_code > DFA__ADVANCE_CYCLE)

18          return 0;

19      }

20      else

21        insn2_code = DFA__ADVANCE_CYCLE;

22   

23      return internal_insn_latency(insn_code, insn2_code, insn, insn2));

24    }

9.6.4.2.12.       输出函数print_reservation

print_reservation仅用作调试/输出信息的目的。

 

8769 static void

8770 output_print_reservation_func (void)                                                    ingenautomata.c

8771 {

8772   decl_t decl;

8773   int i, j;

8774

8775   fprintf (output_file,

8776          "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",

8777            PRINT_RESERVATION_FUNC_NAME,FILE_PARAMETER_NAME,

8778            INSN_PARAMETER_NAME);

8779

8780   if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num== 0)

8781   {

8782     fprintf (output_file, "  fputs (\"%s\", %s);\n}\n\n",

8783           NOTHING_NAME, FILE_PARAMETER_NAME);

8784     return;

8785   }

8786

8787

8788   fputs (" static const char *const reservation_names[] =\n    {",

8789        output_file);

8790

8791   for (i = 0, j= 0; i < description->decls_num;i++)

8792   {

8793     decl = description->decls [i];

8794     if (decl->mode == dm_insn_reserv&& decl != advance_cycle_insn_decl)

8795     {

8796       if (j++ != DECL_INSN_RESERV(decl)->insn_num)

8797         abort ();

8798       fprintf (output_file, "\n      \"%s\",",

8799             regexp_representation(DECL_INSN_RESERV (decl)->regexp));

8800       finish_regexp_representation ();

8801     }

8802   }

8803   if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)

8804     abort ();

8805

8806   fprintf (output_file, "\n      \"%s\"\n    };\n int %s;\n\n",

8807          NOTHING_NAME, INTERNAL_INSN_CODE_NAME);

8808

8809   fprintf (output_file, "  if (%s == 0)\n    %s = %s;\n",

8810          INSN_PARAMETER_NAME,

8811          INTERNAL_INSN_CODE_NAME,ADVANCE_CYCLE_VALUE_NAME);

8812   fprintf (output_file, "  else\n\

8813     {\n\

8814       %s = %s (%s);\n\

8815       if (%s > %s)\n\

8816         %s = %s;\n\

8817     }\n",

8818     INTERNAL_INSN_CODE_NAME,DFA_INSN_CODE_FUNC_NAME,

8819     INSN_PARAMETER_NAME,

8820     INTERNAL_INSN_CODE_NAME,ADVANCE_CYCLE_VALUE_NAME,

8821     INTERNAL_INSN_CODE_NAME,ADVANCE_CYCLE_VALUE_NAME);

8822

8823   fprintf (output_file, "  fputs (reservation_names[%s],%s);\n}\n\n",

8824          INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);

8825 }

 

在8799行,regexp_representation执行真正的工作。

 

6979 static const char *

6980 regexp_representation (regexp_t regexp)                                               ingenautomata.c

6981 {

6982   form_regexp(regexp);

6983   obstack_1grow (&irp, '\0');

6984   returnobstack_base (&irp);

6985 }

 

6907 static void

6908 form_regexp (regexp_tregexp)                                                           ingenautomata.c

6909 {

6910   int i;

6911

6912   if (regexp->mode == rm_unit ||regexp->mode == rm_reserv)

6913   {

6914     const char *name = (regexp->mode ==rm_unit

6915                      ? REGEXP_UNIT(regexp)->name

6916                      : REGEXP_RESERV(regexp)->name);

6917

6918     obstack_grow (&irp, name, strlen (name));

6919   }

6920   else if (regexp->mode == rm_sequence)

6921     for (i = 0; i < REGEXP_SEQUENCE(regexp)->regexps_num; i++)

6922     {

6923       if (i != 0)

6924         obstack_1grow (&irp,',');

6925       form_regexp(REGEXP_SEQUENCE (regexp)->regexps [i]);

6926     }

6927   else if (regexp->mode == rm_allof)

6928   {

6929     obstack_1grow (&irp, '(');

6930     for (i = 0; i < REGEXP_ALLOF(regexp)->regexps_num; i++)

6931     {

6932       if (i != 0)

6933         obstack_1grow (&irp,'+');

6934      if (REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_sequence

6935          || REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_oneof)

6936         obstack_1grow (&irp,'(');

6937       form_regexp(REGEXP_ALLOF (regexp)->regexps [i]);

6938       if (REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_sequence

6939          || REGEXP_ALLOF(regexp)->regexps[i]->mode == rm_oneof)

6940         obstack_1grow (&irp,')');

6941     }

6942     obstack_1grow (&irp, ')');

6943   }

6944   else if (regexp->mode == rm_oneof)

6945     for (i = 0; i < REGEXP_ONEOF(regexp)->regexps_num; i++)

6946     {

6947       if (i != 0)

6948         obstack_1grow (&irp,'|');

6949       if (REGEXP_ONEOF(regexp)->regexps[i]->mode == rm_sequence)

6950         obstack_1grow (&irp, '(');

6951       form_regexp(REGEXP_ONEOF (regexp)->regexps [i]);

6952       if (REGEXP_ONEOF(regexp)->regexps[i]->mode == rm_sequence)

6953         obstack_1grow (&irp,')');

6954     }

6955   else if (regexp->mode == rm_repeat)

6956   {

6957     char digits [30];

6958

6959     if (REGEXP_REPEAT(regexp)->regexp->mode == rm_sequence

6960        || REGEXP_REPEAT(regexp)->regexp->mode == rm_allof

6961        || REGEXP_REPEAT(regexp)->regexp->mode == rm_oneof)

6962       obstack_1grow (&irp, '(');

6963     form_regexp(REGEXP_REPEAT (regexp)->regexp);

6964     if (REGEXP_REPEAT(regexp)->regexp->mode == rm_sequence

6965        || REGEXP_REPEAT(regexp)->regexp->mode == rm_allof

6966        || REGEXP_REPEAT(regexp)->regexp->mode == rm_oneof)

6967       obstack_1grow (&irp, ')');

6968     sprintf (digits, "*%d",REGEXP_REPEAT (regexp)->repeat_num);

6969     obstack_grow (&irp, digits, strlen (digits));

6970   }

6971   else if (regexp->mode == rm_nothing)

6972     obstack_grow (&irp, NOTHING_NAME, strlen(NOTHING_NAME));

6973   else

6974     abort ();

6975 }

 

显然,form_regexp只是把regexp置为其初始的形式(可能不完全是,因为移除了额外的括号),这个形式由define_insn_reservation模式给出(红色部分不是工具输出的)。

 

1    void

2    print_reservation (FILE*f, rtx insn ATTRIBUTE_UNUSED)

3    {

4      static const char *const reservation_names[]=

5      {

6        `regexp`                  // in original readable form

7        nothing

8      };

9      int insn_code;

10  

11     if (insn == 0)

12       insn_code = DFA__ADVANCE_CYCLE;

13     else

14     {

15       insn_code = dfa_insn_code(insn);

16       if (insn_code > DFA__ADVANCE_CYCLE)

17         insn_code = DFA__ADVANCE_CYCLE;

18     }

19     fputs (reservation_names [insn_code], f);

20   }

9.6.4.2.13.       输出函数get_cpu_unit_code与cpu_unit_reseravtion_p

这些函数与define_query_cpu模式相关。在这里我们忽略之。

9.6.4.2.14.       输出函数dfa_clean_insn_cache,dfa_start,dfa_finish

dfa_start是由调度器调用的起始函数,它开启在伪芯片上程序的演习。指令将被根据产生的结果来调整次序。结束演习时,dfa_finish被调用来释放占用的资源。

 

8937 static void

8938 output_dfa_clean_insn_cache_func (void)                                             ingenautomata.c

8939 {

8940   fprintf (output_file,

8941          "void\n%s (void)\n{\n  int%s;\n\n",

8942          DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);

8943   fprintf (output_file,

8944          "  for (%s = 0; %s < %s;%s++)\n    %s [%s] = -1;\n}\n\n",

8945          I_VARIABLE_NAME, I_VARIABLE_NAME,

8946          DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,

8947          DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);

8948 }

 

1     void

2     dfa_clean_insn_cache (void)

3     {

4       int i;

5    

6       for (i =0; i < dfa_insn_codes_length; i++)

7        dfa_insn_codes [i] = -1;

8     }

 

8951 static void

8952 output_dfa_start_func (void)                                                               ingenautomata.c

8953 {

8954   fprintf (output_file,

8955        "void\n%s (void)\n{\n  %s = get_max_uid ();\n",

8956     DFA_START_FUNC_NAME,DFA_INSN_CODES_LENGTH_VARIABLE_NAME);

8957   fprintf (output_file, "  %s = xmalloc (%s * sizeof (int));\n",

8958     DFA_INSN_CODES_VARIABLE_NAME,DFA_INSN_CODES_LENGTH_VARIABLE_NAME);

8959   fprintf (output_file, "  %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);

8960 }

 

1     void

2     dfa_start (void)

3     {

4       dfa_insn_codes_length= get_max_uid ();

5       dfa_insn_codes= xmalloc (dfa_insn_codes_length * sizeof (int));

6       dfa_clean_insn_cache ();

7     }

 

8963 static void

8964 output_dfa_finish_func (void)                                                             ingenautomata.c

8965 {

8966   fprintf (output_file, "void\n%s (void)\n{\n  free (%s);\n}\n\n",

8967          DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);

8968 }

 

1    void

2    dfa_finish (void)

3    {

4      free (dfa_insn_codes);

5    }

9.6.4.3.    其它

write_automata余下的代码用于统计,调试等目的。我们跳过它,因为与我们的目标不太相关。

 

write_automata (continued)

 

9919   if (progress_flag)

9920     fprintf (stderr, "done\n");

9921   if (v_flag)

9922   {

9923     output_description_file = fopen (output_description_file_name,"w");

9924     if (output_description_file == NULL)

9925     {

9926       perror (output_description_file_name);

9927       exit (FATAL_EXIT_CODE);

9928     }

9929     if (progress_flag)

9930       fprintf (stderr, "Output automata description...");

9931     output_description ();

9932     output_automaton_descriptions ();

9933     if (progress_flag)

9934       fprintf (stderr, "done\n");

9935     output_statistics (output_description_file);

9936   }

9937   output_statistics (stderr);

9938   ticker_off (&output_time);

9939   output_time_statistics (stderr);

9940   finish_states ();

9941   finish_arcs ();

9942   finish_automata_lists ();

9943   if (time_flag)

9944   {

9945     fprintf (stderr, "Summary:\n");

9946     fprintf (stderr, "  check time ");

9947     print_active_time (stderr, check_time);

9948     fprintf (stderr, ", generation time");

9949     print_active_time (stderr, generation_time);

9950     fprintf (stderr, ", all time ");

9951     print_active_time (stderr, all_time);

9952     fprintf (stderr, "\n");

9953   }

9954   /* Finish allwork.  */

9955   if (output_description_file != NULL)

9956   {

9957     fflush (output_description_file);

9958     if (ferror (stdout) != 0)

9959       fatal ("Error in writing DFAdescription file %s",

9960            output_description_file_name);

9961     fclose (output_description_file);

9962   }

9963   finish_automaton_decl_table ();

9964   finish_insn_decl_table ();

9965   finish_decl_table ();

9966   obstack_free (&irp, NULL);

9967   if (have_error && output_description_file!= NULL)

9968     remove (output_description_file_name);

9969 }

9.7.完成

 

main (continued)

 

6233   /* Write outconstant delay slot info.  */

6234   write_const_num_delay_slots();

6235

6236   write_length_unit_log ();

6237

6238   fflush (stdout);

6239   return(ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);

6240 }

 

延迟槽调度与指令调度的不同之处在于,确定一条指令是否需要一个延迟槽,仅依赖于将要产生的指令的类型,而不是指令间的数据流(细节参考DEFINE_DELAY模式的概览)。现在关于延迟槽的信息已经被保存入属性“*num_delay_slots”中,并且提取这些属性的函数num_delay_slots已经在输出属性一节中输出了。

经常的,延迟槽的数目不是指令长度的函数。const_num_delay_slots识别出这些指令。

 

5955 static void

5956 write_const_num_delay_slots (void)                                                     ingenattrtab.c

5957 {

5958   struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);

5959   struct attr_value *av;

5960   struct insn_ent *ie;

5961

5962   if (attr)

5963   {

5964     printf ("int\nconst_num_delay_slots(rtx insn)\n");

5965     printf ("{\n");

5966     printf ("  switch (recog_memoized (insn))\n");

5967     printf ("    {\n");

5968

5969     for (av =attr->first_value; av; av = av->next)

5970     {

5971       length_used = 0;

5972       walk_attr_value(av->value);

5973       if (length_used)

5974       {

5975         for (ie= av->first_insn; ie; ie = ie->next)

5976           if (ie->insn_code != -1)

5977             printf ("    case %d:\n", ie->insn_code);

5978           printf ("      return 0;\n");

5979       }

5980     }

5981

5982     printf ("    default:\n");

5983     printf ("      return 1;\n");

5984     printf ("    }\n}\n\n");

5985   }

5986 }

 

如果使用了属性“length”作为滤出目标指令的条件,设置length_used

原创粉丝点击