From: rth Date: Thu, 4 Aug 2005 23:37:00 +0000 (+0000) Subject: PR 21291 X-Git-Tag: upstream/4.9.2~59353 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0ec4b37dc723e9bc757b45ec5e7802eee34d54f3;p=platform%2Fupstream%2Flinaro-gcc.git PR 21291 * tree-outof-ssa.c (coalesce_asm_operands): New. (coalesce_ssa_name): Use it. Split out ... (coalesce_phi_operands, coalesce_result_decls): ... these. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102751 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f07a38e..f5a7b35 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-08-04 Richard Henderson + + PR 21291 + * tree-outof-ssa.c (coalesce_asm_operands): New. + (coalesce_ssa_name): Use it. Split out ... + (coalesce_phi_operands, coalesce_result_decls): ... these. + 2005-08-04 Paul Brook * read-rtl.c (read_quoted_string): Break if EOF. diff --git a/gcc/testsuite/gcc.target/i386/pr21291.c b/gcc/testsuite/gcc.target/i386/pr21291.c new file mode 100644 index 0000000..acfc43d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr21291.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +typedef unsigned long bngdigit; +typedef bngdigit *bng; +typedef unsigned int bngcarry; +typedef unsigned long bngsize; + +bngdigit +bng_ia32_mult_sub_digit (bng a, bngsize alen, bng b, bngsize blen, bngdigit d) +{ + bngdigit out, tmp; + bngcarry carry; + bngdigit a11; + + alen -= blen; + out = 0; + asm ("" + : "+r" (a), "+r" (b), "+mr" (blen), "+mr" (out), "=&r" (tmp) + : "mr" (d) + : "eax", "edx"); + if (alen == 0) + { + a11 = out; + goto t; + } + + a11 = 1; + t: + return a11; +} diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index b8ceaa8..3d83036 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -676,49 +676,26 @@ coalesce_abnormal_edges (var_map map, conflict_graph graph, root_var_p rv) } } +/* Coalesce potential copies via PHI arguments. */ -/* Reduce the number of live ranges in MAP. Live range information is - returned if FLAGS indicates that we are combining temporaries, otherwise - NULL is returned. The only partitions which are associated with actual - variables at this point are those which are forced to be coalesced for - various reason. (live on entry, live across abnormal edges, etc.). */ - -static tree_live_info_p -coalesce_ssa_name (var_map map, int flags) +static void +coalesce_phi_operands (var_map map, coalesce_list_p cl) { - unsigned num, x, i; - sbitmap live; - tree var, phi; - root_var_p rv; - tree_live_info_p liveinfo; - var_ann_t ann; - conflict_graph graph; basic_block bb; - coalesce_list_p cl = NULL; - sbitmap_iterator sbi; - - if (num_var_partitions (map) <= 1) - return NULL; - - liveinfo = calculate_live_on_entry (map); - calculate_live_on_exit (liveinfo); - rv = root_var_init (map); - - /* Remove single element variable from the list. */ - root_var_compact (rv); - - cl = create_coalesce_list (map); + tree phi; - /* Add all potential copies via PHI arguments to the list. */ FOR_EACH_BB (bb) { for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) { tree res = PHI_RESULT (phi); int p = var_to_partition (map, res); + int x; + if (p == NO_PARTITION) continue; - for (x = 0; x < (unsigned)PHI_NUM_ARGS (phi); x++) + + for (x = 0; x < PHI_NUM_ARGS (phi); x++) { tree arg = PHI_ARG_DEF (phi, x); int p2; @@ -739,14 +716,20 @@ coalesce_ssa_name (var_map map, int flags) } } } +} - /* Coalesce all the result decls together. */ - var = NULL_TREE; - i = 0; - for (x = 0; x < num_var_partitions (map); x++) +/* Coalesce all the result decls together. */ + +static void +coalesce_result_decls (var_map map, coalesce_list_p cl) +{ + unsigned int i, x; + tree var = NULL; + + for (i = x = 0; x < num_var_partitions (map); x++) { tree p = partition_to_var (map, x); - if (TREE_CODE (SSA_NAME_VAR(p)) == RESULT_DECL) + if (TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL) { if (var == NULL_TREE) { @@ -760,6 +743,100 @@ coalesce_ssa_name (var_map map, int flags) false)); } } +} + +/* Coalesce matching constraints in asms. */ + +static void +coalesce_asm_operands (var_map map, coalesce_list_p cl) +{ + basic_block bb; + + FOR_EACH_BB (bb) + { + block_stmt_iterator bsi; + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + { + tree stmt = bsi_stmt (bsi); + unsigned long noutputs, i; + tree *outputs, link; + + if (TREE_CODE (stmt) != ASM_EXPR) + continue; + + noutputs = list_length (ASM_OUTPUTS (stmt)); + outputs = (tree *) alloca (noutputs * sizeof (tree)); + for (i = 0, link = ASM_OUTPUTS (stmt); link; + ++i, link = TREE_CHAIN (link)) + outputs[i] = TREE_VALUE (link); + + for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link)) + { + const char *constraint + = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); + tree input = TREE_VALUE (link); + char *end; + unsigned long match; + int p1, p2; + + if (TREE_CODE (input) != SSA_NAME && !DECL_P (input)) + continue; + + match = strtoul (constraint, &end, 10); + if (match >= noutputs || end == constraint) + continue; + + if (TREE_CODE (outputs[match]) != SSA_NAME + && !DECL_P (outputs[match])) + continue; + + p1 = var_to_partition (map, outputs[match]); + if (p1 == NO_PARTITION) + continue; + p2 = var_to_partition (map, input); + if (p2 == NO_PARTITION) + continue; + + add_coalesce (cl, p1, p2, coalesce_cost (REG_BR_PROB_BASE, + maybe_hot_bb_p (bb), + false)); + } + } + } +} + +/* Reduce the number of live ranges in MAP. Live range information is + returned if FLAGS indicates that we are combining temporaries, otherwise + NULL is returned. The only partitions which are associated with actual + variables at this point are those which are forced to be coalesced for + various reason. (live on entry, live across abnormal edges, etc.). */ + +static tree_live_info_p +coalesce_ssa_name (var_map map, int flags) +{ + unsigned num, x; + sbitmap live; + root_var_p rv; + tree_live_info_p liveinfo; + conflict_graph graph; + coalesce_list_p cl = NULL; + sbitmap_iterator sbi; + + if (num_var_partitions (map) <= 1) + return NULL; + + liveinfo = calculate_live_on_entry (map); + calculate_live_on_exit (liveinfo); + rv = root_var_init (map); + + /* Remove single element variable from the list. */ + root_var_compact (rv); + + cl = create_coalesce_list (map); + + coalesce_phi_operands (map, cl); + coalesce_result_decls (map, cl); + coalesce_asm_operands (map, cl); /* Build a conflict graph. */ graph = build_tree_conflict_graph (liveinfo, rv, cl); @@ -787,14 +864,14 @@ coalesce_ssa_name (var_map map, int flags) /* First, coalesce all live on entry variables to their root variable. This will ensure the first use is coming from the correct location. */ - live = sbitmap_alloc (num_var_partitions (map)); + num = num_var_partitions (map); + live = sbitmap_alloc (num); sbitmap_zero (live); /* Set 'live' vector to indicate live on entry partitions. */ - num = num_var_partitions (map); for (x = 0 ; x < num; x++) { - var = partition_to_var (map, x); + tree var = partition_to_var (map, x); if (default_def (SSA_NAME_VAR (var)) == var) SET_BIT (live, x); } @@ -809,8 +886,8 @@ coalesce_ssa_name (var_map map, int flags) partition. */ EXECUTE_IF_SET_IN_SBITMAP (live, 0, x, sbi) { - var = root_var (rv, root_var_find (rv, x)); - ann = var_ann (var); + tree var = root_var (rv, root_var_find (rv, x)); + var_ann_t ann = var_ann (var); /* If these aren't already coalesced... */ if (partition_to_var (map, x) != var) {