aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch')
-rw-r--r--toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch873
1 files changed, 0 insertions, 873 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch
deleted file mode 100644
index 802c3816f1..0000000000
--- a/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch
+++ /dev/null
@@ -1,873 +0,0 @@
-2010-11-26 Tom de Vries <tom@codesourcery.com>
-
- gcc/
- * gcc/ee.c: New file.
- * gcc/tree-pass.h (pass_ee): Declare.
- * gcc/opts.c (decode_options): Set flag_ee at -O2.
- * gcc/timevar.def (TV_EE): New timevar.
- * gcc/common.opt (fextension-elimination): New option.
- * gcc/Makefile.in (ee.o): New rule.
- * gcc/passes.c (pass_ee): Add it.
- * gcc/testsuite/gcc.dg/extend-4.c: New test.
- * gcc/testsuite/gcc.dg/extend-1.c: New test.
- * gcc/testsuite/gcc.dg/extend-2.c: New test.
- * gcc/testsuite/gcc.dg/extend-2-64.c: New test.
- * gcc/testsuite/gcc.dg/extend-3.c: New test.
-
-=== modified file 'gcc/Makefile.in'
---- old/gcc/Makefile.in 2010-11-16 18:05:53 +0000
-+++ new/gcc/Makefile.in 2010-12-10 15:33:37 +0000
-@@ -1194,6 +1194,7 @@
- dse.o \
- dwarf2asm.o \
- dwarf2out.o \
-+ ee.o \
- ebitmap.o \
- emit-rtl.o \
- et-forest.o \
-@@ -2965,6 +2966,11 @@
- web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
- $(DF_H) $(OBSTACK_H) $(TIMEVAR_H) $(TREE_PASS_H)
-+ee.o : ee.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
-+ hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h \
-+ $(DF_H) $(TIMEVAR_H) tree-pass.h $(RECOG_H) $(EXPR_H) \
-+ $(REGS_H) $(TREE_H) $(TM_P_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) \
-+ $(TARGET_H) $(OPTABS_H) insn-codes.h rtlhooks-def.h $(PARAMS_H) $(CGRAPH_H)
- gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \
- $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
-
-=== modified file 'gcc/common.opt'
---- old/gcc/common.opt 2010-11-04 12:43:52 +0000
-+++ new/gcc/common.opt 2010-12-10 15:33:37 +0000
-@@ -496,6 +496,10 @@
- Common Report Var(flag_early_inlining) Init(1) Optimization
- Perform early inlining
-
-+fextension-elimination
-+Common Report Var(flag_ee) Init(0) Optimization
-+Perform extension elimination
-+
- feliminate-dwarf2-dups
- Common Report Var(flag_eliminate_dwarf2_dups)
- Perform DWARF2 duplicate elimination
-
-=== added file 'gcc/ee.c'
---- old/gcc/ee.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/ee.c 2010-12-10 15:33:37 +0000
-@@ -0,0 +1,662 @@
-+/* Redundant extension elimination
-+ Copyright (C) 2010 Free Software Foundation, Inc.
-+ Contributed by Tom de Vries (tom@codesourcery.com)
-+
-+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/>. */
-+
-+/*
-+
-+ MOTIVATING EXAMPLE
-+
-+ The motivating example for this pass is:
-+
-+ void f(unsigned char *p, short s, int c, int *z)
-+ {
-+ if (c)
-+ *z = 0;
-+ *p ^= (unsigned char)s;
-+ }
-+
-+ For MIPS, compilation results in the following insns.
-+
-+ (set (reg/v:SI 199)
-+ (sign_extend:SI (subreg:HI (reg:SI 200) 2)))
-+
-+ ...
-+
-+ (set (reg:QI 203)
-+ (subreg:QI (reg/v:SI 199) 3))
-+
-+ These insns are the only def and the only use of reg 199, each located in a
-+ different bb.
-+
-+ The sign-extension preserves the lower half of reg 200 and copies them to
-+ reg 199, and the subreg use of reg 199 only reads the least significant byte.
-+ The sign extension is therefore redundant (the extension part, not the copy
-+ part), and can safely be replaced with a regcopy from reg 200 to reg 199.
-+
-+
-+ OTHER SIGN/ZERO EXTENSION ELIMINATION PASSES
-+
-+ There are other passes which eliminate sign/zero-extension: combine and
-+ implicit_zee. Both attempt to eliminate extensions by combining them with
-+ other instructions. The combine pass does this at bb level,
-+ implicit_zee works at inter-bb level.
-+
-+ The combine pass combine an extension with either:
-+ - all uses of the extension, or
-+ - all defs of the operand of the extension.
-+ The implicit_zee pass only implements the latter.
-+
-+ For our motivating example, combine doesn't work since the def and the use of
-+ reg 199 are in a different bb.
-+
-+ Implicit_zee does not work since it only combines an extension with the defs
-+ of its operand.
-+
-+
-+ INTENDED EFFECT
-+
-+ This pass works by removing sign/zero-extensions, or replacing them with
-+ regcopies. The idea there is that the regcopy might be eliminated by a later
-+ pass. In case the regcopy cannot be eliminated, it might at least be cheaper
-+ than the extension.
-+
-+
-+ IMPLEMENTATION
-+
-+ The pass scans twice over all instructions.
-+
-+ The first scan registers all uses of a reg in the biggest_use array. After
-+ that first scan, the biggest_use array contains the size in bits of the
-+ biggest use of each reg.
-+
-+ The second scan finds extensions, determines whether they are redundant based
-+ on the biggest use, and deletes or replaces them.
-+
-+ In case that the src and dest reg of the replacement are not of the same size,
-+ we do not replace with a normal regcopy, but with a truncate or with the copy
-+ of a paradoxical subreg instead.
-+
-+
-+ LIMITATIONS
-+
-+ The scope of the analysis is limited to an extension and its uses. The other
-+ type of analysis (related to the defs of the operand of an extension) is not
-+ done.
-+
-+ Furthermore, we do the analysis of biggest use per reg. So when determining
-+ whether an extension is redundant, we take all uses of a the dest reg into
-+ account, also the ones that are not uses of the extension. This could be
-+ overcome by calculating the def-use chains and using those for analysis
-+ instead.
-+
-+ Finally, during the analysis each insn is looked at in isolation. There is no
-+ propagation of information during the analysis. To overcome this limitation,
-+ a backward iterative bit-level liveness analysis is needed. */
-+
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "tree.h"
-+#include "tm_p.h"
-+#include "flags.h"
-+#include "regs.h"
-+#include "hard-reg-set.h"
-+#include "basic-block.h"
-+#include "insn-config.h"
-+#include "function.h"
-+#include "expr.h"
-+#include "insn-attr.h"
-+#include "recog.h"
-+#include "toplev.h"
-+#include "target.h"
-+#include "timevar.h"
-+#include "optabs.h"
-+#include "insn-codes.h"
-+#include "rtlhooks-def.h"
-+#include "output.h"
-+#include "params.h"
-+#include "timevar.h"
-+#include "tree-pass.h"
-+#include "cgraph.h"
-+
-+#define SKIP_REG (-1)
-+
-+/* Array to register the biggest use of a reg, in bits. */
-+
-+static int *biggest_use;
-+
-+/* Forward declaration. */
-+
-+static void note_use (rtx *x, void *data);
-+
-+/* The following two functions are borrowed from trunk/gcc/toplev.c. They can be
-+ removed for a check-in into gcc trunk. */
-+
-+/* Given X, an unsigned number, return the number of least significant bits
-+ that are zero. When X == 0, the result is the word size. */
-+
-+static int
-+ctz_hwi (unsigned HOST_WIDE_INT x)
-+{
-+ return x ? floor_log2 (x & -x) : HOST_BITS_PER_WIDE_INT;
-+}
-+
-+/* Similarly for most significant bits. */
-+
-+static int
-+clz_hwi (unsigned HOST_WIDE_INT x)
-+{
-+ return HOST_BITS_PER_WIDE_INT - 1 - floor_log2(x);
-+}
-+
-+/* Check whether this is a paradoxical subreg. */
-+
-+static bool
-+paradoxical_subreg_p (rtx subreg)
-+{
-+ enum machine_mode subreg_mode, reg_mode;
-+
-+ if (GET_CODE (subreg) != SUBREG)
-+ return false;
-+
-+ subreg_mode = GET_MODE (subreg);
-+ reg_mode = GET_MODE (SUBREG_REG (subreg));
-+
-+ if (GET_MODE_SIZE (subreg_mode) > GET_MODE_SIZE (reg_mode))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Get the size and reg number of a REG or SUBREG use. */
-+
-+static bool
-+reg_use_p (rtx use, int *size, unsigned int *regno)
-+{
-+ rtx reg;
-+
-+ if (REG_P (use))
-+ {
-+ *regno = REGNO (use);
-+ *size = GET_MODE_BITSIZE (GET_MODE (use));
-+ return true;
-+ }
-+ else if (GET_CODE (use) == SUBREG)
-+ {
-+ reg = SUBREG_REG (use);
-+
-+ if (!REG_P (reg))
-+ return false;
-+
-+ *regno = REGNO (reg);
-+
-+ if (paradoxical_subreg_p (use))
-+ *size = GET_MODE_BITSIZE (GET_MODE (reg));
-+ else
-+ *size = subreg_lsb (use) + GET_MODE_BITSIZE (GET_MODE (use));
-+
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+/* Register the use of a reg. */
-+
-+static void
-+register_use (int size, unsigned int regno)
-+{
-+ int *current = &biggest_use[regno];
-+
-+ if (*current == SKIP_REG)
-+ return;
-+
-+ *current = MAX (*current, size);
-+}
-+
-+/* Handle embedded uses. */
-+
-+static void
-+note_embedded_uses (rtx use, rtx pattern)
-+{
-+ const char *format_ptr;
-+ int i, j;
-+
-+ format_ptr = GET_RTX_FORMAT (GET_CODE (use));
-+ for (i = 0; i < GET_RTX_LENGTH (GET_CODE (use)); i++)
-+ if (format_ptr[i] == 'e')
-+ note_use (&XEXP (use, i), pattern);
-+ else if (format_ptr[i] == 'E')
-+ for (j = 0; j < XVECLEN (use, i); j++)
-+ note_use (&XVECEXP (use, i, j), pattern);
-+}
-+
-+/* Get the set that has use as its SRC operand. */
-+
-+static rtx
-+get_set (rtx use, rtx pattern)
-+{
-+ rtx sub;
-+ int i;
-+
-+ if (GET_CODE (pattern) == SET && SET_SRC (pattern) == use)
-+ return pattern;
-+
-+ if (GET_CODE (pattern) == PARALLEL)
-+ for (i = 0; i < XVECLEN (pattern, 0); ++i)
-+ {
-+ sub = XVECEXP (pattern, 0, i);
-+ if (GET_CODE (sub) == SET && SET_SRC (sub) == use)
-+ return sub;
-+ }
-+
-+ return NULL_RTX;
-+}
-+
-+/* Handle a restricted op use. In this context restricted means that a bit in an
-+ operand influences only the same bit or more significant bits in the result.
-+ The bitwise ops are a subclass, but PLUS is one as well. */
-+
-+static void
-+note_restricted_op_use (rtx use, unsigned int nr_operands, rtx pattern)
-+{
-+ unsigned int i, smallest;
-+ int operand_size[2];
-+ int used_size;
-+ unsigned int operand_regno[2];
-+ bool operand_reg[2];
-+ bool operand_ignore[2];
-+ rtx set;
-+
-+ /* Init operand_reg, operand_size, operand_regno and operand_ignore. */
-+ for (i = 0; i < nr_operands; ++i)
-+ {
-+ operand_reg[i] = reg_use_p (XEXP (use, i), &operand_size[i],
-+ &operand_regno[i]);
-+ operand_ignore[i] = false;
-+ }
-+
-+ /* Handle case of reg and-masked with const. */
-+ if (GET_CODE (use) == AND && CONST_INT_P (XEXP (use, 1)) && operand_reg[0])
-+ {
-+ used_size =
-+ HOST_BITS_PER_WIDE_INT - clz_hwi (UINTVAL (XEXP (use, 1)));
-+ operand_size[0] = MIN (operand_size[0], used_size);
-+ }
-+
-+ /* Handle case of reg or-masked with const. */
-+ if (GET_CODE (use) == IOR && CONST_INT_P (XEXP (use, 1)) && operand_reg[0])
-+ {
-+ used_size =
-+ HOST_BITS_PER_WIDE_INT - clz_hwi (~UINTVAL (XEXP (use, 1)));
-+ operand_size[0] = MIN (operand_size[0], used_size);
-+ }
-+
-+ /* Ignore the use of a in 'a = a + b'. */
-+ set = get_set (use, pattern);
-+ if (set != NULL_RTX && REG_P (SET_DEST (set)))
-+ for (i = 0; i < nr_operands; ++i)
-+ operand_ignore[i] = (operand_reg[i]
-+ && (REGNO (SET_DEST (set)) == operand_regno[i]));
-+
-+ /* Handle the case a reg is combined with don't care bits. */
-+ if (nr_operands == 2 && operand_reg[0] && operand_reg[1]
-+ && operand_size[0] != operand_size[1])
-+ {
-+ smallest = operand_size[0] > operand_size[1];
-+
-+ if (paradoxical_subreg_p (XEXP (use, smallest))
-+ && !SUBREG_PROMOTED_VAR_P (XEXP (use, smallest)))
-+ operand_size[1 - smallest] = operand_size[smallest];
-+ }
-+
-+ /* Register the operand use, if necessary. */
-+ for (i = 0; i < nr_operands; ++i)
-+ if (!operand_reg[i])
-+ note_use (&XEXP (use, i), pattern);
-+ else if (!operand_ignore[i])
-+ register_use (operand_size[i], operand_regno[i]);
-+}
-+
-+/* Handle all uses noted by note_uses. */
-+
-+static void
-+note_use (rtx *x, void *data)
-+{
-+ rtx use = *x;
-+ rtx pattern = (rtx)data;
-+ int use_size;
-+ unsigned int use_regno;
-+
-+ switch (GET_CODE (use))
-+ {
-+ case REG:
-+ case SUBREG:
-+ if (!reg_use_p (use, &use_size, &use_regno))
-+ {
-+ note_embedded_uses (use, pattern);
-+ return;
-+ }
-+ register_use (use_size, use_regno);
-+ return;
-+ case IOR:
-+ case AND:
-+ case XOR:
-+ case PLUS:
-+ case MINUS:
-+ note_restricted_op_use (use, 2, pattern);
-+ return;
-+ case NOT:
-+ case NEG:
-+ note_restricted_op_use (use, 1, pattern);
-+ return;
-+ case ASHIFT:
-+ if (!reg_use_p (XEXP (use, 0), &use_size, &use_regno)
-+ || !CONST_INT_P (XEXP (use, 1))
-+ || INTVAL (XEXP (use, 1)) <= 0
-+ || paradoxical_subreg_p (XEXP (use, 0)))
-+ {
-+ note_embedded_uses (use, pattern);
-+ return;
-+ }
-+ register_use (use_size - INTVAL (XEXP (use, 1)), use_regno);
-+ return;
-+ default:
-+ note_embedded_uses (use, pattern);
-+ return;
-+ }
-+}
-+
-+/* Check whether reg is implicitly used. */
-+
-+static bool
-+implicit_use_p (int regno)
-+{
-+#ifdef EPILOGUE_USES
-+ if (EPILOGUE_USES (regno))
-+ return true;
-+#endif
-+
-+#ifdef EH_USES
-+ if (EH_USES (regno))
-+ return true;
-+#endif
-+
-+ return false;
-+}
-+
-+/* Note the uses of argument registers in a call. */
-+
-+static void
-+note_call_uses (rtx insn)
-+{
-+ rtx link, link_expr;
-+
-+ if (!CALL_P (insn))
-+ return;
-+
-+ for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
-+ {
-+ link_expr = XEXP (link, 0);
-+
-+ if (GET_CODE (link_expr) == USE)
-+ note_use (&XEXP (link_expr, 0), link);
-+ }
-+}
-+
-+/* Calculate the biggest use mode for all regs. */
-+
-+static void
-+calculate_biggest_use (void)
-+{
-+ int i;
-+ basic_block bb;
-+ rtx insn;
-+
-+ /* Initialize biggest_use for all regs to 0. If a reg is used implicitly, we
-+ handle that reg conservatively and set it to SKIP_REG instead. */
-+ for (i = 0; i < max_reg_num (); i++)
-+ biggest_use[i] = ((implicit_use_p (i) || HARD_REGISTER_NUM_P (i))
-+ ? SKIP_REG : 0);
-+
-+ /* For all insns, call note_use for each use in insn. */
-+ FOR_EACH_BB (bb)
-+ FOR_BB_INSNS (bb, insn)
-+ {
-+ if (!NONDEBUG_INSN_P (insn))
-+ continue;
-+
-+ note_uses (&PATTERN (insn), note_use, PATTERN (insn));
-+
-+ if (CALL_P (insn))
-+ note_call_uses (insn);
-+ }
-+
-+ /* Dump the biggest uses found. */
-+ if (dump_file)
-+ for (i = 0; i < max_reg_num (); i++)
-+ if (biggest_use[i] > 0)
-+ fprintf (dump_file, "reg %d: size %d\n", i, biggest_use[i]);
-+}
-+
-+/* Check whether this is a sign/zero extension. */
-+
-+static bool
-+extension_p (rtx insn, rtx *dest, rtx *inner, int *preserved_size)
-+{
-+ rtx src, op0;
-+
-+ /* Detect set of reg. */
-+ if (GET_CODE (PATTERN (insn)) != SET)
-+ return false;
-+
-+ src = SET_SRC (PATTERN (insn));
-+ *dest = SET_DEST (PATTERN (insn));
-+
-+ if (!REG_P (*dest))
-+ return false;
-+
-+ /* Detect sign or zero extension. */
-+ if (GET_CODE (src) == ZERO_EXTEND || GET_CODE (src) == SIGN_EXTEND
-+ || (GET_CODE (src) == AND && CONST_INT_P (XEXP (src, 1))))
-+ {
-+ op0 = XEXP (src, 0);
-+
-+ /* Determine amount of least significant bits preserved by operation. */
-+ if (GET_CODE (src) == AND)
-+ *preserved_size = ctz_hwi (~UINTVAL (XEXP (src, 1)));
-+ else
-+ *preserved_size = GET_MODE_BITSIZE (GET_MODE (op0));
-+
-+ if (GET_CODE (op0) == SUBREG)
-+ {
-+ if (subreg_lsb (op0) != 0)
-+ return false;
-+
-+ *inner = SUBREG_REG (op0);
-+ return true;
-+ }
-+ else if (REG_P (op0))
-+ {
-+ *inner = op0;
-+ return true;
-+ }
-+ }
-+
-+ return false;
-+}
-+
-+/* Check whether this is a redundant sign/zero extension. */
-+
-+static bool
-+redundant_extension_p (rtx insn, rtx *dest, rtx *inner)
-+{
-+ int biggest_dest_use;
-+ int preserved_size;
-+
-+ if (!extension_p (insn, dest, inner, &preserved_size))
-+ return false;
-+
-+ if (dump_file)
-+ fprintf (dump_file, "considering extension %u with preserved size %d\n",
-+ INSN_UID (insn), preserved_size);
-+
-+ biggest_dest_use = biggest_use[REGNO (*dest)];
-+
-+ if (biggest_dest_use == SKIP_REG)
-+ return false;
-+
-+ if (preserved_size < biggest_dest_use)
-+ return false;
-+
-+ if (dump_file)
-+ fprintf (dump_file, "found superfluous extension %u\n", INSN_UID (insn));
-+
-+ return true;
-+}
-+
-+/* Try to remove or replace the redundant extension. */
-+
-+static void
-+try_remove_or_replace_extension (rtx insn, rtx dest, rtx inner)
-+{
-+ rtx cp_src, cp_dest, seq, one;
-+
-+ if (GET_MODE_CLASS (GET_MODE (dest)) != GET_MODE_CLASS (GET_MODE (inner)))
-+ return;
-+
-+ /* Check whether replacement is needed. */
-+ if (dest != inner)
-+ {
-+ start_sequence ();
-+
-+ /* Determine the proper replacement operation. */
-+ if (GET_MODE (dest) == GET_MODE (inner))
-+ {
-+ cp_src = inner;
-+ cp_dest = dest;
-+ }
-+ else if (GET_MODE_SIZE (GET_MODE (dest))
-+ > GET_MODE_SIZE (GET_MODE (inner)))
-+ {
-+ emit_clobber (dest);
-+ cp_src = inner;
-+ cp_dest = gen_lowpart_SUBREG (GET_MODE (inner), dest);
-+ }
-+ else
-+ {
-+ cp_src = gen_rtx_TRUNCATE (GET_MODE (dest), inner);
-+ cp_dest = dest;
-+ }
-+
-+ emit_move_insn (cp_dest, cp_src);
-+
-+ seq = get_insns ();
-+ end_sequence ();
-+
-+ /* If the replacement is not supported, bail out. */
-+ for (one = seq; one != NULL_RTX; one = NEXT_INSN (one))
-+ if (recog_memoized (one) < 0 && GET_CODE (PATTERN (one)) != CLOBBER)
-+ return;
-+
-+ /* Insert the replacement. */
-+ emit_insn_before (seq, insn);
-+ }
-+
-+ /* Note replacement/removal in the dump. */
-+ if (dump_file)
-+ {
-+ fprintf (dump_file, "superfluous extension %u ", INSN_UID (insn));
-+ if (dest != inner)
-+ fprintf (dump_file, "replaced by %u\n", INSN_UID (seq));
-+ else
-+ fprintf (dump_file, "removed\n");
-+ }
-+
-+ /* Remove the extension. */
-+ delete_insn (insn);
-+}
-+
-+/* Find redundant extensions and remove or replace them if possible. */
-+
-+static void
-+remove_redundant_extensions (void)
-+{
-+ basic_block bb;
-+ rtx insn, next, dest, inner;
-+
-+ biggest_use = XNEWVEC (int, max_reg_num ());
-+ calculate_biggest_use ();
-+
-+ /* Remove redundant extensions. */
-+ FOR_EACH_BB (bb)
-+ FOR_BB_INSNS_SAFE (bb, insn, next)
-+ {
-+ if (!NONDEBUG_INSN_P (insn))
-+ continue;
-+
-+ if (!redundant_extension_p (insn, &dest, &inner))
-+ continue;
-+
-+ try_remove_or_replace_extension (insn, dest, inner);
-+ }
-+
-+ free (biggest_use);
-+}
-+
-+/* Remove redundant extensions. */
-+
-+static unsigned int
-+rest_of_handle_ee (void)
-+{
-+ remove_redundant_extensions ();
-+ return 0;
-+}
-+
-+/* Run ee pass when flag_ee is set at optimization level > 0. */
-+
-+static bool
-+gate_handle_ee (void)
-+{
-+ return (optimize > 0 && flag_ee);
-+}
-+
-+struct rtl_opt_pass pass_ee =
-+{
-+ {
-+ RTL_PASS,
-+ "ee", /* name */
-+ gate_handle_ee, /* gate */
-+ rest_of_handle_ee, /* execute */
-+ NULL, /* sub */
-+ NULL, /* next */
-+ 0, /* static_pass_number */
-+ TV_EE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ TODO_ggc_collect |
-+ TODO_dump_func |
-+ TODO_verify_rtl_sharing, /* todo_flags_finish */
-+ }
-+};
-
-=== modified file 'gcc/opts.c'
---- old/gcc/opts.c 2010-05-17 09:13:28 +0000
-+++ new/gcc/opts.c 2010-12-10 15:33:37 +0000
-@@ -907,6 +907,7 @@
- flag_tree_switch_conversion = opt2;
- flag_ipa_cp = opt2;
- flag_ipa_sra = opt2;
-+ flag_ee = opt2;
-
- /* Track fields in field-sensitive alias analysis. */
- set_param_value ("max-fields-for-field-sensitive",
-
-=== modified file 'gcc/passes.c'
---- old/gcc/passes.c 2010-09-01 13:29:58 +0000
-+++ new/gcc/passes.c 2010-12-10 15:33:37 +0000
-@@ -974,6 +974,7 @@
- NEXT_PASS (pass_lower_subreg);
- NEXT_PASS (pass_df_initialize_opt);
- NEXT_PASS (pass_cse);
-+ NEXT_PASS (pass_ee);
- NEXT_PASS (pass_rtl_fwprop);
- NEXT_PASS (pass_rtl_cprop);
- NEXT_PASS (pass_rtl_pre);
-
-=== added file 'gcc/testsuite/gcc.dg/extend-1.c'
---- old/gcc/testsuite/gcc.dg/extend-1.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.dg/extend-1.c 2010-12-10 15:33:37 +0000
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fdump-rtl-ee" } */
-+
-+void f(unsigned char * p, short s, int c, int *z)
-+{
-+ if (c)
-+ *z = 0;
-+ *p ^= (unsigned char)s;
-+}
-+
-+/* { dg-final { scan-rtl-dump-times "sign_extend:" 0 "ee" { target mips*-*-* } } } */
-+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 1 "ee" { target mips*-*-* } } } */
-+/* { dg-final { cleanup-rtl-dump "ee" } } */
-
-=== added file 'gcc/testsuite/gcc.dg/extend-2-64.c'
---- old/gcc/testsuite/gcc.dg/extend-2-64.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.dg/extend-2-64.c 2010-12-10 15:33:37 +0000
-@@ -0,0 +1,20 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fdump-rtl-ee" } */
-+/* { dg-require-effective-target mips64 } */
-+
-+void f(unsigned char * p, short *s, int c)
-+{
-+ short or = 0;
-+ while (c)
-+ {
-+ or = or | s[c];
-+ c --;
-+ }
-+ *p = (unsigned char)or;
-+}
-+
-+/* { dg-final { scan-rtl-dump-times "zero_extend:" 1 "ee" { target mips*-*-* } } } */
-+/* { dg-final { scan-rtl-dump-times "sign_extend:" 0 "ee" { target mips*-*-* } } } */
-+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 3 "ee" { target mips*-*-* } } } */
-+/* { dg-final { cleanup-rtl-dump "ee" } } */
-+
-
-=== added file 'gcc/testsuite/gcc.dg/extend-2.c'
---- old/gcc/testsuite/gcc.dg/extend-2.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.dg/extend-2.c 2010-12-10 15:33:37 +0000
-@@ -0,0 +1,20 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fdump-rtl-ee" } */
-+/* { dg-require-effective-target ilp32 } */
-+
-+void f(unsigned char * p, short *s, int c)
-+{
-+ short or = 0;
-+ while (c)
-+ {
-+ or = or | s[c];
-+ c --;
-+ }
-+ *p = (unsigned char)or;
-+}
-+
-+/* { dg-final { scan-rtl-dump-times "zero_extend" 0 "ee" { target mips*-*-* } } } */
-+/* { dg-final { scan-rtl-dump-times "sign_extend" 0 "ee" { target mips*-*-* } } } */
-+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 2 "ee" { target mips*-*-* } } } */
-+/* { dg-final { cleanup-rtl-dump "ee" } } */
-+
-
-=== added file 'gcc/testsuite/gcc.dg/extend-3.c'
---- old/gcc/testsuite/gcc.dg/extend-3.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.dg/extend-3.c 2010-12-10 15:33:37 +0000
-@@ -0,0 +1,12 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fdump-rtl-ee" } */
-+
-+unsigned int f(unsigned char byte)
-+{
-+ return byte << 25;
-+}
-+
-+/* { dg-final { scan-rtl-dump-times "zero_extend:" 0 "ee" { target mips*-*-* } } } */
-+/* { dg-final { scan-rtl-dump "superfluous extension \[0-9\]+ replaced" "ee" { target mips*-*-* } } } */
-+/* { dg-final { cleanup-rtl-dump "ee" } } */
-+
-
-=== added file 'gcc/testsuite/gcc.dg/extend-4.c'
---- old/gcc/testsuite/gcc.dg/extend-4.c 1970-01-01 00:00:00 +0000
-+++ new/gcc/testsuite/gcc.dg/extend-4.c 2010-12-10 15:33:37 +0000
-@@ -0,0 +1,13 @@
-+/* { dg-do compile } */
-+/* { dg-options "-O2 -fdump-rtl-ee" } */
-+
-+unsigned char f(unsigned int a)
-+{
-+ unsigned int b = a & 0x10ff;
-+ return b;
-+}
-+
-+/* { dg-final { scan-rtl-dump-times "and:" 0 "ee" { target mips*-*-* } } } */
-+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 1 "ee" { target mips*-*-* } } } */
-+/* { dg-final { cleanup-rtl-dump "ee" } } */
-+
-
-=== modified file 'gcc/timevar.def'
---- old/gcc/timevar.def 2009-11-27 12:43:08 +0000
-+++ new/gcc/timevar.def 2010-12-10 15:33:37 +0000
-@@ -162,6 +162,7 @@
- DEFTIMEVAR (TV_VARCONST , "varconst")
- DEFTIMEVAR (TV_LOWER_SUBREG , "lower subreg")
- DEFTIMEVAR (TV_JUMP , "jump")
-+DEFTIMEVAR (TV_EE , "extension elimination")
- DEFTIMEVAR (TV_FWPROP , "forward prop")
- DEFTIMEVAR (TV_CSE , "CSE")
- DEFTIMEVAR (TV_DCE , "dead code elimination")
-
-=== modified file 'gcc/tree-pass.h'
---- old/gcc/tree-pass.h 2010-09-01 13:29:58 +0000
-+++ new/gcc/tree-pass.h 2010-12-10 15:33:37 +0000
-@@ -468,6 +468,7 @@
- extern struct rtl_opt_pass pass_initial_value_sets;
- extern struct rtl_opt_pass pass_unshare_all_rtl;
- extern struct rtl_opt_pass pass_instantiate_virtual_regs;
-+extern struct rtl_opt_pass pass_ee;
- extern struct rtl_opt_pass pass_rtl_fwprop;
- extern struct rtl_opt_pass pass_rtl_fwprop_addr;
- extern struct rtl_opt_pass pass_jump2;
-