diff options
author | Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> | 2009-03-31 21:23:29 +0000 |
---|---|---|
committer | Ramana Radhakrishnan <ramana@gcc.gnu.org> | 2009-03-31 21:23:29 +0000 |
commit | 824523999285e704ff2c549d8dbd8d20bb1c6ac0 (patch) | |
tree | 5ad82d1f0bc2b3f9ef01549ecef14b0054cb9fed /gcc | |
parent | 207bf79d7f23a3883694578f431c08960c348e38 (diff) | |
download | gcc-824523999285e704ff2c549d8dbd8d20bb1c6ac0.zip gcc-824523999285e704ff2c549d8dbd8d20bb1c6ac0.tar.gz gcc-824523999285e704ff2c549d8dbd8d20bb1c6ac0.tar.bz2 |
common.opt (frtl-abstract-sequences): Delete.
2009-03-31 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* common.opt (frtl-abstract-sequences): Delete.
* doc/invoke.texi (Option Summary): Likewise.
(Optimize Options): Likewise.
* rtl-factoring.c: Delete file.
* Makefile.in (OBJS-common): Remove rtl-factoring.o.
* passes.c (init_optimization_passes): Remove rtl_abstr_seq pass.
2009-03-31 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* gcc.c-torture/compile/pr33009.c: Delete.
* gcc.c-torture/compile/pr11832.c: Likewise.
From-SVN: r145374
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/Makefile.in | 5 | ||||
-rw-r--r-- | gcc/common.opt | 4 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 10 | ||||
-rw-r--r-- | gcc/passes.c | 1 | ||||
-rw-r--r-- | gcc/rtl-factoring.c | 1474 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr11832.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr33009.c | 41 |
8 files changed, 6 insertions, 1569 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 5d0e4a8..79780e9 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1169,7 +1169,6 @@ OBJS-common = \ reorg.o \ resource.o \ rtl-error.o \ - rtl-factoring.o \ rtl.o \ rtlanal.o \ rtlhooks.o \ @@ -2193,10 +2192,6 @@ tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_DUMP_H) $(EXCEPT_H) langhooks.h $(CFGLOOP_H) tree-pass.h \ $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) $(TOPLEV_H) \ tree-ssa-propagate.h tree-scalar-evolution.h -rtl-factoring.o : rtl-factoring.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ - coretypes.h $(TM_H) $(BASIC_BLOCK_H) $(RESOURCE_H) $(GGC_H) $(REGS_H) \ - $(PARAMS_H) $(EXPR_H) addresses.h $(TM_P_H) tree-pass.h $(TREE_FLOW_H) \ - $(TIMEVAR_H) output.h $(DF_H) tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(EXCEPT_H) tree-pass.h $(FLAGS_H) langhooks.h \ diff --git a/gcc/common.opt b/gcc/common.opt index 3626c9e..1cc0ac2 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1037,10 +1037,6 @@ fsection-anchors Common Report Var(flag_section_anchors) Optimization Access data in the same section from shared anchor points -frtl-abstract-sequences -Common Report Var(flag_rtl_seqabstr) Optimization -Perform sequence abstraction optimization on RTL - fsee Common Report Var(flag_see) Init(0) Eliminate redundant sign extensions using LCM. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index b2a764a..131633d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -356,7 +356,7 @@ Objective-C and Objective-C++ Dialects}. -freciprocal-math -fregmove -frename-registers -freorder-blocks @gol -freorder-blocks-and-partition -freorder-functions @gol -frerun-cse-after-loop -freschedule-modulo-scheduled-loops @gol --frounding-math -frtl-abstract-sequences -fsched2-use-superblocks @gol +-frounding-math -fsched2-use-superblocks @gol -fsched2-use-traces -fsched-spec-load -fsched-spec-load-dangerous @gol -fsched-stalled-insns-dep[=@var{n}] -fsched-stalled-insns[=@var{n}] @gol -fschedule-insns -fschedule-insns2 -fsection-anchors -fsee @gol @@ -6954,14 +6954,6 @@ Future versions of GCC may provide finer control of this setting using C99's @code{FENV_ACCESS} pragma. This command line option will be used to specify the default state for @code{FENV_ACCESS}. -@item -frtl-abstract-sequences -@opindex frtl-abstract-sequences -It is a size optimization method. This option is to find identical -sequences of code, which can be turned into pseudo-procedures and -then replace all occurrences with calls to the newly created -subroutine. It is kind of an opposite of @option{-finline-functions}. -This optimization runs at RTL level. - @item -fsignaling-nans @opindex fsignaling-nans Compile code assuming that IEEE signaling NaNs may generate user-visible diff --git a/gcc/passes.c b/gcc/passes.c index 4e8944a..6ebceb3 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -787,7 +787,6 @@ init_optimization_passes (void) NEXT_PASS (pass_branch_target_load_optimize1); NEXT_PASS (pass_thread_prologue_and_epilogue); NEXT_PASS (pass_rtl_dse2); - NEXT_PASS (pass_rtl_seqabstr); NEXT_PASS (pass_stack_adjustments); NEXT_PASS (pass_peephole2); NEXT_PASS (pass_if_after_reload); diff --git a/gcc/rtl-factoring.c b/gcc/rtl-factoring.c deleted file mode 100644 index 4c879691..0000000 --- a/gcc/rtl-factoring.c +++ /dev/null @@ -1,1474 +0,0 @@ -/* RTL factoring (sequence abstraction). - Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - -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 3, 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 COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "rtl.h" -#include "obstack.h" -#include "basic-block.h" -#include "resource.h" -#include "flags.h" -#include "ggc.h" -#include "regs.h" -#include "params.h" -#include "expr.h" -#include "tm_p.h" -#include "tree-pass.h" -#include "tree-flow.h" -#include "timevar.h" -#include "output.h" -#include "df.h" -#include "addresses.h" - -/* Sequence abstraction: - - It is a size optimization method. The main idea of this technique is to - find identical sequences of code, which can be turned into procedures and - then replace all occurrences with calls to the newly created subroutine. - It is kind of an opposite of function inlining. - - There are four major parts of this file: - - sequence fingerprint - In order to avoid the comparison of every insn with every other, hash - value will be designed for every insn by COMPUTE_HASH. - These hash values are used for grouping the sequence candidates. So - we only need to compare every insn with every other in same hash group. - - FILL_HASH_BUCKET creates all hash values and stores into HASH_BUCKETS. - The result is used by COLLECT_PATTERN_SEQS. - - code matching - In code matching the algorithm compares every two possible sequence - candidates which last insns are in the same hash group. If these - sequences are identical they will be stored and do further searches for - finding more sequences which are identical with the first one. - - COLLECT_PATTERN_SEQS does the code matching and stores the results into - PATTERN_SEQS. - - gain computation - This part computes the gain of abstraction which could be archived when - turning the pattern sequence into a pseudo-function and its matching - sequences into pseudo-calls. After it the most effective sequences will - be marked for abstraction. - - RECOMPUTE_GAIN does the gain computation. The sequences with the maximum - gain is on the top of PATTERN_SEQS. - - abstract code - This part turns the pattern sequence into a pseudo-function and its - matching sequences into pseudo-calls. - - ABSTRACT_BEST_SEQ does the code merging. - - - C code example: - - // Original source // After sequence abstraction - { { - void *jump_label; - ... ... - jump_label = &&exit_0; - entry_0: - I0; I0; - I1; I1; - I2; I2; - I3; I3; - goto *jump_label; - exit_0: - ... ... - jump_label = &&exit_1; - goto entry_0; - I0; - I1; - I2; - I3; - exit_1: - ... ... - jump_label = &&exit_2; - goto entry_0; - I0; - I1; - I2; - I3; - exit_2: - ... ... - jump_label = &&exit_3; - goto entry_0; - I0; - I1; - I2; - I3; - exit_3: - ... ... - } } - - - TODO: - - Use REG_ALLOC_ORDER when choosing link register. - - Handle JUMP_INSNs. Also handle volatile function calls (handle them - similar to unconditional jumps.) - - Test command line option -fpic. -*/ - -/* Predicate yielding nonzero iff X is an abstractable insn. Non-jump insns are - abstractable. */ -#define ABSTRACTABLE_INSN_P(X) (INSN_P (X) && !JUMP_P (X)) - -/* First parameter of the htab_create function call. */ -#define HASH_INIT 1023 - -/* Multiplier for cost of sequence call to avoid abstracting short - sequences. */ -#ifndef SEQ_CALL_COST_MULTIPLIER -#define SEQ_CALL_COST_MULTIPLIER 2 -#endif - -/* Recomputes the cost of MSEQ pattern/matching sequence. */ -#define RECOMPUTE_COST(SEQ) \ -{ \ - int l; \ - rtx x = SEQ->insn; \ - SEQ->cost = 0; \ - for (l = 0; l < SEQ->abstracted_length; l++) \ - { \ - SEQ->cost += compute_rtx_cost (x); \ - x = prev_insn_in_block (x); \ - } \ -} - -/* A sequence matching a pattern sequence. */ -typedef struct matching_seq_def -{ - /* The last insn in the matching sequence. */ - rtx insn; - - /* Index of INSN instruction. */ - unsigned long idx; - - /* The number of insns matching in this sequence and the pattern sequence. - */ - int matching_length; - - /* The number of insns selected to abstract from this sequence. Less than - or equal to MATCHING_LENGTH. */ - int abstracted_length; - - /* The cost of the sequence. */ - int cost; - - /* The next sequence in the chain matching the same pattern. */ - struct matching_seq_def *next_matching_seq; -} *matching_seq; - - -/* A pattern instruction sequence. */ -typedef struct pattern_seq_def -{ - /* The last insn in the pattern sequence. */ - rtx insn; - - /* Index of INSN instruction. */ - unsigned long idx; - - /* The gain of transforming the pattern sequence into a pseudo-function and - the matching sequences into pseudo-calls. */ - int gain; - - /* The maximum of the ABSTRACTED_LENGTH of the matching sequences. */ - int abstracted_length; - - /* The cost of the sequence. */ - int cost; - - /* The register used to hold the return address during the pseudo-call. */ - rtx link_reg; - - /* The sequences matching this pattern. */ - matching_seq matching_seqs; - - /* The next pattern sequence in the chain. */ - struct pattern_seq_def *next_pattern_seq; -} *pattern_seq; - - -/* A block of a pattern sequence. */ -typedef struct seq_block_def -{ - /* The number of insns in the block. */ - int length; - - /* The code_label of the block. */ - rtx label; - - /* The sequences entering the pattern sequence at LABEL. */ - matching_seq matching_seqs; - - /* The next block in the chain. The blocks are sorted by LENGTH in - ascending order. */ - struct seq_block_def *next_seq_block; -} *seq_block; - -/* Contains same sequence candidates for further searching. */ -typedef struct hash_bucket_def -{ - /* The hash value of the group. */ - unsigned int hash; - - /* List of sequence candidates. */ - htab_t seq_candidates; -} *p_hash_bucket; -typedef const struct hash_bucket_def *const_p_hash_bucket; - -/* Contains the last insn of the sequence, and its index value. */ -typedef struct hash_elem_def -{ - /* Unique index; ordered by FILL_HASH_BUCKET. */ - unsigned long idx; - - /* The last insn in the sequence. */ - rtx insn; - - /* The cached length of the insn. */ - int length; -} *p_hash_elem; -typedef const struct hash_elem_def *const_p_hash_elem; - -/* The list of same sequence candidates. */ -static htab_t hash_buckets; - -/* The pattern sequences collected from the current functions. */ -static pattern_seq pattern_seqs; - -/* The blocks of the current pattern sequence. */ -static seq_block seq_blocks; - -/* Cost of calling sequence. */ -static int seq_call_cost; - -/* Cost of jump. */ -static int seq_jump_cost; - -/* Cost of returning. */ -static int seq_return_cost; - -/* Returns the first insn preceding INSN for which INSN_P is true and belongs to - the same basic block. Returns NULL_RTX if no such insn can be found. */ - -static rtx -prev_insn_in_block (rtx insn) -{ - basic_block bb = BLOCK_FOR_INSN (insn); - - if (!bb) - return NULL_RTX; - - while (insn != BB_HEAD (bb)) - { - insn = PREV_INSN (insn); - if (INSN_P (insn)) - return insn; - } - return NULL_RTX; -} - -/* Returns the hash value of INSN. */ - -static unsigned int -compute_hash (rtx insn) -{ - unsigned int hash = 0; - rtx prev; - - hash = INSN_CODE (insn) * 100; - - prev = prev_insn_in_block (insn); - if (prev) - hash += INSN_CODE (prev); - - return hash; -} - -/* Compute the cost of INSN rtx for abstraction. */ - -static int -compute_rtx_cost (rtx insn) -{ - struct hash_bucket_def tmp_bucket; - p_hash_bucket bucket; - struct hash_elem_def tmp_elem; - p_hash_elem elem = NULL; - int cost = -1; - - /* Compute hash value for INSN. */ - tmp_bucket.hash = compute_hash (insn); - - /* Select the hash group. */ - bucket = (p_hash_bucket) htab_find (hash_buckets, &tmp_bucket); - - if (bucket) - { - tmp_elem.insn = insn; - - /* Select the insn. */ - elem = (p_hash_elem) htab_find (bucket->seq_candidates, &tmp_elem); - - /* If INSN is parsed the cost will be the cached length. */ - if (elem) - cost = elem->length; - } - - /* If we can't parse the INSN cost will be the instruction length. */ - if (cost == -1) - { - cost = get_attr_length (insn); - - /* Cache the length. */ - if (elem) - elem->length = cost; - } - - /* If we can't get an accurate estimate for a complex instruction, - assume that it has the same cost as a single fast instruction. */ - return cost != 0 ? cost : COSTS_N_INSNS (1); -} - -/* Determines the number of common insns in the sequences ending in INSN1 and - INSN2. Returns with LEN number of common insns and COST cost of sequence. -*/ - -static void -matching_length (rtx insn1, rtx insn2, int* len, int* cost) -{ - rtx x1; - rtx x2; - - x1 = insn1; - x2 = insn2; - *len = 0; - *cost = 0; - while (x1 && x2 && (x1 != insn2) && (x2 != insn1) - && rtx_equal_p (PATTERN (x1), PATTERN (x2))) - { - (*len)++; - (*cost) += compute_rtx_cost (x1); - x1 = prev_insn_in_block (x1); - x2 = prev_insn_in_block (x2); - } -} - -/* Adds E0 as a pattern sequence to PATTERN_SEQS with E1 as a matching - sequence. */ - -static void -match_seqs (p_hash_elem e0, p_hash_elem e1) -{ - int len; - int cost; - matching_seq mseq, p_prev, p_next; - - /* Determines the cost of the sequence and return without doing anything - if it is too small to produce any gain. */ - matching_length (e0->insn, e1->insn, &len, &cost); - if (cost <= seq_call_cost) - return; - - /* Prepend a new PATTERN_SEQ to PATTERN_SEQS if the last pattern sequence - does not end in E0->INSN. This assumes that once the E0->INSN changes - the old value will never appear again. */ - if (!pattern_seqs || pattern_seqs->insn != e0->insn) - { - pattern_seq pseq = - (pattern_seq) xmalloc (sizeof (struct pattern_seq_def)); - pseq->insn = e0->insn; - pseq->idx = e0->idx; - pseq->gain = 0; /* Set to zero to force recomputing. */ - pseq->abstracted_length = 0; - pseq->cost = 0; - pseq->link_reg = NULL_RTX; - pseq->matching_seqs = NULL; - pseq->next_pattern_seq = pattern_seqs; - pattern_seqs = pseq; - } - - /* Find the position of E1 in the matching sequences list. */ - p_prev = NULL; - p_next = pattern_seqs->matching_seqs; - while (p_next && p_next->idx < e1->idx) - { - p_prev = p_next; - p_next = p_next->next_matching_seq; - } - - /* Add a new E1 matching sequence to the pattern sequence. We know that - it ends in E0->INSN. */ - mseq = (matching_seq) xmalloc (sizeof (struct matching_seq_def)); - mseq->insn = e1->insn; - mseq->idx = e1->idx; - mseq->matching_length = len; - mseq->abstracted_length = 0; - mseq->cost = cost; - - if (p_prev == NULL) - pattern_seqs->matching_seqs = mseq; - else - p_prev->next_matching_seq = mseq; - mseq->next_matching_seq = p_next; -} - -/* Collects all pattern sequences and their matching sequences and puts them - into PATTERN_SEQS. */ - -static void -collect_pattern_seqs (void) -{ - htab_iterator hti0, hti1, hti2; - p_hash_bucket hash_bucket; - p_hash_elem e0, e1; -#if defined STACK_REGS || defined HAVE_cc0 - basic_block bb; - bitmap_head dont_collect; - - /* Extra initialization step to ensure that no stack registers (if present) - or cc0 code (if present) are live across abnormal edges. - Set a flag in DONT_COLLECT for an insn if a stack register is live - after the insn or the insn is cc0 setter or user. */ - bitmap_initialize (&dont_collect, NULL); - -#ifdef STACK_REGS - FOR_EACH_BB (bb) - { - regset_head live; - rtx insn; - rtx prev; - - /* Initialize liveness propagation. */ - INIT_REG_SET (&live); - bitmap_copy (&live, DF_LR_OUT (bb)); - df_simulate_initialize_backwards (bb, &live); - - /* Propagate liveness info and mark insns where a stack reg is live. */ - insn = BB_END (bb); - for (insn = BB_END (bb); ; insn = prev) - { - prev = PREV_INSN (insn); - if (INSN_P (insn)) - { - int reg; - for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++) - { - if (REGNO_REG_SET_P (&live, reg)) - { - bitmap_set_bit (&dont_collect, INSN_UID (insn)); - break; - } - } - - } - if (insn == BB_HEAD (bb)) - break; - df_simulate_one_insn_backwards (bb, insn, &live); - insn = prev; - } - - /* Free unused data. */ - CLEAR_REG_SET (&live); - } -#endif - -#ifdef HAVE_cc0 - /* Mark CC0 setters and users as ineligible for collection into sequences. - This is an over-conservative fix, since it is OK to include - a cc0_setter, but only if we also include the corresponding cc0_user, - and vice versa. */ - FOR_EACH_BB (bb) - { - rtx insn; - rtx next_tail; - - next_tail = NEXT_INSN (BB_END (bb)); - - for (insn = BB_HEAD (bb); insn != next_tail; insn = NEXT_INSN (insn)) - { - if (INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn))) - bitmap_set_bit (&dont_collect, INSN_UID (insn)); - } - } -#endif - -#endif /* defined STACK_REGS || defined HAVE_cc0 */ - - /* Initialize PATTERN_SEQS to empty. */ - pattern_seqs = 0; - - /* Try to match every abstractable insn with every other insn in the same - HASH_BUCKET. */ - - FOR_EACH_HTAB_ELEMENT (hash_buckets, hash_bucket, p_hash_bucket, hti0) - if (htab_elements (hash_bucket->seq_candidates) > 1) - FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e0, p_hash_elem, hti1) - FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e1, p_hash_elem, - hti2) - if (e0 != e1 -#if defined STACK_REGS || defined HAVE_cc0 - && !bitmap_bit_p (&dont_collect, INSN_UID (e0->insn)) - && !bitmap_bit_p (&dont_collect, INSN_UID (e1->insn)) -#endif - ) - match_seqs (e0, e1); -#if defined STACK_REGS || defined HAVE_cc0 - /* Free unused data. */ - bitmap_clear (&dont_collect); -#endif -} - -/* Transforms a regset to a HARD_REG_SET. Every hard register in REGS is added - to hregs. Additionally, the hard counterpart of every renumbered pseudo - register is also added. */ - -static void -renumbered_reg_set_to_hard_reg_set (HARD_REG_SET * hregs, regset regs) -{ - int r; - - REG_SET_TO_HARD_REG_SET (*hregs, regs); - for (r = FIRST_PSEUDO_REGISTER; r < max_regno; r++) - if (REGNO_REG_SET_P (regs, r) && reg_renumber[r] >= 0) - SET_HARD_REG_BIT (*hregs, reg_renumber[r]); -} - -/* Clears the bits in REGS for all registers, which are live in the sequence - give by its last INSN and its LENGTH. */ - -static void -clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length) -{ - basic_block bb; - regset_head live; - HARD_REG_SET hlive; - rtx x; - int i; - - /* Initialize liveness propagation. */ - bb = BLOCK_FOR_INSN (insn); - INIT_REG_SET (&live); - bitmap_copy (&live, DF_LR_OUT (bb)); - df_simulate_initialize_backwards (bb, &live); - - /* Propagate until INSN if found. */ - for (x = BB_END (bb); x != insn; x = PREV_INSN (x)) - df_simulate_one_insn_backwards (bb, x, &live); - - /* Clear registers live after INSN. */ - renumbered_reg_set_to_hard_reg_set (&hlive, &live); - AND_COMPL_HARD_REG_SET (*regs, hlive); - - /* Clear registers live in and before the sequence. */ - for (i = 0; i < length;) - { - rtx prev = PREV_INSN (x); - df_simulate_one_insn_backwards (bb, x, &live); - - if (INSN_P (x)) - { - renumbered_reg_set_to_hard_reg_set (&hlive, &live); - AND_COMPL_HARD_REG_SET (*regs, hlive); - i++; - } - - x = prev; - } - - /* Free unused data. */ - CLEAR_REG_SET (&live); -} - -/* Computes the gain of turning PSEQ into a pseudo-function and its matching - sequences into pseudo-calls. Also computes and caches the number of insns to - abstract from the matching sequences. */ - -static void -recompute_gain_for_pattern_seq (pattern_seq pseq) -{ - matching_seq mseq; - rtx x; - int i; - int hascall; - HARD_REG_SET linkregs; - - /* Initialize data. */ - SET_HARD_REG_SET (linkregs); - pseq->link_reg = NULL_RTX; - pseq->abstracted_length = 0; - - pseq->gain = -(seq_call_cost - seq_jump_cost + seq_return_cost); - - /* Determine ABSTRACTED_LENGTH and COST for matching sequences of PSEQ. - ABSTRACTED_LENGTH may be less than MATCHING_LENGTH if sequences in the - same block overlap. */ - - for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq) - { - /* Determine ABSTRACTED_LENGTH. */ - if (mseq->next_matching_seq) - mseq->abstracted_length = (int)(mseq->next_matching_seq->idx - - mseq->idx); - else - mseq->abstracted_length = mseq->matching_length; - - if (mseq->abstracted_length > mseq->matching_length) - mseq->abstracted_length = mseq->matching_length; - - /* Compute the cost of sequence. */ - RECOMPUTE_COST (mseq); - - /* If COST is big enough registers live in this matching sequence - should not be used as a link register. Also set ABSTRACTED_LENGTH - of PSEQ. */ - if (mseq->cost > seq_call_cost) - { - clear_regs_live_in_seq (&linkregs, mseq->insn, - mseq->abstracted_length); - if (mseq->abstracted_length > pseq->abstracted_length) - pseq->abstracted_length = mseq->abstracted_length; - } - } - - /* Modify ABSTRACTED_LENGTH of PSEQ if pattern sequence overlaps with one - of the matching sequences. */ - for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq) - { - x = pseq->insn; - for (i = 0; (i < pseq->abstracted_length) && (x != mseq->insn); i++) - x = prev_insn_in_block (x); - pseq->abstracted_length = i; - } - - /* Compute the cost of pattern sequence. */ - RECOMPUTE_COST (pseq); - - /* No gain if COST is too small. */ - if (pseq->cost <= seq_call_cost) - { - pseq->gain = -1; - return; - } - - /* Ensure that no matching sequence is longer than the pattern sequence. */ - for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq) - { - if (mseq->abstracted_length > pseq->abstracted_length) - { - mseq->abstracted_length = pseq->abstracted_length; - RECOMPUTE_COST (mseq); - } - /* Once the length is stabilizing the gain can be calculated. */ - if (mseq->cost > seq_call_cost) - pseq->gain += mseq->cost - seq_call_cost; - } - - /* No need to do further work if there is no gain. */ - if (pseq->gain <= 0) - return; - - /* Should not use registers live in the pattern sequence as link register. - */ - clear_regs_live_in_seq (&linkregs, pseq->insn, pseq->abstracted_length); - - /* Determine whether pattern sequence contains a call_insn. */ - hascall = 0; - x = pseq->insn; - for (i = 0; i < pseq->abstracted_length; i++) - { - if (CALL_P (x)) - { - hascall = 1; - break; - } - x = prev_insn_in_block (x); - } - - /* Should not use a register as a link register if - it is a fixed - register, or - the sequence contains a call insn and the register is a - call used register, or - the register needs to be saved if used in a - function but was not used before (since saving it can invalidate already - computed frame pointer offsets), or - the register cannot be used as a - base register. */ - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (fixed_regs[i] -#ifdef REGNO_OK_FOR_INDIRECT_JUMP_P - || (!REGNO_OK_FOR_INDIRECT_JUMP_P (i, Pmode)) -#else - || (!ok_for_base_p_1 (i, Pmode, MEM, SCRATCH)) - || (!reg_class_subset_p (REGNO_REG_CLASS (i), - base_reg_class (VOIDmode, MEM, SCRATCH))) -#endif - || (hascall && call_used_regs[i]) - || (!call_used_regs[i] && !df_regs_ever_live_p (i))) - CLEAR_HARD_REG_BIT (linkregs, i); - - /* Find an appropriate register to be used as the link register. */ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (linkregs, i)) - { - pseq->link_reg = gen_rtx_REG (Pmode, i); - break; - } - - /* Abstraction is not possible if no link register is available, so set - gain to 0. */ - if (!pseq->link_reg) - pseq->gain = 0; -} - -/* Deallocates memory occupied by PSEQ and its matching seqs. */ - -static void -free_pattern_seq (pattern_seq pseq) -{ - while (pseq->matching_seqs) - { - matching_seq mseq = pseq->matching_seqs; - pseq->matching_seqs = mseq->next_matching_seq; - free (mseq); - } - free (pseq); -} - - -/* Computes the gain for pattern sequences. Pattern sequences producing no gain - are deleted. The pattern sequence with the biggest gain is moved to the first - place of PATTERN_SEQS. */ - -static void -recompute_gain (void) -{ - pattern_seq *pseq; - int maxgain; - - maxgain = 0; - for (pseq = &pattern_seqs; *pseq;) - { - if ((*pseq)->gain <= 0) - recompute_gain_for_pattern_seq (*pseq); - - if ((*pseq)->gain > 0) - { - if ((*pseq)->gain > maxgain) - { - pattern_seq temp = *pseq; - (*pseq) = temp->next_pattern_seq; - temp->next_pattern_seq = pattern_seqs; - pattern_seqs = temp; - maxgain = pattern_seqs->gain; - } - else - { - pseq = &(*pseq)->next_pattern_seq; - } - } - else - { - pattern_seq temp = *pseq; - *pseq = temp->next_pattern_seq; - free_pattern_seq (temp); - } - } -} - -/* Updated those pattern sequences and matching sequences, which overlap with - the sequence given by INSN and LEN. Deletes sequences shrinking below a - limit. */ - -static void -erase_from_pattern_seqs (rtx insn, int len) -{ - pattern_seq *pseq; - matching_seq *mseq; - rtx x; - int plen, mlen; - int pcost, mcost; - - while (len > 0) - { - for (pseq = &pattern_seqs; *pseq;) - { - plen = 0; - pcost = 0; - for (x = (*pseq)->insn; x && (x != insn); - x = prev_insn_in_block (x)) - { - plen++; - pcost += compute_rtx_cost (x); - } - - if (pcost <= seq_call_cost) - { - pattern_seq temp = *pseq; - *pseq = temp->next_pattern_seq; - free_pattern_seq (temp); - } - else - { - for (mseq = &(*pseq)->matching_seqs; *mseq;) - { - mlen = 0; - mcost = 0; - for (x = (*mseq)->insn; - x && (x != insn) && (mlen < plen) - && (mlen < (*mseq)->matching_length); - x = prev_insn_in_block (x)) - { - mlen++; - mcost += compute_rtx_cost (x); - } - - if (mcost <= seq_call_cost) - { - matching_seq temp = *mseq; - *mseq = temp->next_matching_seq; - free (temp); - /* Set to 0 to force gain recomputation. */ - (*pseq)->gain = 0; - } - else - { - if (mlen < (*mseq)->matching_length) - { - (*mseq)->cost = mcost; - (*mseq)->matching_length = mlen; - /* Set to 0 to force gain recomputation. */ - (*pseq)->gain = 0; - } - mseq = &(*mseq)->next_matching_seq; - } - } - - pseq = &(*pseq)->next_pattern_seq; - } - } - - len--; - insn = prev_insn_in_block (insn); - } -} - -/* Updates those pattern sequences and matching sequences, which overlap with - the pattern sequence with the biggest gain and its matching sequences. */ - -static void -update_pattern_seqs (void) -{ - pattern_seq bestpseq; - matching_seq mseq; - - bestpseq = pattern_seqs; - pattern_seqs = bestpseq->next_pattern_seq; - - for (mseq = bestpseq->matching_seqs; mseq; mseq = mseq->next_matching_seq) - if (mseq->cost > seq_call_cost) - erase_from_pattern_seqs (mseq->insn, mseq->abstracted_length); - erase_from_pattern_seqs (bestpseq->insn, bestpseq->abstracted_length); - - bestpseq->next_pattern_seq = pattern_seqs; - pattern_seqs = bestpseq; -} - -/* Groups together those matching sequences of the best pattern sequence, which - have the same ABSTRACTED_LENGTH and puts these groups in ascending order. - SEQ_BLOCKS contains the result. */ - -static void -determine_seq_blocks (void) -{ - seq_block sb; - matching_seq *mseq; - matching_seq m; - - /* Initialize SEQ_BLOCKS to empty. */ - seq_blocks = 0; - - /* Process all matching sequences. */ - for (mseq = &pattern_seqs->matching_seqs; *mseq;) - { - /* Deal only with matching sequences being long enough. */ - if ((*mseq)->cost <= seq_call_cost) - { - mseq = &(*mseq)->next_matching_seq; - continue; - } - - /* Ensure that SB contains a seq_block with the appropriate length. - Insert a new seq_block if necessary. */ - if (!seq_blocks || ((*mseq)->abstracted_length < seq_blocks->length)) - { - sb = (seq_block) xmalloc (sizeof (struct seq_block_def)); - sb->length = (*mseq)->abstracted_length; - sb->label = NULL_RTX; - sb->matching_seqs = 0; - sb->next_seq_block = seq_blocks; - seq_blocks = sb; - } - else - { - for (sb = seq_blocks; sb; sb = sb->next_seq_block) - { - if ((*mseq)->abstracted_length == sb->length) - break; - if (!sb->next_seq_block - || ((*mseq)->abstracted_length < - sb->next_seq_block->length)) - { - seq_block temp = - (seq_block) xmalloc (sizeof (struct seq_block_def)); - temp->length = (*mseq)->abstracted_length; - temp->label = NULL_RTX; - temp->matching_seqs = 0; - temp->next_seq_block = sb->next_seq_block; - sb->next_seq_block = temp; - } - } - } - - /* Remove the matching sequence from the linked list of the pattern - sequence and link it to SB. */ - m = *mseq; - *mseq = m->next_matching_seq; - m->next_matching_seq = sb->matching_seqs; - sb->matching_seqs = m; - } -} - -/* Builds a symbol_ref for LABEL. */ - -static rtx -gen_symbol_ref_rtx_for_label (const_rtx label) -{ - char name[20]; - rtx sym; - - ASM_GENERATE_INTERNAL_LABEL (name, "L", CODE_LABEL_NUMBER (label)); - sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); - SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL; - return sym; -} - -/* Splits basic block at the requested insn and rebuilds dataflow. */ - -static basic_block -split_block_and_df_analyze (basic_block bb, rtx insn) -{ - basic_block next; - next = split_block (bb, insn)->dest; - df_analyze (); - return next; -} - -/* Ensures that INSN is the last insn in its block and returns the block label - of the next block. */ - -static rtx -block_label_after (rtx insn) -{ - basic_block bb = BLOCK_FOR_INSN (insn); - if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR)) - return block_label (bb->next_bb); - else - return block_label (split_block_and_df_analyze (bb, insn)); -} - -/* Ensures that the last insns of the best pattern and its matching sequences - are the last insns in their block. Additionally, extends the live set at the - end of the pattern sequence with the live sets at the end of the matching - sequences. */ - -static void -split_blocks_after_seqs (void) -{ - seq_block sb; - matching_seq mseq; - - block_label_after (pattern_seqs->insn); - for (sb = seq_blocks; sb; sb = sb->next_seq_block) - { - for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq) - { - block_label_after (mseq->insn); - IOR_REG_SET (df_get_live_out (BLOCK_FOR_INSN (pattern_seqs->insn)), - df_get_live_out (BLOCK_FOR_INSN (mseq->insn))); - } - } -} - -/* Splits the best pattern sequence according to SEQ_BLOCKS. Emits pseudo-call - and -return insns before and after the sequence. */ - -static void -split_pattern_seq (void) -{ - rtx insn; - basic_block bb; - rtx retlabel, retjmp, saveinsn; - int i; - seq_block sb; - - insn = pattern_seqs->insn; - bb = BLOCK_FOR_INSN (insn); - - /* Get the label after the sequence. This will be the return address. The - label will be referenced using a symbol_ref so protect it from - deleting. */ - retlabel = block_label_after (insn); - LABEL_PRESERVE_P (retlabel) = 1; - - /* Emit an indirect jump via the link register after the sequence acting - as the return insn. Also emit a barrier and update the basic block. */ - if (!find_reg_note (BB_END (bb), REG_NORETURN, NULL)) - retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg), - BB_END (bb)); - emit_barrier_after (BB_END (bb)); - - /* Replace all outgoing edges with a new one to the block of RETLABEL. */ - while (EDGE_COUNT (bb->succs) != 0) - remove_edge (EDGE_SUCC (bb, 0)); - make_edge (bb, BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL); - - /* Split the sequence according to SEQ_BLOCKS and cache the label of the - resulting basic blocks. */ - i = 0; - for (sb = seq_blocks; sb; sb = sb->next_seq_block) - { - for (; i < sb->length; i++) - insn = prev_insn_in_block (insn); - - sb->label = block_label (split_block_and_df_analyze (bb, insn)); - } - - /* Emit an insn saving the return address to the link register before the - sequence. */ - saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg, - gen_symbol_ref_rtx_for_label - (retlabel)), BB_END (bb)); - /* Update liveness info. */ - SET_REGNO_REG_SET (df_get_live_out (bb), - REGNO (pattern_seqs->link_reg)); -} - -/* Deletes the insns of the matching sequences of the best pattern sequence and - replaces them with pseudo-calls to the pattern sequence. */ - -static void -erase_matching_seqs (void) -{ - seq_block sb; - matching_seq mseq; - rtx insn; - basic_block bb; - rtx retlabel, saveinsn, callinsn; - int i; - - for (sb = seq_blocks; sb; sb = sb->next_seq_block) - { - for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq) - { - insn = mseq->insn; - bb = BLOCK_FOR_INSN (insn); - - /* Get the label after the sequence. This will be the return - address. The label will be referenced using a symbol_ref so - protect it from deleting. */ - retlabel = block_label_after (insn); - LABEL_PRESERVE_P (retlabel) = 1; - - /* Delete the insns of the sequence. */ - for (i = 0; i < sb->length; i++) - insn = prev_insn_in_block (insn); - delete_basic_block (split_block_and_df_analyze (bb, insn)); - - /* Emit an insn saving the return address to the link register - before the deleted sequence. */ - saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg, - gen_symbol_ref_rtx_for_label - (retlabel)), - BB_END (bb)); - BLOCK_FOR_INSN (saveinsn) = bb; - - /* Emit a jump to the appropriate part of the pattern sequence - after the save insn. Also update the basic block. */ - callinsn = emit_jump_insn_after (gen_jump (sb->label), saveinsn); - JUMP_LABEL (callinsn) = sb->label; - LABEL_NUSES (sb->label)++; - BLOCK_FOR_INSN (callinsn) = bb; - BB_END (bb) = callinsn; - - /* Maintain control flow and liveness information. */ - SET_REGNO_REG_SET (df_get_live_out (bb), - REGNO (pattern_seqs->link_reg)); - emit_barrier_after (BB_END (bb)); - make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0); - IOR_REG_SET (df_get_live_out (bb), - df_get_live_in (BLOCK_FOR_INSN (sb->label))); - - make_edge (BLOCK_FOR_INSN (seq_blocks->label), - BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL); - } - } -} - -/* Deallocates SEQ_BLOCKS and all the matching sequences. */ - -static void -free_seq_blocks (void) -{ - while (seq_blocks) - { - seq_block sb = seq_blocks; - while (sb->matching_seqs) - { - matching_seq mseq = sb->matching_seqs; - sb->matching_seqs = mseq->next_matching_seq; - free (mseq); - } - seq_blocks = sb->next_seq_block; - free (sb); - } -} - -/* Transforms the best pattern sequence into a pseudo-function and its matching - sequences to pseudo-calls. Afterwards the best pattern sequence is removed - from PATTERN_SEQS. */ - -static void -abstract_best_seq (void) -{ - pattern_seq bestpseq; - - /* Do the abstraction. */ - determine_seq_blocks (); - split_blocks_after_seqs (); - split_pattern_seq (); - erase_matching_seqs (); - free_seq_blocks (); - - /* Record the usage of the link register. */ - df_set_regs_ever_live (REGNO (pattern_seqs->link_reg), true); - - /* Remove the best pattern sequence. */ - bestpseq = pattern_seqs; - pattern_seqs = bestpseq->next_pattern_seq; - free_pattern_seq (bestpseq); -} - -/* Prints info on the pattern sequences to the dump file. */ - -static void -dump_pattern_seqs (void) -{ - pattern_seq pseq; - matching_seq mseq; - - if (!dump_file) - return; - - fprintf (dump_file, ";; Pattern sequences\n"); - for (pseq = pattern_seqs; pseq; pseq = pseq->next_pattern_seq) - { - fprintf (dump_file, "Pattern sequence at insn %d matches sequences at", - INSN_UID (pseq->insn)); - for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq) - { - fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn), - mseq->matching_length); - if (mseq->next_matching_seq) - fprintf (dump_file, ","); - } - fprintf (dump_file, ".\n"); - } - fprintf (dump_file, "\n"); -} - -/* Prints info on the best pattern sequence transformed in the ITER-th - iteration to the dump file. */ - -static void -dump_best_pattern_seq (int iter) -{ - matching_seq mseq; - - if (!dump_file) - return; - - fprintf (dump_file, ";; Iteration %d\n", iter); - fprintf (dump_file, - "Best pattern sequence with %d gain is at insn %d (length %d).\n", - pattern_seqs->gain, INSN_UID (pattern_seqs->insn), - pattern_seqs->abstracted_length); - fprintf (dump_file, "Matching sequences are at"); - for (mseq = pattern_seqs->matching_seqs; mseq; - mseq = mseq->next_matching_seq) - { - fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn), - mseq->abstracted_length); - if (mseq->next_matching_seq) - fprintf (dump_file, ","); - } - fprintf (dump_file, ".\n"); - fprintf (dump_file, "Using reg %d as link register.\n\n", - REGNO (pattern_seqs->link_reg)); -} - -/* Htab hash function for hash_bucket_def structure. */ - -static unsigned int -htab_hash_bucket (const void *p) -{ - const_p_hash_bucket bucket = (const_p_hash_bucket) p; - return bucket->hash; -} - -/* Htab equal function for hash_bucket_def structure. */ - -static int -htab_eq_bucket (const void *p0, const void *p1) -{ - return htab_hash_bucket (p0) == htab_hash_bucket (p1); -} - -/* Htab delete function for hash_bucket_def structure. */ - -static void -htab_del_bucket (void *p) -{ - p_hash_bucket bucket = (p_hash_bucket) p; - - if (bucket->seq_candidates) - htab_delete (bucket->seq_candidates); - - free (bucket); -} - -/* Htab hash function for hash_bucket_def structure. */ - -static unsigned int -htab_hash_elem (const void *p) -{ - const_p_hash_elem elem = (const_p_hash_elem) p; - return htab_hash_pointer (elem->insn); -} - -/* Htab equal function for hash_bucket_def structure. */ - -static int -htab_eq_elem (const void *p0, const void *p1) -{ - return htab_hash_elem (p0) == htab_hash_elem (p1); -} - -/* Htab delete function for hash_bucket_def structure. */ - -static void -htab_del_elem (void *p) -{ - p_hash_elem elem = (p_hash_elem) p; - free (elem); -} - -/* Creates a hash value for each sequence candidate and saves them - in HASH_BUCKET. */ - -static void -fill_hash_bucket (void) -{ - basic_block bb; - rtx insn; - void **slot; - p_hash_bucket bucket; - struct hash_bucket_def tmp_bucket; - p_hash_elem elem; - unsigned long insn_idx; - - insn_idx = 0; - FOR_EACH_BB (bb) - { - FOR_BB_INSNS_REVERSE (bb, insn) - { - if (!ABSTRACTABLE_INSN_P (insn)) - continue; - - /* Compute hash value for INSN. */ - tmp_bucket.hash = compute_hash (insn); - - /* Select the hash group. */ - bucket = (p_hash_bucket) htab_find (hash_buckets, &tmp_bucket); - - if (!bucket) - { - /* Create a new hash group. */ - bucket = (p_hash_bucket) xcalloc (1, - sizeof (struct hash_bucket_def)); - bucket->hash = tmp_bucket.hash; - bucket->seq_candidates = NULL; - - slot = htab_find_slot (hash_buckets, &tmp_bucket, INSERT); - *slot = bucket; - } - - /* Create new list for storing sequence candidates. */ - if (!bucket->seq_candidates) - bucket->seq_candidates = htab_create (HASH_INIT, - htab_hash_elem, - htab_eq_elem, - htab_del_elem); - - elem = (p_hash_elem) xcalloc (1, sizeof (struct hash_elem_def)); - elem->insn = insn; - elem->idx = insn_idx; - elem->length = get_attr_length (insn); - - /* Insert INSN into BUCKET hash bucket. */ - slot = htab_find_slot (bucket->seq_candidates, elem, INSERT); - *slot = elem; - - insn_idx++; - } - } -} - -/* Computes the cost of calling sequence and the cost of return. */ - -static void -compute_init_costs (void) -{ - rtx rtx_jump, rtx_store, rtx_return, reg, label; - basic_block bb; - - FOR_EACH_BB (bb) - if (BB_HEAD (bb)) - break; - - label = block_label (bb); - reg = gen_rtx_REG (Pmode, 0); - - /* Pattern for indirect jump. */ - rtx_jump = gen_indirect_jump (reg); - - /* Pattern for storing address. */ - rtx_store = gen_rtx_SET (VOIDmode, reg, gen_symbol_ref_rtx_for_label (label)); - - /* Pattern for return insn. */ - rtx_return = gen_jump (label); - - /* The cost of jump. */ - seq_jump_cost = compute_rtx_cost (make_jump_insn_raw (rtx_jump)); - - /* The cost of calling sequence. */ - seq_call_cost = seq_jump_cost + compute_rtx_cost (make_insn_raw (rtx_store)); - - /* The cost of return. */ - seq_return_cost = compute_rtx_cost (make_jump_insn_raw (rtx_return)); - - /* Simple heuristic for minimal sequence cost. */ - seq_call_cost = (int)(seq_call_cost * (double)SEQ_CALL_COST_MULTIPLIER); -} - -/* Finds equivalent insn sequences in the current function and retains only one - instance of them which is turned into a pseudo-function. The additional - copies are erased and replaced by pseudo-calls to the retained sequence. */ - -static void -rtl_seqabstr (void) -{ - int iter; - df_set_flags (DF_LR_RUN_DCE); - df_analyze (); - - /* Create a hash list for COLLECT_PATTERN_SEQS. */ - hash_buckets = htab_create (HASH_INIT, htab_hash_bucket , htab_eq_bucket , - htab_del_bucket); - fill_hash_bucket (); - - /* Compute the common cost of abstraction. */ - compute_init_costs (); - - /* Build an initial set of pattern sequences from the current function. */ - collect_pattern_seqs (); - dump_pattern_seqs (); - - /* Iterate until there are no sequences to abstract. */ - for (iter = 1;; iter++) - { - /* Recompute gain for sequences if necessary and select sequence with - biggest gain. */ - recompute_gain (); - if (!pattern_seqs) - break; - dump_best_pattern_seq (iter); - /* Update the cached info of the other sequences and force gain - recomputation where needed. */ - update_pattern_seqs (); - /* Turn best sequences into pseudo-functions and -calls. */ - abstract_best_seq (); - } - - /* Cleanup hash tables. */ - htab_delete (hash_buckets); -} - -/* The gate function for TREE_OPT_PASS. */ - -static bool -gate_rtl_seqabstr (void) -{ - return flag_rtl_seqabstr; -} - -/* The entry point of the sequence abstraction algorithm. */ - -static unsigned int -rest_of_rtl_seqabstr (void) -{ - /* Abstract out common insn sequences. */ - rtl_seqabstr (); - return 0; -} - -struct rtl_opt_pass pass_rtl_seqabstr = -{ - { - RTL_PASS, - "seqabstr", /* name */ - gate_rtl_seqabstr, /* gate */ - rest_of_rtl_seqabstr, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_SEQABSTR, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | - TODO_ggc_collect /* todo_flags_finish */ - } -}; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c845ed9..99a310b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-31 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + * gcc.c-torture/compile/pr33009.c: Delete. + * gcc.c-torture/compile/pr11832.c: Likewise. + 2009-03-31 Joseph Myers <joseph@codesourcery.com> PR c/448 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr11832.c b/gcc/testsuite/gcc.c-torture/compile/pr11832.c deleted file mode 100644 index ad14c0c..0000000 --- a/gcc/testsuite/gcc.c-torture/compile/pr11832.c +++ /dev/null @@ -1,35 +0,0 @@ -/* { dg-do compile } */ -/* Currently ICEs for Alpha, IA64, HPPA, MIPS, CRIS, Xtensa, PowerPC, SH and SPARC; see PR33642. */ -/* { dg-xfail-if "PR33642" { alpha*-*-* hppa*-*-* mips*-*-* powerpc*-*-* cris-*-* crisv32-*-* ia64-*-* xtensa*-*-* sh*-*-* sparc*-*-* s390*-*-* } { "*" } { "" } } */ -/* Currently ICEs for (x86 && ilp32 && pic). */ -/* { dg-xfail-if "PR33642/36240" { { i?86-*-* x86_64-*-* } && { ilp32 && { ! nonpic } } } { "*" } { "" } } */ -/* { dg-prune-output ".*internal compiler error.*" } -/* { dg-options "-frtl-abstract-sequences" } */ - -int a, b, e; -unsigned char *c; -void foo() -{ - int d = 13; - b = -1; - switch (e) { - case 1: - b++; c[b] = (unsigned char)d; - break; - case 2: - b++; c[b] = (unsigned char)d; - b++; c[b] = (unsigned char)d; - break; - case 3: - b++; c[b] = (unsigned char)d; - b++; c[b] = (unsigned char)d; - b++; c[b] = (unsigned char)d; - break; - default: - a = 1; - b++; c[b] = (unsigned char)d; - b++; c[b] = (unsigned char)d; - b++; c[b] = (unsigned char)d; - b++; c[b] = (unsigned char)d; - } -} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33009.c b/gcc/testsuite/gcc.c-torture/compile/pr33009.c index d6118ea..e69de29 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr33009.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr33009.c @@ -1,41 +0,0 @@ -/* { dg-do compile } */ -/* Currently ICEs for Alpha, IA64, HPPA, MIPS, CRIS, Xtensa, PowerPC, SH and SPARC; see PR33642. */ -/* { dg-xfail-if "PR33642" { alpha*-*-* hppa*-*-* mips*-*-* powerpc*-*-* cris-*-* crisv32-*-* ia64-*-* xtensa*-*-* sh*-*-* sparc*-*-* s390*-*-* } { "*" } { "" } } */ -/* Currently ICEs for (x86 && ilp32 && pic). */ -/* { dg-xfail-if "PR33642/36240" { { i?86-*-* x86_64-*-* } && { ilp32 && { ! nonpic } } } { "*" } { "" } } */ -/* { dg-prune-output ".*internal compiler error.*" } -/* { dg-options "-frtl-abstract-sequences" } */ - -char *progName; -int bar0 (char *, ...); -void bar1 (char *); -void exit (int); - - -#define SAME \ - bar0 ("%s: Bad flag `%s'\n", argv[i], argv[i] );\ - bar1 ( progName ); \ - exit ( 1 ); - - -int foo ( int argc, char *argv[] ) -{ - int i; - for (i = 0; i < argc; i++) { - switch (argv[i][0]) { - case 'c': - break; - default: - - SAME - - break; - } - } - for (i = 0; i < argc; i++) { - - SAME - - } - return 0; -} |