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

9.6.4.2.8.           Outputfunctions internal_state_dead_lock_p & state_dead_lock_p

These two functions provide a wrapper for dead_lock_x table (refer to 9.6.4.1.4 Output table for locked states).

 

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.           Outputfunctions state_size & internal_reset & state_reset

These are helper functions for DFA_chip (refer to 9.6.4.2.1 Pseudo chip definition)

 

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.       Outputfunction min_insn_conflict_delay

min_insn_conflict_delay finds out the minimum conflict delays between two giveninstruction.

 

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    }

 

See that at line 25, the automatons’ states inside DFA_chip havebeen cleaned as 0, which indicate the starting state for all automatons. So internal_state_transition atline 26 should return -1 as result of capable issuing instruction insn.Inside this function, automatons’ states are updated accordingly, and internal_min_issue_delay isinvoked to find the issue cost of insn2 following insn.

9.6.4.2.11.       Outputfunctions internal_insn_latency & insn_latency

Latency indicates the delay of the result of the instruction can beavailable after it starts. Besides the default_latency field indefine_insn_reservation describes the latency for common cases, there aredefine_bypass definitions defining the latencies for special cases.

 

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 defines special latency between specified instructionpair, otherwise we should use default_latency given in thedefine_insn_reservation pattern as indicated by the generated function (contentin red is not output by the tool). The relationbetween define_bypass and define_insn_reservation can refer to 9.5.7.3rd Loop of Processing Decls – DECL_BYPASS.

 

1     static int

2     internal_insn_latency (intinsn_code ATTRIBUTE_UNUSED,

3                       int insn2_code ATTRIBUTE_UNUSED,

4                      rtx insn ATTRIBUTE_UNUSED,

5                      rtx insn2 ATTRIBUTE_UNUSED)

6     {

7       staticconst unsigned char default_latencies[] =

8       {

9        `default_latency`           // default latency 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 is a helper function. We need an interface accepts twoinstructions, one is the candidate and the other is executing, and returns thelatency between these two instructions. It is the output 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 }

 

The output insn_latency has following definition.

 

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.       Outputfunction print_reservation

print_reservation is just for debugging/information purpose.

 

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 }

 

At line 8799, regexp_representation does the dirty job.

 

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 }

 

Obvioulsy, form_regexp justs put the regexpinto its original form (not exactly maybe, with extra parenthesises removed)which is given in define_insn_reservation pattern (content in red belwo is not output by the tool).

 

1     void

2     print_reservation (FILE*f, rtx insn ATTRIBUTE_UNUSED)

3     {

4       staticconst char *const reservation_names[] =

5       {

6        `regexp`                 // in original readable form

7         nothing

8       };

9       intinsn_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.       Outputfunctions get_cpu_unit_code & cpu_unit_reseravtion_p

These functions are relate with define_query_cpu pattern. We omitthem here.

9.6.4.2.14.       Outputfunctions dfa_clean_insn_cache & dfa_start & dfa_finish

dfa_start is the starting function invoked by the scheduler to begin the dryrun of program upon the pseudo chip. Instructions will be re-ordered accordingto the result generated. To finish the dry-run, dfa_finish is invoked torelease resource occupied.

 

8937 static void

8938 output_dfa_clean_insn_cache_func (void)                                             in genautomata.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)                                                               in genautomata.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.    Miscellaneous

Rest code of write_automata is for purpose of statistics,debug, informative. We skip it as it is not related to our intention.

 

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 automatadescription...");

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 DFA descriptionfile %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.Finish

 

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 }

 

Delay slot scheduling differs from instruction scheduling in thatdetermining whether an instruction needs a delay slot is dependent only on thetype of instruction being generated, not on data flow between the instructions(detail refer to 8.1.1 Overview of DEFINE_DELAYpattern). Now the information of the delay slots have been saved intoattribute *num_delay_slots, and the function num_delay_slots fetchingthis attribute has been output in section 9.6.1.4Output attributes.

Quite often, the number of delay slots is not a function of thelength of the instruction. const_num_delay_slots tellsout these instructions.

 

5955 static void

5956 write_const_num_delay_slots (void)                                                     in genattrtab.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_used is set if attribute of “length” used as condition to filter out thetarget instruction.

你可能感兴趣的:(gcc,File,output,conflict,statistics,delay)