From 8028052c75113e6984ea056878c6891db9a02850 Mon Sep 17 00:00:00 2001 From: Andrew Macleod Date: Mon, 24 Sep 2007 13:35:37 +0000 Subject: temp checking of files so they dont get lost git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ssa-pressure-branch@128715 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/Makefile.in | 5 + gcc/tree-outof-ssa.c | 9 + gcc/tree-ssa-live.c | 50 +++++- gcc/tree-ssa-live.h | 23 ++- gcc/tree-ssa-pressure.c | 433 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree-ssa-pressure.h | 200 ++++++++++++++++++++++ 6 files changed, 718 insertions(+), 2 deletions(-) create mode 100644 gcc/tree-ssa-pressure.c create mode 100644 gcc/tree-ssa-pressure.h diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 051dacf3bc7..685fb7dd075 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1127,6 +1127,7 @@ OBJS-common = \ tree-ssa-operands.o \ tree-ssa-phiopt.o \ tree-ssa-pre.o \ + tree-ssa-pressure.o \ tree-ssa-propagate.o \ tree-ssa-reassoc.o \ tree-ssa-sink.o \ @@ -1924,6 +1925,10 @@ tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ $(TREE_SSA_LIVE_H) bitmap.h $(FLAGS_H) $(HASHTAB_H) toplev.h +tree-ssa-pressure.o : tree-ssa-pressure.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ + $(TREE_SSA_LIVE_H) bitmap.h $(FLAGS_H) $(HASHTAB_H) toplev.h \ + tree-ssa-pressure.h tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) bitmap.h $(GGC_H) toplev.h diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 7e759ba8176..6092770793c 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -34,6 +34,7 @@ Boston, MA 02110-1301, USA. */ #include "tree-ssa-live.h" #include "tree-pass.h" #include "toplev.h" +#include "tree-ssa-pressure.h" /* Used to hold all the components required to do SSA PHI elimination. @@ -1139,6 +1140,14 @@ remove_ssa_form (bool perform_ter) map = coalesce_ssa_name (); + if (dump_file) + { + pressure_table_p p; + p = calculate_name_pressure (PRESS_INTEGER|PRESS_FLOAT, NULL); + dump_ssa_pressure (dump_file, p); + delete_pressure_table (p); + } + /* Return to viewing the variable list as just all reference variables after coalescing has been performed. */ partition_view_normal (map, false); diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 7e98e2cf8e8..b60e89528fa 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -542,6 +542,8 @@ new_tree_live_info (var_map map) live->work_stack = XNEWVEC (int, last_basic_block); live->stack_top = live->work_stack; + live->dead_on_exit = NULL; + live->global = BITMAP_ALLOC (NULL); return live; } @@ -565,6 +567,11 @@ delete_tree_live_info (tree_live_info_p live) BITMAP_FREE (live->livein[x]); free (live->livein); + if (live->dead_on_exit) + for (x = live->num_blocks - 1; x >= 0; x--) + BITMAP_FREE (live->dead_on_exit[x]); + free (live->dead_on_exit); + free (live); } @@ -716,7 +723,7 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live) /* Calculate the live on exit vectors based on the entry info in LIVEINFO. */ -void +static void calculate_live_on_exit (tree_live_info_p liveinfo) { unsigned i; @@ -757,6 +764,47 @@ calculate_live_on_exit (tree_live_info_p liveinfo) } +/* Calculate the dead on exit vectors based on the entry and exit info in + LIVEINFO. Dead on exit are partitions which are used as PHI arguments in + successor blocks, but have no further uses. */ + +void +calculate_dead_on_exit (tree_live_info_p live) +{ + bitmap *doe, b; + basic_block bb; + edge e; + edge_iterator ei; + bitmap l = BITMAP_ALLOC (NULL); + + gcc_assert (live->liveout); + gcc_assert (n_basic_blocks == live->num_blocks); + + doe = XCNEWVEC (bitmap, n_basic_blocks); + + FOR_EACH_BB (bb) + { + b = BITMAP_ALLOC (NULL); + bitmap_clear (l); + /* Calculate all partitions which are live on entry to a successor. */ + FOR_EACH_EDGE (e, ei, bb->succs) + { + if (e->dest == EXIT_BLOCK_PTR) + continue; + bitmap_ior_into (l, live_on_entry (live, e->dest)); + } + /* Now calculate dead on exit by finding those that are live at exit + and NOT live on entry to a successor. Thse are the ssa_names which + go dead in PHI's, and thus go dead in a copy on an exit edge to BB. */ + bitmap_and_compl (b, live_on_exit (live, bb), l); + doe[bb->index] = b; + } + + BITMAP_FREE (l); + live->dead_on_exit = doe; +} + + /* Given partition map MAP, calculate all the live on entry bitmaps for each partition. Return a new live info object. */ diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h index d0aeedf08df..85437e7ff91 100644 --- a/gcc/tree-ssa-live.h +++ b/gcc/tree-ssa-live.h @@ -274,11 +274,17 @@ typedef struct tree_live_info_d /* Bitmap of what variables are live on exit for a basic blocks. */ bitmap *liveout; + + /* Bitmap of what variables are dead on exit. This is defined as the + variables which are used in PHI arguments on at least one exit edge + from a block, but are not used beyond that. These are variables which + will have a use inserted on the exit edge during out of ssa. */ + bitmap *dead_on_exit; } *tree_live_info_p; extern tree_live_info_p calculate_live_ranges (var_map); -extern void calculate_live_on_exit (tree_live_info_p); +extern void calculate_dead_on_exit (tree_live_info_p); extern void delete_tree_live_info (tree_live_info_p); #define LIVEDUMP_ENTRY 0x01 @@ -325,6 +331,21 @@ live_on_exit (tree_live_info_p live, basic_block bb) } +/* Return the bitmap from LIVE representing the dead on exit partitions from + block BB. */ + +static inline bitmap +dead_on_exit (tree_live_info_p live, basic_block bb) +{ + gcc_assert (live->dead_on_exit); + gcc_assert (bb != ENTRY_BLOCK_PTR); + gcc_assert (bb != EXIT_BLOCK_PTR); + + return live->dead_on_exit[bb->index]; +} + + + /* Return the partition map which the information in LIVE utilizes. */ static inline var_map diff --git a/gcc/tree-ssa-pressure.c b/gcc/tree-ssa-pressure.c new file mode 100644 index 00000000000..0846b59e874 --- /dev/null +++ b/gcc/tree-ssa-pressure.c @@ -0,0 +1,433 @@ +/* Calculate and Manage SSA_NAME pressure. + Copyright (C) 2006 Free Software Foundation, Inc. + Contributed by Andrew MacLeod + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "flags.h" +#include "diagnostic.h" +#include "bitmap.h" +#include "tree-flow.h" +#include "hashtab.h" +#include "tree-dump.h" +#include "tree-ssa-live.h" +#include "toplev.h" +#include "tree-ssa-pressure.h" + + +/* Initialize pressure unit object PTR with NUM stmt's. */ + +static void +init_pressure_unit (pressure_unit_p ptr, unsigned num) +{ + ptr->bb_start_pressure = XCNEWVEC (int, n_basic_blocks); + ptr->stmt_pressure = XCNEWVEC (struct stmt_pressure_unit_d, num); + ptr->uid_limit = num; +} + + +/* Clear pressure unit PTR, freeing any memory associated with it. */ + +static void +clear_pressure_unit (pressure_unit_p ptr) +{ + unsigned x; + + for (x = 0; x < ptr->uid_limit; x++) + if (ptr->stmt_pressure[x].dead_partitions) + VEC_free (int, heap, ptr->stmt_pressure[x].dead_partitions); + + free (ptr->stmt_pressure); + free (ptr->bb_start_pressure); +} + + +/* Create a new pressure table with UID_LIMIT stmt's and using FLAGS to select + functional units. */ + +static pressure_table_p +new_pressure_table (int uid_limit, int flags) +{ + pressure_table_p tab; + int unit_count = 0; + int *ftu; + int x; + + ftu = xmalloc (sizeof (int) * (PRESS_MAX_FLAG + 1)); + memset (ftu, 0xff, sizeof (int) * (PRESS_MAX_FLAG + 1)); + + if (flags & PRESS_INTEGER) + ftu[PRESS_INTEGER] = unit_count++; + if (flags & PRESS_FLOAT) + ftu[PRESS_FLOAT] = unit_count++; + + tab = xmalloc (sizeof (struct pressure_table_d) + + sizeof (struct pressure_unit_d) * (unit_count - 1)); + + tab->flags = flags; + tab->unit_count = unit_count; + tab->flag_to_unit = ftu; + + for (x = 0; x < unit_count; x++) + init_pressure_unit (&(tab->unit[x]), uid_limit); + + return tab; +} + + +/* Delete pressure table TAB, freeing all associated memory. */ + +void +delete_pressure_table (pressure_table_p tab) +{ + int x; + + for (x = 0; x < tab->unit_count; x++) + clear_pressure_unit (&(tab->unit[x])); + + delete_tree_live_info (tab->live_info); + if (tab->owns_map) + delete_var_map (tab->map); + free (tab->flag_to_unit); + free (tab); +} + + +/* Get stmt pressure info for functional unit UNIT in STMT from table PTR. */ + +static inline stmt_pressure_unit_p +get_stmt_pressure_from_table (tree stmt, pressure_table_p ptr, int unit) +{ + unsigned uid = stmt_ann (stmt)->uid; + pressure_unit_p p; + + gcc_assert (unit < ptr->unit_count); + + p = &(ptr->unit[unit]); + gcc_assert (uid < p->uid_limit); + return &(p->stmt_pressure[uid]); +} + + + +/* Add SSA_VAR to MAP if it is a type specified in FLAGS. */ + +static void +register_ssa_name (var_map map, tree ssa_var, int flags) +{ + /* Checking to see if its a partition already is a lot cheaper than + determining the type first. */ + if (var_to_partition (map, ssa_var) != NO_PARTITION) + { + if (unit_type (ssa_var) & flags) + register_ssa_partition (map, ssa_var); + } +} + + + +/* Add PARTITION to thr dead list of SP if it isn't already there. */ + +static void +add_to_dead_list (int partition, stmt_pressure_unit_p sp) +{ + if (sp->dead_partitions == NULL) + sp->dead_partitions = VEC_alloc (int, heap, 3); + else + if (in_dead_list_p (partition, sp)) + return; + + VEC_safe_push (int, heap, sp->dead_partitions, partition); +} + + +/* Process a use of PARTITION in STMT. If it is already in LIVE, then no action + needs to be taken. Otherwise this represents the last use of the partition. + That means the partition is dead at this stmt, and should be added to the + live list (since the block is being processed in reverse. TAB is the + pressure table. */ + + +static inline void +maybe_goes_dead (int partition, tree stmt, bitmap live, pressure_table_p tab) +{ + pressure_unit_p press; + stmt_pressure_unit_p ptr; + + /* If its already live, then it doesn't go dead at this stmt. */ + if (bitmap_bit_p (live, partition)) + return; + + bitmap_set_bit (live, partition); + press = get_partition_unit (partition, tab); + ptr = get_stmt_pressure (stmt, press); + ptr->pressure_change -= 1; + add_to_dead_list (partition, ptr); +} + + +/* Process a def of PARTITION in STMT. If the def is dead (has no uses) it + will not be in LIVE. In any case, it must be removed from LIVE since this + marks the beginning of a live range, and the block is being stepped through + in reverse. TAB is the pressure table. */ + +static inline void +comes_alive (int partition, tree stmt, bitmap live, pressure_table_p tab) +{ + pressure_unit_p press = get_partition_unit (partition, tab); + stmt_pressure_unit_p ptr = get_stmt_pressure (stmt, press); + + if (bitmap_bit_p (live, partition)) + { + bitmap_clear_bit (live, partition); + ptr->pressure_change += 1; + } + else + add_to_dead_list (partition, ptr); +} + + +/* Main entry point which creates a pressure table for the functional units + specified in FLAGS. */ + +pressure_table_p +calculate_name_pressure (int flags, var_map vmap) +{ + var_map map; + tree var, stmt, phi; + tree_live_info_p live_info; + bitmap live; + pressure_table_p press; + basic_block bb; + block_stmt_iterator bsi; + ssa_op_iter iter; + int i; + unsigned uid = 0; + unsigned x; + bitmap_iterator bi; + + if (vmap == NULL) + { + map = init_var_map (num_ssa_names + 1); + + /* register all the partitions the pressure table cares about. */ + FOR_EACH_BB (bb) + { + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) + { + if (!is_gimple_reg (PHI_RESULT (phi))) + continue; + + register_ssa_name (map, PHI_RESULT (phi), flags); + for (i = 0; i < PHI_NUM_ARGS (phi); i++) + { + var = PHI_ARG_DEF (phi, i); + if (TREE_CODE (var) == SSA_NAME) + register_ssa_name (map, var, flags); + } + } + + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + { + stmt = bsi_stmt (bsi); + stmt_ann (stmt)->uid = uid++; + FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, + (SSA_OP_DEF|SSA_OP_USE)) + register_ssa_name (map, var, flags); + } + } + } + else + { + map = vmap; + /* Calculate a UID for each stmt. */ + FOR_EACH_BB (bb) + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + stmt_ann (bsi_stmt (bsi))->uid = uid++; + } + + /* Now view the partition normally, with all unused ssa_names removed. */ + partition_view_normal (map, false); + + press = new_pressure_table (uid, flags); + press->map = map; + press->owns_map = (vmap == NULL); + + /* calculate the live range info. */ + live_info = calculate_live_ranges (map); + calculate_dead_on_exit (live_info); + press->live_info = live_info; + + + /* Walk through each basic block in reversem tracking which partitions are + live, and creating entries in the pressure table for each stmt. */ + live = BITMAP_ALLOC (NULL); + FOR_EACH_BB (bb) + { + int p; + + /* Walk each stmt. */ + bitmap_copy (live, live_on_exit (live_info, bb)); + for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi)) + { + stmt = bsi_stmt (bsi); + FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF) + if ((p = var_to_partition (map, var)) != NO_PARTITION) + comes_alive (p, stmt, live, press); + FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE) + if ((p = var_to_partition (map, var)) != NO_PARTITION) + maybe_goes_dead (p, stmt, live, press); + } + + /* Calculate starting register pressure in each block for each unit. */ + EXECUTE_IF_SET_IN_BITMAP (live_on_entry (live_info, bb), 0, x, bi) + { + pressure_unit_p p = get_partition_unit (x, press); + p->bb_start_pressure[bb->index]++; + } + + /* Add PHI results to the starting register pressure since they map to + copies on incoming edges during out-of-ssa. */ + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) + { + int part = var_to_partition (map, PHI_RESULT (phi)); + if (part != NO_PARTITION) + { + pressure_unit_p p = get_partition_unit (part, press); + p->bb_start_pressure[bb->index]++; + } + } + } + BITMAP_FREE (live); + + return press; +} + + +/* Dump table PRESS to output file F in a readable form. */ + +void +dump_ssa_pressure (FILE *f, pressure_table_p press) +{ + basic_block bb; + block_stmt_iterator bsi; + tree stmt, phi, var; + int i; + unsigned x; + stmt_pressure_unit_p sp; + bitmap_iterator bi; + int *curr_press; + + curr_press = alloca (press->unit_count * sizeof (int)); + FOR_EACH_BB (bb) + { + for (i = 0; i < press->unit_count; i++) + { + curr_press[i] = get_start_unit_pressure (press, bb, i); + fprintf (f, "[%3d] ", curr_press[i]); + } + fprintf (f, "Basic Block %d. Live on entry: ", + bb->index); + + EXECUTE_IF_SET_IN_BITMAP (live_on_entry (press->live_info, bb), 0, x, bi) + { + print_generic_expr (f, partition_to_var (press->map, x), TDF_SLIM); + fprintf(f, " "); + } + fprintf(f, "\n"); + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) + { + for (i = 0; i < press->unit_count; i++) + fprintf (f, " "); + if (var_to_partition (press->map, PHI_RESULT (phi)) == NO_PARTITION) + print_generic_stmt (f, phi, TDF_SLIM); + else + { + print_generic_expr (f, PHI_RESULT(phi), TDF_SLIM); + fprintf (f, " = PHI <"); + for (i = 0; i < PHI_NUM_ARGS (phi); i++) + { + basic_block bb_src= PHI_ARG_EDGE (phi, i)->src; + if (i != 0) + fprintf (f, ", "); + var = PHI_ARG_DEF (phi, i); + print_generic_expr (f, var, TDF_SLIM); + if (TREE_CODE (var) == SSA_NAME && + var_to_partition (press->map, var) != NO_PARTITION) + { + if (bitmap_bit_p (dead_on_exit(press->live_info, bb_src), + var_to_partition (press->map, var))) + fprintf (f, "##"); + } + fprintf (f, "(%1d)", bb_src->index); + } + fprintf (f, ">;\n"); + } + } + + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + { + bool dead_printed = false; + stmt = bsi_stmt (bsi); + for (i = 0; i < press->unit_count; i++) + { + sp = get_stmt_pressure_from_table (stmt, press, i); + curr_press[i] += sp->pressure_change; + fprintf (f, "[%3d] ", curr_press[i]); + } + print_generic_expr (f, stmt, TDF_SLIM); + for (i = 0; i < press->unit_count; i++) + { + sp = get_stmt_pressure_from_table (stmt, press, i); + if (sp->dead_partitions) + { + if (!dead_printed) + { + fprintf (f, " ##dead list## - "); + dead_printed = true; + } + for (x = 0; x < VEC_length (int, sp->dead_partitions); x++) + { + if (x != 0) + fprintf (f, ", "); + print_generic_expr (f, + partition_to_var (press->map, + VEC_index (int, + sp->dead_partitions, + x)), + TDF_SLIM); + } + } + } + fprintf (f, "\n"); + } + + fprintf (f, "Dead on exit : "); + EXECUTE_IF_SET_IN_BITMAP (dead_on_exit (press->live_info, bb), 0, x, bi) + { + print_generic_expr (f, partition_to_var (press->map, x), TDF_SLIM); + fprintf(f, " "); + } + fprintf (f, "\n\n"); + } +} diff --git a/gcc/tree-ssa-pressure.h b/gcc/tree-ssa-pressure.h new file mode 100644 index 00000000000..a6a05431b42 --- /dev/null +++ b/gcc/tree-ssa-pressure.h @@ -0,0 +1,200 @@ +/* Header file for calculating and Managing SSA_NAME pressure. + Copyright (C) 2006 Free Software Foundation, Inc. + Contributed by Andrew MacLeod + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + +#include "vec.h" + +#ifndef _TREE_SSA_PRESSURE_H +#define _TREE_SSA_PRESSURE_H + + +/* This structure represents the changes in register pressure within a stmt. */ + +typedef struct stmt_pressure_unit_d +{ + int pressure_change; /* Change in register pressure. */ + VEC(int,heap) *dead_partitions; /* List of dead registers. */ +} *stmt_pressure_unit_p; + + +/* Dynamic vector used to represent register pressure changes for any + new stmt's which have been created since the table was created. */ +DEF_VEC_P(stmt_pressure_unit_p); +DEF_VEC_ALLOC_P(stmt_pressure_unit_p,heap); + + +/* This represents the register pressure in the function for a single register + type. */ + +typedef struct pressure_unit_d +{ + unsigned uid_limit; /* Upper UID of original stmts. */ + int *bb_start_pressure; /* Vector of starting pressures. */ + stmt_pressure_unit_p stmt_pressure; /* Stmt pressure vector. */ +} *pressure_unit_p; + + +/* This represents register pressure for the entire function for multiple + functional units. It also contains all the live range info. */ + +typedef struct pressure_table_d +{ + int flags; /* Flag for selecting units. */ + int unit_count; /* Number of functional units. */ + int *flag_to_unit; /* Convert flag bit to unit number. */ + bool owns_map; /* Created var_map. */ + var_map map; /* Partition map. */ + tree_live_info_p live_info; /* Live range info. */ + struct pressure_unit_d unit[1]; /* Stmt pressure units. */ +} *pressure_table_p; + +extern pressure_table_p calculate_name_pressure (int, var_map); +extern void delete_pressure_table (pressure_table_p); +extern void dump_ssa_pressure (FILE *, pressure_table_p); + +/* Funcitonal unit flags. */ + +#define PRESS_INTEGER 0x01 +#define PRESS_FLOAT 0x02 +#define PRESS_MAX_FLAG (PRESS_FLOAT|PRESS_INTEGER) + + +/* Return the BB starting pressure for UNIT in TAB. */ + +static inline int +get_start_unit_pressure (pressure_table_p tab, basic_block bb, int unit) +{ +#ifdef ENABLE_CHECKING + gcc_assert (unit >= 0 && unit < tab->unit_count); +#endif + return tab->unit[unit].bb_start_pressure[bb->index]; +} + + +/* Return the BB starting pressure for the unit specified by FLAG in TAB. */ + +static inline int +get_start_pressure (pressure_table_p tab, basic_block bb, int flag) +{ + int unit; + +#ifdef ENABLE_CHECKING + /* Make sure 'flags' is in a valid range. */ + gcc_assert ((flag & ~PRESS_MAX_FLAG) == 0); +#endif + + unit = tab->flag_to_unit[flag]; + return get_start_unit_pressure (tab, bb, unit); +} + + + +/* Return the flag representing the functional unit for SSA_NAME. */ +static int +unit_type (tree ssa_name) +{ + tree type; + int ret = 0; + gcc_assert (TREE_CODE (ssa_name) == SSA_NAME); + + type = TREE_TYPE (SSA_NAME_VAR (ssa_name)); + + if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) + ret = PRESS_INTEGER; + else + if (SCALAR_FLOAT_TYPE_P (type) || COMPLEX_FLOAT_TYPE_P (type)) + ret = PRESS_FLOAT; + + return ret; +} + + +/* Return the unit number PARTITION belongs to in table PRESS. */ + +static inline int +partition_unit (int partition, pressure_table_p press) +{ + tree name = partition_to_var (press->map, partition); + int ret = unit_type (name); + + gcc_assert (ret != 0); + return press->flag_to_unit[ret]; +} + + +/* Return the pressure unit pointer which PARITION belongs to in TAB. */ + +static pressure_unit_p +get_partition_unit (int partition, pressure_table_p tab) +{ + int u = partition_unit (partition, tab); + return &(tab->unit[u]); +} + + +/* Get stmt pressure info from function unit PTR for STMT. */ + +static inline stmt_pressure_unit_p +get_stmt_pressure (tree stmt, pressure_unit_p ptr) +{ + unsigned uid = stmt_ann (stmt)->uid; + gcc_assert (uid < ptr->uid_limit); + return &(ptr->stmt_pressure[uid]); +} + + +/* Return TRUE if PARTITION is in the dead list of SP. */ + +static inline bool +in_dead_list_p (int partition, stmt_pressure_unit_p sp) +{ + unsigned x; + + for (x = 0; x < VEC_length (int, sp->dead_partitions); x++) + if (VEC_index (int, sp->dead_partitions, x) == partition) + return true; + + return false; +} + + +static inline bool +dead_partition_in_stmt_p (pressure_table_p tab, tree stmt, int partition) +{ + pressure_unit_p unit_p; + stmt_pressure_unit_p stmt_press; + +#ifdef ENABLE_CHECKING + gcc_assert (partition != NO_PARTITION); +#endif + + unit_p = get_partition_unit (partition, tab); + stmt_press = get_stmt_pressure (stmt, unit_p); + return in_dead_list_p (partition, stmt_press); +} + +static inline bool +dead_name_in_stmt_p (pressure_table_p tab, tree stmt, tree ssa_name) +{ + int p = var_to_partition (tab->map, ssa_name); + return dead_partition_in_stmt_p (tab, stmt, p); +} + +#endif -- cgit v1.2.3