From: Tom Wood Date: Tue, 25 Aug 1992 20:22:38 +0000 (+0000) Subject: (extend_range, init_range): New functions. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ef3fad04839638138ab28d7a00e40fca253f3d45;p=gcc.git (extend_range, init_range): New functions. (write_units): Add blockage_function, blockage_range_function, max_blockage and max_issue_delay fields to struct function_unit_desc. Drop max_busy_cost field. Write #defines for min/max blockage, issue delay, multiplicity, and simultaneity and for BLOCKAGE_BITS and INSN_QUEUE_SIZE. (main): Compute the new values. From-SVN: r1950 --- diff --git a/gcc/genattr.c b/gcc/genattr.c index 957ebd1d1c0..cf9bd3c4682 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -38,12 +38,46 @@ char *xmalloc (); static void fatal (); void fancy_abort (); -struct namelist +/* A range of values. */ + +struct range +{ + int min; + int max; +}; + +/* Record information about each function unit mentioned in a + DEFINE_FUNCTION_UNIT. */ + +struct function_unit { - struct namelist *next; - char *name; + char *name; /* Function unit name. */ + struct function_unit *next; /* Next function unit. */ + int multiplicity; /* Number of units of this type. */ + int simultaneity; /* Maximum number of simultaneous insns + on this function unit or 0 if unlimited. */ + struct range ready_cost; /* Range of ready cost values. */ + struct range issue_delay; /* Range of issue delay values. */ }; +static void +extend_range (range, min, max) + struct range *range; + int min; + int max; +{ + if (range->min > min) range->min = min; + if (range->max < max) range->max = max; +} + +static void +init_range (range) + struct range *range; +{ + range->min = 100000; + range->max = -1; +} + static void write_upcase (str) char *str; @@ -106,9 +140,17 @@ gen_attr (attr) } static void -write_units (num_units, min_ready_cost, max_ready_cost, - min_busy_delay, max_busy_delay) +write_units (num_units, multiplicity, simultaneity, + ready_cost, issue_delay, blockage) + int num_units; + struct range *multiplicity; + struct range *simultaneity; + struct range *ready_cost; + struct range *issue_delay; + struct range *blockage; { + int i, q_size; + printf ("#define INSN_SCHEDULING\n\n"); printf ("extern int result_ready_cost ();\n"); printf ("extern int function_units_used ();\n\n"); @@ -119,15 +161,34 @@ write_units (num_units, min_ready_cost, max_ready_cost, printf (" int multiplicity;\n"); printf (" int simultaneity;\n"); printf (" int default_cost;\n"); - printf (" int max_busy_cost;\n"); + printf (" int max_issue_delay;\n"); printf (" int (*ready_cost_function) ();\n"); printf (" int (*conflict_cost_function) ();\n"); + printf (" int max_blockage;\n"); + printf (" unsigned int (*blockage_range_function) ();\n"); + printf (" int (*blockage_function) ();\n"); printf ("} function_units[];\n\n"); printf ("#define FUNCTION_UNITS_SIZE %d\n", num_units); - printf ("#define MIN_READY_COST %d\n", min_ready_cost); - printf ("#define MAX_READY_COST %d\n", max_ready_cost); - printf ("#define MIN_BUSY_DELAY %d\n", min_busy_delay); - printf ("#define MAX_BUSY_DELAY %d\n\n", max_busy_delay); + printf ("#define MIN_MULTIPLICITY %d\n", multiplicity->min); + printf ("#define MAX_MULTIPLICITY %d\n", multiplicity->max); + printf ("#define MIN_SIMULTANEITY %d\n", simultaneity->min); + printf ("#define MAX_SIMULTANEITY %d\n", simultaneity->max); + printf ("#define MIN_READY_COST %d\n", ready_cost->min); + printf ("#define MAX_READY_COST %d\n", ready_cost->max); + printf ("#define MIN_ISSUE_DELAY %d\n", issue_delay->min); + printf ("#define MAX_ISSUE_DELAY %d\n", issue_delay->max); + printf ("#define MIN_BLOCKAGE %d\n", blockage->min); + printf ("#define MAX_BLOCKAGE %d\n", blockage->max); + for (i = 0; (1 << i) < blockage->max; i++) + ; + printf ("#define BLOCKAGE_BITS %d\n", i + 1); + + /* INSN_QUEUE_SIZE is a power of two larger than MAX_BLOCKAGE and + MAX_READY_COST. This is the longest time an isnsn may be queued. */ + i = MAX (blockage->max, ready_cost->max); + for (q_size = 1; q_size <= i; q_size <<= 1) + ; + printf ("#define INSN_QUEUE_SIZE %d\n", q_size); } char * @@ -182,13 +243,18 @@ main (argc, argv) int have_delay = 0; int have_annul_true = 0; int have_annul_false = 0; - int have_units = 0; int num_units = 0; - int min_ready_cost = 100000, max_ready_cost = -1; - int min_busy_delay = 100000, max_busy_delay = -1; - struct namelist *units = 0; + struct range all_simultaneity, all_multiplicity; + struct range all_ready_cost, all_issue_delay, all_blockage; + struct function_unit *units = 0, *unit; int i; + init_range (&all_multiplicity); + init_range (&all_simultaneity); + init_range (&all_ready_cost); + init_range (&all_issue_delay); + init_range (&all_blockage); + obstack_init (rtl_obstack); if (argc <= 1) @@ -255,40 +321,90 @@ from the machine description file `md'. */\n\n"); else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT) { - struct namelist *unit; char *name = XSTR (desc, 0); - int ready_cost = XINT (desc, 4); - int busy_delay = XINT (desc, 5); - - have_units = 1; - if (min_ready_cost > ready_cost) min_ready_cost = ready_cost; - if (max_ready_cost < ready_cost) max_ready_cost = ready_cost; - if (min_busy_delay > busy_delay) min_busy_delay = busy_delay; - if (max_busy_delay < busy_delay) max_busy_delay = busy_delay; - - /* If the optional conflict vector was specified, the busy delay - may be zero. */ - if (XVEC (desc, 6) != 0) min_busy_delay = 0; + int multiplicity = XINT (desc, 1); + int simultaneity = XINT (desc, 2); + int ready_cost = MAX (XINT (desc, 4), 1); + int issue_delay = MAX (XINT (desc, 5), 1); + int issueexp_p = (XVEC (desc, 6) != 0); for (unit = units; unit; unit = unit->next) if (strcmp (unit->name, name) == 0) break; + if (unit == 0) { int len = strlen (name) + 1; - unit = (struct namelist *) alloca (sizeof (struct namelist)); + unit = (struct function_unit *) + alloca (sizeof (struct function_unit)); unit->name = (char *) alloca (len); bcopy (name, unit->name, len); + unit->multiplicity = multiplicity; + unit->simultaneity = simultaneity; + unit->ready_cost.min = unit->ready_cost.max = ready_cost; + unit->issue_delay.min = unit->issue_delay.max = issue_delay; unit->next = units; units = unit; num_units++; + + extend_range (&all_multiplicity, multiplicity, multiplicity); + extend_range (&all_simultaneity, simultaneity, simultaneity); } + else if (unit->multiplicity != multiplicity + || unit->simultaneity != simultaneity) + fatal ("Differing specifications given for `%s' function unit.", + unit->name); + + extend_range (&unit->ready_cost, ready_cost, ready_cost); + extend_range (&unit->issue_delay, + issueexp_p ? 1 : issue_delay, issue_delay); + extend_range (&all_ready_cost, + unit->ready_cost.min, unit->ready_cost.max); + extend_range (&all_issue_delay, + unit->issue_delay.min, unit->issue_delay.max); } } - if (have_units) - write_units (num_units, min_ready_cost, max_ready_cost, - min_busy_delay, max_busy_delay); + if (num_units > 0) + { + /* Compute the range of blockage cost values. See genattrtab.c + for the derivation. BLOCKAGE (E,C) when SIMULTANEITY is zero is + + MAX (ISSUE-DELAY (E,C), + READY-COST (E) - (READY-COST (C) - 1)) + + and otherwise + + MAX (ISSUE-DELAY (E,C), + READY-COST (E) - (READY-COST (C) - 1), + READY-COST (E) - FILL-TIME) */ + + for (unit = units; unit; unit = unit->next) + { + struct range blockage; + int max_issue_time = MAX (unit->issue_delay.max, 1); + + blockage = unit->issue_delay; + blockage.max = MAX (unit->ready_cost.max + - (unit->ready_cost.min - 1), + blockage.max); + blockage.min = MAX (1, blockage.min); + + if (unit->simultaneity != 0) + { + int fill_time = ((unit->simultaneity - 1) + * unit->issue_delay.min); + blockage.min = MAX (unit->ready_cost.min - fill_time, + blockage.min); + blockage.max = MAX (unit->ready_cost.max - fill_time, + blockage.max); + } + extend_range (&all_blockage, blockage.min, blockage.max); + } + + write_units (num_units, &all_multiplicity, &all_simultaneity, + &all_ready_cost, &all_issue_delay, &all_blockage); + } fflush (stdout); exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);