From a5b022e7af7b70507d5e5d54eef6cb0621399607 Mon Sep 17 00:00:00 2001 From: tmsriram Date: Wed, 12 May 2010 21:15:19 +0000 Subject: * implicit-zee.c: New file. * tree-pass.h (pass_implicit_zee): Declare. * passes.c (init_optimization_passes): Add zee pass. * common.opt (fzee): New flag. * timevar.def (TV_ZEE): Define. * config/i386/i386.c (optimization_options): Turn on ZEE for level 2 and beyond. * Makefile.in (implicit-zee.o): Add new build file. * gcc.target/i386/zee.c: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159342 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/implicit-zee.c | 1002 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1002 insertions(+) create mode 100644 gcc/implicit-zee.c (limited to 'gcc/implicit-zee.c') diff --git a/gcc/implicit-zee.c b/gcc/implicit-zee.c new file mode 100644 index 00000000000..12cdfd95166 --- /dev/null +++ b/gcc/implicit-zee.c @@ -0,0 +1,1002 @@ +/* Redundant Zero-extension elimination for targets that implicitly + zero-extend writes to the lower 32-bit portion of 64-bit registers. + Copyright (C) 2010 Free Software Foundation, Inc. + Contributed by Sriraman Tallam (tmsriram@google.com) and + Silvius Rus (rus@google.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 +. */ + + +/* Problem Description : + -------------------- + This pass is intended to be applicable only to targets that implicitly + zero-extend 64-bit registers after writing to their lower 32-bit half. + For instance, x86_64 zero-extends the upper bits of a register + implicitly whenever an instruction writes to its lower 32-bit half. + For example, the instruction *add edi,eax* also zero-extends the upper + 32-bits of rax after doing the addition. These zero extensions come + for free and GCC does not always exploit this well. That is, it has + been observed that there are plenty of cases where GCC explicitly + zero-extends registers for x86_64 that are actually useless because + these registers were already implicitly zero-extended in a prior + instruction. This pass tries to eliminate such useless zero extension + instructions. + + How does this pass work ? + -------------------------- + + This pass is run after register allocation. Hence, all registers that + this pass deals with are hard registers. This pass first looks for a + zero-extension instruction that could possibly be redundant. Such zero + extension instructions show up in RTL with the pattern : + (set (reg:DI x) (zero_extend:DI (reg:SI x))). + where x can be any one of the 64-bit hard registers. + Now, this pass tries to eliminate this instruction by merging the + zero-extension with the definitions of register x. For instance, if + one of the definitions of register x was : + (set (reg:SI x) (plus:SI (reg:SI z1) (reg:SI z2))), + then the combination converts this into : + (set (reg:DI x) (zero_extend:DI (plus:SI (reg:SI z1) (reg:SI z2)))). + If all the merged definitions are recognizable assembly instructions, + the zero-extension is effectively eliminated. For example, in x86_64, + implicit zero-extensions are captured with appropriate patterns in the + i386.md file. Hence, these merged definition can be matched to a single + assembly instruction. The original zero-extension instruction is then + deleted if all the definitions can be merged. + + However, there are cases where the definition instruction cannot be + merged with a zero-extend. Examples are CALL instructions. In such + cases, the original zero extension is not redundant and this pass does + not delete it. + + Handling conditional moves : + ---------------------------- + + Architectures like x86_64 support conditional moves whose semantics for + zero-extension differ from the other instructions. For instance, the + instruction *cmov ebx, eax* + zero-extends eax onto rax only when the move from ebx to eax happens. + Otherwise, eax may not be zero-extended. Conditional moves appear as + RTL instructions of the form + (set (reg:SI x) (if_then_else (cond) (reg:SI y) (reg:SI z))). + This pass tries to merge a zero-extension with a conditional move by + actually merging the defintions of y and z with a zero-extend and then + converting the conditional move into : + (set (reg:DI x) (if_then_else (cond) (reg:DI y) (reg:DI z))). + Since registers y and z are zero-extended, register x will also be + zero-extended after the conditional move. Note that this step has to + be done transitively since the definition of a conditional copy can be + another conditional copy. + + Motivating Example I : + --------------------- + For this program : + ********************************************** + bad_code.c + + int mask[1000]; + + int foo(unsigned x) + { + if (x < 10) + x = x * 45; + else + x = x * 78; + return mask[x]; + } + ********************************************** + + $ gcc -O2 -fsee bad_code.c (Turned on existing sign-extension elimination.) + ........ + 400315: b8 4e 00 00 00 mov $0x4e,%eax + 40031a: 0f af f8 imul %eax,%edi + 40031d: 89 ff mov %edi,%edi ---> Useless extend. + 40031f: 8b 04 bd 60 19 40 00 mov 0x401960(,%rdi,4),%eax + 400326: c3 retq + ...... + 400330: ba 2d 00 00 00 mov $0x2d,%edx + 400335: 0f af fa imul %edx,%edi + 400338: 89 ff mov %edi,%edi ---> Useless extend. + 40033a: 8b 04 bd 60 19 40 00 mov 0x401960(,%rdi,4),%eax + 400341: c3 retq + + $ gcc -O2 -fzee bad_code.c + ...... + 400315: 6b ff 4e imul $0x4e,%edi,%edi + 400318: 8b 04 bd 40 19 40 00 mov 0x401940(,%rdi,4),%eax + 40031f: c3 retq + 400320: 6b ff 2d imul $0x2d,%edi,%edi + 400323: 8b 04 bd 40 19 40 00 mov 0x401940(,%rdi,4),%eax + 40032a: c3 retq + + Motivating Example II : + --------------------- + + Here is an example with a conditional move. + + For this program : + ********************************************** + + unsigned long long foo(unsigned x , unsigned y) + { + unsigned z; + if (x > 100) + z = x + y; + else + z = x - y; + return (unsigned long long)(z); + } + + $ gcc -O2 -fsee bad_code.c (Turned on existing sign-extension elimination.) + ............ + 400360: 8d 14 3e lea (%rsi,%rdi,1),%edx + 400363: 89 f8 mov %edi,%eax + 400365: 29 f0 sub %esi,%eax + 400367: 83 ff 65 cmp $0x65,%edi + 40036a: 0f 43 c2 cmovae %edx,%eax + 40036d: 89 c0 mov %eax,%eax ---> Useless extend. + 40036f: c3 retq + + $ gcc -O2 -fzee bad_code.c + ............. + 400360: 89 fa mov %edi,%edx + 400362: 8d 04 3e lea (%rsi,%rdi,1),%eax + 400365: 29 f2 sub %esi,%edx + 400367: 83 ff 65 cmp $0x65,%edi + 40036a: 89 d6 mov %edx,%esi + 40036c: 48 0f 42 c6 cmovb %rsi,%rax + 400370: c3 retq + + + Usefulness : + ---------- + + This pass reduces the dynamic instruction count of a compression benchmark by + 2.8% and improves its run-time by about 1%. The compression benchmark had the + following code sequence in a very hot region of code before ZEE optimized it : + + shr $0x5, %edx + mov %edx, %edx --> Useless zero-extend. + + How to turn on ? + ---------------- + -fzee -O2. */ + + +#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 "real.h" +#include "toplev.h" +#include "target.h" +#include "timevar.h" +#include "optabs.h" +#include "insn-codes.h" +#include "rtlhooks-def.h" +/* Include output.h for dump_file. */ +#include "output.h" +#include "params.h" +#include "timevar.h" +#include "tree-pass.h" +#include "df.h" +#include "cgraph.h" + +/* This says if a register is newly created for the purpose of + zero-extension. */ + +enum insn_merge_code +{ + MERGE_NOT_ATTEMPTED = 0, + MERGE_SUCCESS +}; + +/* This says if a INSN UID or its definition has already been merged + with a zero-extend or not. */ + +static enum insn_merge_code *is_insn_merge_attempted; +static int max_insn_uid; + +/* Returns the merge code status for INSN. */ + +static enum insn_merge_code +get_insn_status (rtx insn) +{ + gcc_assert (INSN_UID (insn) < max_insn_uid); + return is_insn_merge_attempted[INSN_UID (insn)]; +} + +/* Sets the merge code status of INSN to CODE. */ + +static void +set_insn_status (rtx insn, enum insn_merge_code code) +{ + gcc_assert (INSN_UID (insn) < max_insn_uid); + is_insn_merge_attempted[INSN_UID (insn)] = code; +} + +/* Check to see if this zero-extend matches a pattern + that could be eliminated. This is called via + for_each_rtx in function find_and_remove_ze. */ + +static int +is_set_with_extension_DI (rtx *expr, void *data) +{ + /* Looking only for patterns of the type : + SET (REG:DI X) (ZERO_EXTEND (REG:SI x)) + */ + + if (GET_CODE (*expr) == SET + && GET_MODE (SET_DEST (*expr)) == DImode + && GET_CODE (SET_DEST (*expr)) == REG + && GET_CODE (SET_SRC (*expr)) == ZERO_EXTEND + && GET_CODE (XEXP (SET_SRC (*expr),0)) == REG + && GET_MODE (XEXP (SET_SRC (*expr),0)) == SImode + && REGNO (SET_DEST (*expr)) == REGNO (XEXP (SET_SRC (*expr),0))) + { + *(rtx **)(data) = expr; + return 1; + } + return 0; +} + +/* Given a insn (CURR_INSN) and a pointer to the SET rtx (ORIG_SET) + that needs to be modified, this code modifies the SET rtx to a + new SET rtx that zero_extends the right hand expression into a DImode + register (NEWREG) on the left hand side. Note that multiple + assumptions are made about the nature of the set that needs + to be true for this to work and is called from merge_def_and_ze. + + Original : + (set (reg:SI a) (expression)) + + Transform : + (set (reg:DI a) (zero_extend (expression))) + + Special Cases : + If the expression is a constant or another zero_extend directly + assign it to the DI mode register. */ + +static bool +combine_set_zero_extend (rtx curr_insn, rtx *orig_set, rtx newreg) +{ + rtx temp_extension, simplified_temp_extension, new_set, new_const_int; + rtx orig_src; + HOST_WIDE_INT val; + unsigned int mask, delta_width; + + /* Change the SET rtx and validate it. */ + orig_src = SET_SRC (*orig_set); + new_set = NULL_RTX; + + /* The right hand side can also be VOIDmode. These cases have to be + handled differently. */ + + if (GET_MODE (orig_src) != SImode) + { + /* Merge constants by directly moving the constant into the + DImode register under some conditions. */ + + if (GET_CODE (orig_src) == CONST_INT + && HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (SImode)) + { + if (INTVAL (orig_src) >= 0) + new_set = gen_rtx_SET (VOIDmode, newreg, orig_src); + else if (INTVAL (orig_src) < 0) + { + /* Zero-extending a negative SImode integer into DImode + makes it a positive integer. Convert the given negative + integer into the appropriate integer when zero-extended. */ + + delta_width = HOST_BITS_PER_WIDE_INT - GET_MODE_BITSIZE (SImode); + mask = (~(unsigned HOST_WIDE_INT) 0) >> delta_width; + val = INTVAL (orig_src); + val = val & mask; + new_const_int = gen_rtx_CONST_INT (VOIDmode, val); + new_set = gen_rtx_SET (VOIDmode, newreg, new_const_int); + } + else + return false; + } + else + { + /* This is mostly due to a call insn that should not be + optimized. */ + + return false; + } + } + else if (GET_CODE (orig_src) == ZERO_EXTEND) + { + /* Here a zero-extend is used to get to SI. Why not make it + all the way till DI. */ + + temp_extension = gen_rtx_ZERO_EXTEND (DImode, XEXP (orig_src, 0)); + simplified_temp_extension = simplify_rtx (temp_extension); + if (simplified_temp_extension) + temp_extension = simplified_temp_extension; + new_set = gen_rtx_SET (VOIDmode, newreg, temp_extension); + } + else if (GET_CODE (orig_src) == IF_THEN_ELSE) + { + /* Only IF_THEN_ELSE of phi-type copies are combined. Otherwise, + in general, IF_THEN_ELSE should not be combined. */ + + return false; + } + else + { + /* This is the normal case we expect. */ + + temp_extension = gen_rtx_ZERO_EXTEND (DImode, orig_src); + simplified_temp_extension = simplify_rtx (temp_extension); + if (simplified_temp_extension) + temp_extension = simplified_temp_extension; + new_set = gen_rtx_SET (VOIDmode, newreg, temp_extension); + } + + gcc_assert (new_set != NULL_RTX); + + /* This change is a part of a group of changes. Hence, + validate_change will not try to commit the change. */ + + if (validate_change (curr_insn, orig_set, new_set, true)) + { + if (dump_file) + { + fprintf (dump_file, "Merged Instruction with ZERO_EXTEND:\n"); + print_rtl_single (dump_file, curr_insn); + } + return true; + } + return false; +} + +/* This returns the DI mode for the SI register REG_SI. */ + +static rtx +get_reg_di (rtx reg_si) +{ + rtx newreg; + + newreg = gen_rtx_REG (DImode, REGNO (reg_si)); + gcc_assert (newreg); + return newreg; +} + +/* Treat if_then_else insns, where the operands of both branches + are registers, as copies. For instance, + Original : + (set (reg:SI a) (if_then_else (cond) (reg:SI b) (reg:SI c))) + Transformed : + (set (reg:DI a) (if_then_else (cond) (reg:DI b) (reg:DI c))) + DEF_INSN is the if_then_else insn. */ + +static bool +transform_ifelse (rtx def_insn) +{ + rtx set_insn = PATTERN (def_insn); + rtx srcreg, dstreg, srcreg2; + rtx map_srcreg, map_dstreg, map_srcreg2; + rtx ifexpr; + rtx cond; + rtx new_set; + + gcc_assert (GET_CODE (set_insn) == SET); + cond = XEXP (SET_SRC (set_insn), 0); + dstreg = SET_DEST (set_insn); + srcreg = XEXP (SET_SRC (set_insn), 1); + srcreg2 = XEXP (SET_SRC (set_insn), 2); + map_srcreg = get_reg_di (srcreg); + map_srcreg2 = get_reg_di (srcreg2); + map_dstreg = get_reg_di (dstreg); + ifexpr = gen_rtx_IF_THEN_ELSE (DImode, cond, map_srcreg, map_srcreg2); + new_set = gen_rtx_SET (VOIDmode, map_dstreg, ifexpr); + + if (validate_change (def_insn, &PATTERN (def_insn), new_set, true)) + { + if (dump_file) + { + fprintf (dump_file, "Cond_Move Instruction's mode extended :\n"); + print_rtl_single (dump_file, def_insn); + } + return true; + } + else + return false; +} + +/* Function to get all the immediate definitions of an instruction. + The reaching definitions are desired for WHICH_REG used in + CURR_INSN. This function returns 0 if there was an error getting + a definition. Upon success, this function returns the number of + definitions and stores the definitions in DEST. */ + +static int +get_defs (rtx curr_insn, rtx which_reg, VEC (rtx,heap) **dest) +{ + df_ref reg_info, *defs; + struct df_link *def_chain; + int n_refs = 0; + + defs = DF_INSN_USES (curr_insn); + reg_info = NULL; + + while (*defs) + { + reg_info = *defs; + if (GET_CODE (DF_REF_REG (reg_info)) == SUBREG) + return 0; + if (REGNO (DF_REF_REG (reg_info)) == REGNO (which_reg)) + break; + defs++; + } + + gcc_assert (reg_info != NULL && defs != NULL); + def_chain = DF_REF_CHAIN (reg_info); + + while (def_chain) + { + /* Problem getting some definition for this instruction. */ + + if (def_chain->ref == NULL) + return 0; + if (DF_REF_INSN_INFO (def_chain->ref) == NULL) + return 0; + def_chain = def_chain->next; + } + + def_chain = DF_REF_CHAIN (reg_info); + + if (dest == NULL) + return 1; + + while (def_chain) + { + VEC_safe_push (rtx, heap, *dest, DF_REF_INSN (def_chain->ref)); + def_chain = def_chain->next; + n_refs++; + } + return n_refs; +} + +/* rtx function to check if this SET insn, EXPR, is a conditional copy insn : + (set (reg:SI a ) (IF_THEN_ELSE (cond) (reg:SI b) (reg:SI c))) + Called from is_insn_cond_copy. DATA stores the two registers on each + side of the condition. */ + +static int +is_this_a_cmove (rtx expr, void *data) +{ + /* Check for conditional (if-then-else) copy. */ + + if (GET_CODE (expr) == SET + && GET_CODE (SET_DEST (expr)) == REG + && GET_MODE (SET_DEST (expr)) == SImode + && GET_CODE (SET_SRC (expr)) == IF_THEN_ELSE + && GET_CODE (XEXP (SET_SRC (expr), 1)) == REG + && GET_MODE (XEXP (SET_SRC (expr), 1)) == SImode + && GET_CODE (XEXP (SET_SRC (expr), 2)) == REG + && GET_MODE (XEXP (SET_SRC (expr), 2)) == SImode) + { + ((rtx *)data)[0] = XEXP (SET_SRC (expr), 1); + ((rtx *)data)[1] = XEXP (SET_SRC (expr), 2); + return 1; + } + return 0; +} + +/* This returns 1 if it found + (SET (reg:SI REGNO (def_reg)) (if_then_else (cond) (REG:SI x1) (REG:SI x2))) + in the DEF_INSN pattern. It stores the x1 and x2 in COPY_REG_1 + and COPY_REG_2. */ + +static int +is_insn_cond_copy (rtx def_insn, rtx *copy_reg_1, rtx *copy_reg_2) +{ + int type; + rtx set_expr; + rtx srcreg[2]; + + srcreg[0] = NULL_RTX; + srcreg[1] = NULL_RTX; + + set_expr = single_set (def_insn); + + if (set_expr == NULL_RTX) + return 0; + + type = is_this_a_cmove (set_expr, (void *) srcreg); + + if (type) + { + *copy_reg_1 = srcreg[0]; + *copy_reg_2 = srcreg[1]; + return type; + } + + return 0; +} + +/* Reaching Definitions of the zero-extended register could be conditional + copies or regular definitions. This function separates the two types into + two lists, DEFS_LIST and COPIES_LIST. This is necessary because, if a + reaching definition is a conditional copy, combining the zero_extend with + this definition is wrong. Conditional copies are merged by transitively + merging its definitions. The defs_list is populated with all the reaching + definitions of the zero-extension instruction (ZERO_EXTEND_INSN) which must + be merged with a zero_extend. The copies_list contains all the conditional + moves that will later be extended into a DI mode conditonal move if all the + merges are successful. The function returns false when there is a failure + in getting some definitions, like that of parameters. It returns 1 upon + success, 0 upon failure and 2 when all definitions of the ZERO_EXTEND_INSN + were merged previously. */ + +static int +make_defs_and_copies_lists (rtx zero_extend_insn, rtx set_pat, + VEC (rtx,heap) **defs_list, + VEC (rtx,heap) **copies_list) +{ + bool *is_insn_visited; + VEC (rtx,heap) *work_list; + rtx srcreg, copy_reg_1, copy_reg_2; + rtx def_insn; + int n_defs = 0; + int vec_index = 0; + int n_worklist = 0; + int i, is_copy; + + srcreg = XEXP (SET_SRC (set_pat), 0); + work_list = VEC_alloc (rtx, heap, 8); + + /* Initialize the Work List */ + n_worklist = get_defs (zero_extend_insn, srcreg, &work_list); + + if (n_worklist == 0) + { + VEC_free (rtx, heap, work_list); + /* The number of defs being equal to zero can only imply that all of its + definitions have been previously merged. */ + return 2; + } + + is_insn_visited = XNEWVEC (bool, max_insn_uid); + + for (i = 0; i < max_insn_uid; i++) + is_insn_visited[i] = false; + + + /* Perform transitive closure for conditional copies. */ + while (n_worklist > vec_index) + { + def_insn = VEC_index (rtx, work_list, vec_index); + gcc_assert (INSN_UID (def_insn) < max_insn_uid); + + if (is_insn_visited[INSN_UID (def_insn)]) + { + vec_index++; + continue; + } + + is_insn_visited[INSN_UID (def_insn)] = true; + copy_reg_1 = copy_reg_2 = NULL_RTX; + is_copy = is_insn_cond_copy (def_insn, ©_reg_1, ©_reg_2); + if (is_copy) + { + gcc_assert (copy_reg_1 && copy_reg_2); + + /* Push it into the copy list first. */ + + VEC_safe_push (rtx, heap, *copies_list, def_insn); + + /* Perform transitive closure here */ + + n_defs = get_defs (def_insn, copy_reg_1, &work_list); + + if (n_defs == 0) + { + VEC_free (rtx, heap, work_list); + XDELETEVEC (is_insn_visited); + return 0; + } + n_worklist += n_defs; + + n_defs = get_defs (def_insn, copy_reg_2, &work_list); + if (n_defs == 0) + { + VEC_free (rtx, heap, work_list); + XDELETEVEC (is_insn_visited); + return 0; + } + n_worklist += n_defs; + } + else + { + VEC_safe_push (rtx, heap, *defs_list, def_insn); + } + vec_index++; + } + + VEC_free (rtx, heap, work_list); + XDELETEVEC (is_insn_visited); + return 1; +} + +/* Merge the DEF_INSN with a zero-extend. Calls combine_set_zero_extend + on the SET pattern. */ + +static bool +merge_def_and_ze (rtx def_insn) +{ + enum rtx_code code; + rtx setreg; + rtx *sub_rtx; + rtx s_expr; + int i; + + code = GET_CODE (PATTERN (def_insn)); + sub_rtx = NULL; + + if (code == PARALLEL) + { + for (i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++) + { + s_expr = XVECEXP (PATTERN (def_insn), 0, i); + if (GET_CODE (s_expr) != SET) + continue; + + if (sub_rtx == NULL) + sub_rtx = &XVECEXP (PATTERN (def_insn), 0, i); + else + { + /* PARALLEL with multiple SETs. */ + return false; + } + } + } + else if (code == SET) + sub_rtx = &PATTERN (def_insn); + else + { + /* It is not a PARALLEL or a SET, what could it be ? */ + return false; + } + + gcc_assert (sub_rtx != NULL); + + if (GET_CODE (SET_DEST (*sub_rtx)) == REG + && GET_MODE (SET_DEST (*sub_rtx)) == SImode) + { + setreg = get_reg_di (SET_DEST (*sub_rtx)); + return combine_set_zero_extend (def_insn, sub_rtx, setreg); + } + else + return false; + return true; +} + +/* This function goes through all reaching defs of the source + of the zero extension instruction (ZERO_EXTEND_INSN) and + tries to combine the zero extension with the definition + instruction. The changes are made as a group so that even + if one definition cannot be merged, all reaching definitions + end up not being merged. When a conditional copy is encountered, + merging is attempted transitively on its definitions. It returns + true upon success and false upon failure. */ + +static bool +combine_reaching_defs (rtx zero_extend_insn, rtx set_pat) +{ + rtx def_insn; + bool merge_successful = true; + int i; + int defs_ix; + int outcome; + + /* To store the definitions that have been merged. */ + + VEC (rtx, heap) *defs_list, *copies_list, *vec; + enum insn_merge_code merge_code; + + defs_list = VEC_alloc (rtx, heap, 8); + copies_list = VEC_alloc (rtx, heap, 8); + + outcome = make_defs_and_copies_lists (zero_extend_insn, + set_pat, &defs_list, &copies_list); + + /* outcome == 2 implies that all the definitions for this zero_extend were + merged while previously when handling other zero_extends. */ + + if (outcome == 2) + { + VEC_free (rtx, heap, defs_list); + VEC_free (rtx, heap, copies_list); + if (dump_file) + fprintf (dump_file, "All definitions have been merged previously...\n"); + return true; + } + + if (outcome == 0) + { + VEC_free (rtx, heap, defs_list); + VEC_free (rtx, heap, copies_list); + return false; + } + + merge_successful = true; + + /* Go through the defs vector and try to merge all the definitions + in this vector. */ + + vec = VEC_alloc (rtx, heap, 8); + for (defs_ix = 0; VEC_iterate (rtx, defs_list, defs_ix, def_insn); defs_ix++) + { + merge_code = get_insn_status (def_insn); + gcc_assert (merge_code == MERGE_NOT_ATTEMPTED); + + if (merge_def_and_ze (def_insn)) + VEC_safe_push (rtx, heap, vec, def_insn); + else + { + merge_successful = false; + break; + } + } + + /* Now go through the conditional copies vector and try to merge all + the copies in this vector. */ + + if (merge_successful) + { + for (i = 0; VEC_iterate (rtx, copies_list, i, def_insn); i++) + { + if (transform_ifelse (def_insn)) + { + VEC_safe_push (rtx, heap, vec, def_insn); + } + else + { + merge_successful = false; + break; + } + } + } + + if (merge_successful) + { + /* Commit the changes here if possible */ + /* XXX : Now, it is an all or nothing scenario. Even if one definition + cannot be merged we totally bail. In future, allow zero-extensions to + be partially eliminated along those paths where the definitions could + be merged. */ + + if (apply_change_group ()) + { + if (dump_file) + fprintf (dump_file, "All merges were successful ....\n"); + + for (i = 0; VEC_iterate (rtx, vec, i, def_insn); i++) + { + set_insn_status (def_insn, MERGE_SUCCESS); + } + + VEC_free (rtx, heap, vec); + VEC_free (rtx, heap, defs_list); + VEC_free (rtx, heap, copies_list); + return true; + } + else + { + /* Changes need not be cancelled explicitly as apply_change_group () + does it. Print list of definitions in the dump_file for debug + purposes. This zero-extension cannot be deleted. */ + + if (dump_file) + { + for (i = 0; VEC_iterate (rtx, vec, i, def_insn); i++) + { + fprintf (dump_file, " Ummergable definitions : \n"); + print_rtl_single (dump_file, def_insn); + } + } + } + } + else + { + /* Cancel any changes that have been made so far. */ + cancel_changes (0); + } + + VEC_free (rtx, heap, vec); + VEC_free (rtx, heap, defs_list); + VEC_free (rtx, heap, copies_list); + return false; +} + +/* Goes through the instruction stream looking for zero-extends. If the zero + extension instruction has atleast one def it adds it to a list of possible + candidates for deletion. It returns the list of candidates. */ + +static VEC (rtx,heap)* +find_removable_zero_extends (void) +{ + VEC (rtx, heap) *zeinsn_list; + basic_block curr_block; + rtx curr_insn; + rtx *set_insn; + rtx which_reg; + int type ; + int has_defs; + + zeinsn_list = VEC_alloc (rtx, heap, 8); + FOR_EACH_BB (curr_block) + { + FOR_BB_INSNS (curr_block, curr_insn) + { + if (!INSN_P (curr_insn)) + continue; + + type = for_each_rtx (&PATTERN (curr_insn), + is_set_with_extension_DI, + (void *)&set_insn); + + if (!type) + continue; + + which_reg = XEXP (SET_SRC (*set_insn), 0); + has_defs = get_defs (curr_insn, which_reg, NULL); + if (has_defs) + VEC_safe_push (rtx, heap, zeinsn_list, curr_insn); + else if (dump_file) + { + fprintf (dump_file, "Cannot eliminate zero extension : \n"); + print_rtl_single (dump_file, curr_insn); + fprintf (dump_file, + "This has no defs. Could be extending parameters.\n"); + } + } + } + return zeinsn_list; +} + +/* This is the main function that checks the insn stream for redundant + zero extensions and tries to remove them if possible. */ + +static unsigned int +find_and_remove_ze (void) +{ + rtx curr_insn = NULL_RTX; + int i; + int ix; + long long num_realized = 0; + long long num_ze_opportunities = 0; + VEC (rtx, heap) *zeinsn_list; + VEC (rtx, heap) *zeinsn_del_list; + + /* Construct DU chain to get all reaching definitions of each + zero-extension instruction. */ + + df_chain_add_problem (DF_UD_CHAIN + DF_DU_CHAIN); + df_analyze (); + + max_insn_uid = get_max_uid (); + + is_insn_merge_attempted = XNEWVEC (enum insn_merge_code, + sizeof (enum insn_merge_code)* max_insn_uid); + + for (i = 0; i < max_insn_uid; i++) + { + is_insn_merge_attempted[i] = MERGE_NOT_ATTEMPTED; + } + + num_ze_opportunities = num_realized = 0; + + zeinsn_del_list = VEC_alloc (rtx, heap, 4); + + zeinsn_list = find_removable_zero_extends (); + + for (ix = 0; VEC_iterate (rtx, zeinsn_list, ix, curr_insn); ix++) + { + num_ze_opportunities++; + /* Try to combine the zero-extends with the definition here. */ + + if (dump_file) + { + fprintf (dump_file, "Trying to eliminate zero extension : \n"); + print_rtl_single (dump_file, curr_insn); + } + + if (combine_reaching_defs (curr_insn, PATTERN (curr_insn))) + { + if (dump_file) + fprintf (dump_file, "Eliminated the zero extension...\n"); + num_realized++; + VEC_safe_push (rtx, heap, zeinsn_del_list, curr_insn); + } + } + + /* Delete all useless zero extensions here in one sweep. */ + for (ix = 0; VEC_iterate (rtx, zeinsn_del_list, ix, curr_insn); ix++) + { + delete_insn (curr_insn); + } + + free (is_insn_merge_attempted); + VEC_free (rtx, heap, zeinsn_list); + VEC_free (rtx, heap, zeinsn_del_list); + + if (dump_file && num_ze_opportunities > 0) + fprintf (dump_file, "\n %s : num_zee_opportunities = %lld " + "num_realized = %lld \n", + current_function_name (), + num_ze_opportunities, num_realized); + + df_finish_pass (false); + return 0; +} + +/* Find and remove redundant zero extensions. */ + +static unsigned int +rest_of_handle_zee (void) +{ + timevar_push (TV_ZEE); + find_and_remove_ze (); + timevar_pop (TV_ZEE); + return 0; +} + +/* Run zee pass when flag_zee is set at optimization level > 0. */ + +static bool +gate_handle_zee (void) +{ + return (optimize > 0 && flag_zee); +} + +struct rtl_opt_pass pass_implicit_zee = +{ + { + RTL_PASS, + "zee", /* name */ + gate_handle_zee, /* gate */ + rest_of_handle_zee, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_ZEE, /* 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 */ + } +}; -- cgit v1.2.1 From a7a4626828090600459358ca745c4482cf9551a1 Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 21 May 2010 13:53:22 +0000 Subject: gcc/ChangeLog: * tree.h: Include real.h and fixed-value.h as basic datatypes. * dfp.c, convert.c, reload1.c, reginfo.c, tree-flow.h, tree-ssa-threadedge.c, tree-ssanames.c, tree-loop-linear.c, tree-into-ssa.c, tree-vect-generic.c, tree-ssa-structalias.c, tree-ssa-loop-im.c, tree-dump.c, tree-complex.c, tree-ssa-uninit.c, genrecog.c, tree-ssa-threadupdate.c, tree-ssa-loop-niter.c, tree-pretty-print.c, tree-loop-distribution.c, tree-ssa-loop-unswitch.c, c-lex.c, optabs.c, postreload-gcse.c, tree-ssa-loop-manip.c, postreload.c, tree-ssa-loop-ch.c, tree-tailcall.c, tree.c, reload.c, tree-scalar-evolution.c, rtlanal.c, tree-phinodes.c, builtins.c, final.c, genoutput.c, fold-const.c, tree-ssa-dse.c, genautomata.c, tree-ssa-uncprop.c, toplev.c, tree-chrec.c, genemit.c, c-cppbuiltin.c, tree-ssa-sccvn.c, tree-ssa-ccp.c, tree-ssa-loop-ivopts.c, mode-switching.c, tree-call-cdce.c, cse.c, genpeep.c, tree-ssa-math-opts.c, tree-ssa-dom.c, tree-nrv.c, tree-ssa-propagate.c, tree-ssa-alias.c, tree-ssa-sink.c, jump.c, ifcvt.c, dwarf2out.c, expr.c, genattrtab.c, genconditions.c, tree-ssa-loop-ivcanon.c, tree-ssa-loop.c, tree-parloops.c, recog.c, tree-ssa-address.c, lcm.c, tree-eh.c, gimple-pretty-print.c, c-pretty-print.c, print-rtl.c, gcse.c, tree-if-conv.c, tree-data-ref.c, tree-affine.c, gimplify.c, tree-ssa-phiopt.c, implicit-zee.c, expmed.c, tree-dfa.c, emit-rtl.c, store-motion.c, cselib.c, tree-cfgcleanup.c, simplify-rtx.c, tree-ssa-pre.c, genpreds.c, tree-mudflap.c, print-tree.c, tree-ssa-copy.c, tree-ssa-forwprop.c, tree-ssa-dce.c, varasm.c, tree-nested.c, tree-ssa.c, tree-ssa-loop-prefetch.c, rtl.c, tree-inline.c, integrate.c, tree-optimize.c, tree-ssa-phiprop.c, fixed-value.c, combine.c, tree-profile.c, c-common.c, sched-vis.c, tree-cfg.c, passes.c, tree-ssa-reassoc.c, config/alpha/alpha.c, config/frv/frv.c, config/s390/s390.c, config/m32c/m32c.c, config/spu/spu.c, config/sparc/sparc.c, config/mep/mep.c, config/m32r/m32r.c, config/rx/rx.c, config/i386/i386.c, config/sh/sh.c, config/pdp11/pdp11.c, config/avr/avr.c, config/crx/crx.c, config/xtensa/xtensa.c, config/stormy16/stormy16.c, config/fr30/fr30.c, config/lm32/lm32.c, config/moxie/moxie.c, config/m68hc11/m68hc11.c, config/cris/cris.c, config/iq2000/iq2000.c, config/mn10300/mn10300.c, config/ia64/ia64.c, config/m68k/m68k.c, config/rs6000/rs6000.c, config/picochip/picochip.c, config/darwin.c, config/arc/arc.c, config/mcore/mcore.c, config/score/score3.c, config/score/score7.c, config/score/score.c, config/arm/arm.c, config/pa/pa.c, config/mips/mips.c, config/vax/vax.c, config/h8300/h8300.c, config/v850/v850.c, config/mmix/mmix.c, config/bfin/bfin.c: Clean up redundant includes. * Makefile.in: Update accordingly. java/ChangeLog: * typeck.c, decl.c, jcf-parse.c, except.c, expr.c: cp/Changelog: * error.c, tree.c, typeck2.c, cxx-pretty-print.c, mangle.c: Clean up redundant includes. fortran/ChangeLog: * trans-const.c, trans-types.c, trans-intrinsic.c: Clean up redundant includes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159663 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/implicit-zee.c | 1 - 1 file changed, 1 deletion(-) (limited to 'gcc/implicit-zee.c') diff --git a/gcc/implicit-zee.c b/gcc/implicit-zee.c index 12cdfd95166..3344d7f8af2 100644 --- a/gcc/implicit-zee.c +++ b/gcc/implicit-zee.c @@ -193,7 +193,6 @@ along with GCC; see the file COPYING3. If not see #include "expr.h" #include "insn-attr.h" #include "recog.h" -#include "real.h" #include "toplev.h" #include "target.h" #include "timevar.h" -- cgit v1.2.1 From 2194737c50f72655cb0d098b010840c14a2c40fc Mon Sep 17 00:00:00 2001 From: hjl Date: Fri, 25 Jun 2010 15:33:21 +0000 Subject: Don't search DEBUG_INSNs for removable zero extends. 2010-06-25 H.J. Lu PR rtl-optimization/44326 * implicit-zee.c (find_removable_zero_extends): Replace INSN_P with NONDEBUG_INSN_P. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161389 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/implicit-zee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/implicit-zee.c') diff --git a/gcc/implicit-zee.c b/gcc/implicit-zee.c index 3344d7f8af2..46029cdac38 100644 --- a/gcc/implicit-zee.c +++ b/gcc/implicit-zee.c @@ -858,7 +858,7 @@ find_removable_zero_extends (void) { FOR_BB_INSNS (curr_block, curr_insn) { - if (!INSN_P (curr_insn)) + if (!NONDEBUG_INSN_P (curr_insn)) continue; type = for_each_rtx (&PATTERN (curr_insn), -- cgit v1.2.1 From b749ba71e73e4264cb528d0cbd06194b508c168c Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Fri, 2 Jul 2010 19:25:30 +0000 Subject: * implicit-zee.c (combine_reaching_defs): Fix long lines. (is_set_with_extension_DI): Delete. (struct zero_extend_info): New structure. (add_removable_zero_extend ): New function. (find_removable_zero_extends): Use note_stores to find SETs. (find_and_remove_ze): Fix long line, remove superfluous parentheses. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161736 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/implicit-zee.c | 165 +++++++++++++++++++++++++---------------------------- 1 file changed, 79 insertions(+), 86 deletions(-) (limited to 'gcc/implicit-zee.c') diff --git a/gcc/implicit-zee.c b/gcc/implicit-zee.c index 46029cdac38..40a270bf8d7 100644 --- a/gcc/implicit-zee.c +++ b/gcc/implicit-zee.c @@ -100,17 +100,17 @@ along with GCC; see the file COPYING3. If not see } ********************************************** - $ gcc -O2 -fsee bad_code.c (Turned on existing sign-extension elimination.) + $ gcc -O2 -fsee bad_code.c (Turned on existing sign-extension elimination) ........ 400315: b8 4e 00 00 00 mov $0x4e,%eax 40031a: 0f af f8 imul %eax,%edi - 40031d: 89 ff mov %edi,%edi ---> Useless extend. + 40031d: 89 ff mov %edi,%edi --> Useless extend 40031f: 8b 04 bd 60 19 40 00 mov 0x401960(,%rdi,4),%eax 400326: c3 retq ...... 400330: ba 2d 00 00 00 mov $0x2d,%edx 400335: 0f af fa imul %edx,%edi - 400338: 89 ff mov %edi,%edi ---> Useless extend. + 400338: 89 ff mov %edi,%edi --> Useless extend 40033a: 8b 04 bd 60 19 40 00 mov 0x401960(,%rdi,4),%eax 400341: c3 retq @@ -141,14 +141,14 @@ along with GCC; see the file COPYING3. If not see return (unsigned long long)(z); } - $ gcc -O2 -fsee bad_code.c (Turned on existing sign-extension elimination.) + $ gcc -O2 -fsee bad_code.c (Turned on existing sign-extension elimination) ............ 400360: 8d 14 3e lea (%rsi,%rdi,1),%edx 400363: 89 f8 mov %edi,%eax 400365: 29 f0 sub %esi,%eax 400367: 83 ff 65 cmp $0x65,%edi 40036a: 0f 43 c2 cmovae %edx,%eax - 40036d: 89 c0 mov %eax,%eax ---> Useless extend. + 40036d: 89 c0 mov %eax,%eax --> Useless extend 40036f: c3 retq $ gcc -O2 -fzee bad_code.c @@ -165,16 +165,13 @@ along with GCC; see the file COPYING3. If not see Usefulness : ---------- - This pass reduces the dynamic instruction count of a compression benchmark by - 2.8% and improves its run-time by about 1%. The compression benchmark had the - following code sequence in a very hot region of code before ZEE optimized it : + This pass reduces the dynamic instruction count of a compression benchmark + by 2.8% and improves its run time by about 1%. The compression benchmark + had the following code sequence in a very hot region of code before ZEE + optimized it : shr $0x5, %edx - mov %edx, %edx --> Useless zero-extend. - - How to turn on ? - ---------------- - -fzee -O2. */ + mov %edx, %edx --> Useless zero-extend */ #include "config.h" @@ -240,31 +237,6 @@ set_insn_status (rtx insn, enum insn_merge_code code) is_insn_merge_attempted[INSN_UID (insn)] = code; } -/* Check to see if this zero-extend matches a pattern - that could be eliminated. This is called via - for_each_rtx in function find_and_remove_ze. */ - -static int -is_set_with_extension_DI (rtx *expr, void *data) -{ - /* Looking only for patterns of the type : - SET (REG:DI X) (ZERO_EXTEND (REG:SI x)) - */ - - if (GET_CODE (*expr) == SET - && GET_MODE (SET_DEST (*expr)) == DImode - && GET_CODE (SET_DEST (*expr)) == REG - && GET_CODE (SET_SRC (*expr)) == ZERO_EXTEND - && GET_CODE (XEXP (SET_SRC (*expr),0)) == REG - && GET_MODE (XEXP (SET_SRC (*expr),0)) == SImode - && REGNO (SET_DEST (*expr)) == REGNO (XEXP (SET_SRC (*expr),0))) - { - *(rtx **)(data) = expr; - return 1; - } - return 0; -} - /* Given a insn (CURR_INSN) and a pointer to the SET rtx (ORIG_SET) that needs to be modified, this code modifies the SET rtx to a new SET rtx that zero_extends the right hand expression into a DImode @@ -737,7 +709,7 @@ combine_reaching_defs (rtx zero_extend_insn, rtx set_pat) VEC_free (rtx, heap, defs_list); VEC_free (rtx, heap, copies_list); if (dump_file) - fprintf (dump_file, "All definitions have been merged previously...\n"); + fprintf (dump_file, "All definitions have been merged previously.\n"); return true; } @@ -812,8 +784,8 @@ combine_reaching_defs (rtx zero_extend_insn, rtx set_pat) } else { - /* Changes need not be cancelled explicitly as apply_change_group () - does it. Print list of definitions in the dump_file for debug + /* Changes need not be cancelled explicitly as apply_change_group + does it. Print list of definitions in the dump_file for debug purposes. This zero-extension cannot be deleted. */ if (dump_file) @@ -838,50 +810,74 @@ combine_reaching_defs (rtx zero_extend_insn, rtx set_pat) return false; } -/* Goes through the instruction stream looking for zero-extends. If the zero - extension instruction has atleast one def it adds it to a list of possible - candidates for deletion. It returns the list of candidates. */ +/* Carry information about zero-extensions while walking the RTL. */ + +struct zero_extend_info +{ + /* The insn where the zero-extension is. */ + rtx insn; + + /* The list of candidates. */ + VEC (rtx, heap) *insn_list; +}; + +/* Add a zero-extend pattern that could be eliminated. This is called via + note_stores from find_removable_zero_extends. */ + +static void +add_removable_zero_extend (rtx x ATTRIBUTE_UNUSED, const_rtx expr, void *data) +{ + struct zero_extend_info *zei = (struct zero_extend_info *)data; + rtx src, dest; + + /* We are looking for SET (REG:DI N) (ZERO_EXTEND (REG:SI N)). */ + if (GET_CODE (expr) != SET) + return; + + src = SET_SRC (expr); + dest = SET_DEST (expr); + + if (REG_P (dest) + && GET_MODE (dest) == DImode + && GET_CODE (src) == ZERO_EXTEND + && REG_P (XEXP (src, 0)) + && GET_MODE (XEXP (src, 0)) == SImode + && REGNO (dest) == REGNO (XEXP (src, 0))) + { + if (get_defs (zei->insn, XEXP (src, 0), NULL)) + VEC_safe_push (rtx, heap, zei->insn_list, zei->insn); + else if (dump_file) + { + fprintf (dump_file, "Cannot eliminate zero-extension: \n"); + print_rtl_single (dump_file, zei->insn); + fprintf (dump_file, "No defs. Could be extending parameters.\n"); + } + } +} + +/* Traverse the instruction stream looking for zero-extends and return the + list of candidates. */ static VEC (rtx,heap)* find_removable_zero_extends (void) { - VEC (rtx, heap) *zeinsn_list; - basic_block curr_block; - rtx curr_insn; - rtx *set_insn; - rtx which_reg; - int type ; - int has_defs; - - zeinsn_list = VEC_alloc (rtx, heap, 8); - FOR_EACH_BB (curr_block) - { - FOR_BB_INSNS (curr_block, curr_insn) - { - if (!NONDEBUG_INSN_P (curr_insn)) - continue; + struct zero_extend_info zei; + basic_block bb; + rtx insn; - type = for_each_rtx (&PATTERN (curr_insn), - is_set_with_extension_DI, - (void *)&set_insn); + zei.insn_list = VEC_alloc (rtx, heap, 8); - if (!type) - continue; + FOR_EACH_BB (bb) + FOR_BB_INSNS (bb, insn) + { + if (!NONDEBUG_INSN_P (insn)) + continue; - which_reg = XEXP (SET_SRC (*set_insn), 0); - has_defs = get_defs (curr_insn, which_reg, NULL); - if (has_defs) - VEC_safe_push (rtx, heap, zeinsn_list, curr_insn); - else if (dump_file) - { - fprintf (dump_file, "Cannot eliminate zero extension : \n"); - print_rtl_single (dump_file, curr_insn); - fprintf (dump_file, - "This has no defs. Could be extending parameters.\n"); - } - } - } - return zeinsn_list; + zei.insn = insn; + note_stores (PATTERN (insn), add_removable_zero_extend, &zei); + } + + return zei.insn_list; } /* This is the main function that checks the insn stream for redundant @@ -906,13 +902,12 @@ find_and_remove_ze (void) max_insn_uid = get_max_uid (); - is_insn_merge_attempted = XNEWVEC (enum insn_merge_code, - sizeof (enum insn_merge_code)* max_insn_uid); + is_insn_merge_attempted + = XNEWVEC (enum insn_merge_code, + sizeof (enum insn_merge_code) * max_insn_uid); for (i = 0; i < max_insn_uid; i++) - { - is_insn_merge_attempted[i] = MERGE_NOT_ATTEMPTED; - } + is_insn_merge_attempted[i] = MERGE_NOT_ATTEMPTED; num_ze_opportunities = num_realized = 0; @@ -942,9 +937,7 @@ find_and_remove_ze (void) /* Delete all useless zero extensions here in one sweep. */ for (ix = 0; VEC_iterate (rtx, zeinsn_del_list, ix, curr_insn); ix++) - { - delete_insn (curr_insn); - } + delete_insn (curr_insn); free (is_insn_merge_attempted); VEC_free (rtx, heap, zeinsn_list); -- cgit v1.2.1 From 0b205f4ca112a643f4f1b9c9886648b569e0b380 Mon Sep 17 00:00:00 2001 From: manu Date: Thu, 8 Jul 2010 04:22:54 +0000 Subject: =?UTF-8?q?2010-07-08=20=20Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez=20?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * toplev.h: Do not include diagnostic-core.h. Include diagnostic-core.h in every file that includes toplev.h. * c-tree.h: Do not include toplev.h. * pretty-print.h: Update comment. * Makefile.in: Update dependencies. * alias.c: Include diagnostic-core.h in every file that includes toplev.h. * attribs.c: Likewise. * auto-inc-dec.c: Likewise. * bb-reorder.c: Likewise. * bt-load.c: Likewise. * caller-save.c: Likewise. * calls.c: Likewise. * cfg.c: Likewise. * cfganal.c: Likewise. * cfgbuild.c: Likewise. * cfgcleanup.c: Likewise. * cfghooks.c: Likewise. * cfgloop.c: Likewise. * combine.c: Likewise. * config/alpha/alpha.c: Likewise. * config/arc/arc.c: Likewise. * config/arm/arm.c: Likewise. * config/arm/pe.c: Likewise. * config/avr/avr.c: Likewise. * config/bfin/bfin.c: Likewise. * config/cris/cris.c: Likewise. * config/crx/crx.c: Likewise. * config/darwin-c.c: Likewise. * config/darwin.c: Likewise. * config/fr30/fr30.c: Likewise. * config/frv/frv.c: Likewise. * config/h8300/h8300.c: Likewise. * config/host-darwin.c: Likewise. * config/i386/i386.c: Likewise. * config/i386/netware.c: Likewise. * config/i386/nwld.c: Likewise. * config/i386/winnt-cxx.c: Likewise. * config/i386/winnt-stubs.c: Likewise. * config/i386/winnt.c: Likewise. * config/ia64/ia64-c.c: Likewise. * config/ia64/ia64.c: Likewise. * config/iq2000/iq2000.c: Likewise. * config/lm32/lm32.c: Likewise. * config/m32c/m32c-pragma.c: Likewise. * config/m32c/m32c.c: Likewise. * config/m32r/m32r.c: Likewise. * config/m68hc11/m68hc11.c: Likewise. * config/m68k/m68k.c: Likewise. * config/mcore/mcore.c: Likewise. * config/mep/mep-pragma.c: Likewise. * config/mep/mep.c: Likewise. * config/mmix/mmix.c: Likewise. * config/mn10300/mn10300.c: Likewise. * config/moxie/moxie.c: Likewise. * config/pa/pa.c: Likewise. * config/pdp11/pdp11.c: Likewise. * config/picochip/picochip.c: Likewise. * config/rs6000/rs6000-c.c: Likewise. * config/rs6000/rs6000.c: Likewise. * config/rx/rx.c: Likewise. * config/s390/s390.c: Likewise. * config/score/score.c: Likewise. * config/score/score3.c: Likewise. * config/score/score7.c: Likewise. * config/sh/sh.c: Likewise. * config/sh/symbian-base.c: Likewise. * config/sh/symbian-c.c: Likewise. * config/sh/symbian-cxx.c: Likewise. * config/sol2-c.c: Likewise. * config/sol2.c: Likewise. * config/sparc/sparc.c: Likewise. * config/spu/spu.c: Likewise. * config/stormy16/stormy16.c: Likewise. * config/v850/v850-c.c: Likewise. * config/v850/v850.c: Likewise. * config/vax/vax.c: Likewise. * config/vxworks.c: Likewise. * config/xtensa/xtensa.c: Likewise. * convert.c: Likewise. * cse.c: Likewise. * cselib.c: Likewise. * dbgcnt.c: Likewise. * dbxout.c: Likewise. * ddg.c: Likewise. * dominance.c: Likewise. * emit-rtl.c: Likewise. * explow.c: Likewise. * expmed.c: Likewise. * fixed-value.c: Likewise. * fold-const.c: Likewise. * fwprop.c: Likewise. * gcse.c: Likewise. * ggc-common.c: Likewise. * ggc-page.c: Likewise. * ggc-zone.c: Likewise. * gimple-low.c: Likewise. * gimplify.c: Likewise. * graph.c: Likewise. * haifa-sched.c: Likewise. * ifcvt.c: Likewise. * implicit-zee.c: Likewise. * integrate.c: Likewise. * ira-build.c: Likewise. * ira-color.c: Likewise. * ira-conflicts.c: Likewise. * ira-costs.c: Likewise. * ira-lives.c: Likewise. * ira.c: Likewise. * lists.c: Likewise. * loop-doloop.c: Likewise. * loop-iv.c: Likewise. * lto-opts.c: Likewise. * lto-symtab.c: Likewise. * main.c: Likewise. * modulo-sched.c: Likewise. * optabs.c: Likewise. * params.c: Likewise. * plugin.c: Likewise. * postreload-gcse.c: Likewise. * postreload.c: Likewise. * predict.c: Likewise. * profile.c: Likewise. * real.c: Likewise. * regcprop.c: Likewise. * reginfo.c: Likewise. * regmove.c: Likewise. * reorg.c: Likewise. * resource.c: Likewise. * rtl.c: Likewise. * rtlanal.c: Likewise. * sched-deps.c: Likewise. * sched-ebb.c: Likewise. * sched-rgn.c: Likewise. * sdbout.c: Likewise. * sel-sched-dump.c: Likewise. * sel-sched-ir.c: Likewise. * simplify-rtx.c: Likewise. * stmt.c: Likewise. * stor-layout.c: Likewise. * store-motion.c: Likewise. * targhooks.c: Likewise. * tree-cfg.c: Likewise. * tree-cfgcleanup.c: Likewise. * tree-dump.c: Likewise. * tree-eh.c: Likewise. * tree-inline.c: Likewise. * tree-nomudflap.c: Likewise. * tree-object-size.c: Likewise. * tree-optimize.c: Likewise. * tree-outof-ssa.c: Likewise. * tree-phinodes.c: Likewise. * tree-profile.c: Likewise. * tree-ssa-ccp.c: Likewise. * tree-ssa-coalesce.c: Likewise. * tree-ssa-live.c: Likewise. * tree-ssa-loop-niter.c: Likewise. * tree-ssa-loop-prefetch.c: Likewise. * tree-ssa-loop.c: Likewise. * tree-ssa-structalias.c: Likewise. * tree-ssa-uninit.c: Likewise. * tree-ssa.c: Likewise. * tree-vect-data-refs.c: Likewise. * tree-vect-loop-manip.c: Likewise. * tree-vect-loop.c: Likewise. * tree-vect-patterns.c: Likewise. * tree-vect-stmts.c: Likewise. * tree-vrp.c: Likewise. * varasm.c: Likewise. * vec.c: Likewise. * web.c: Likewise. * xcoffout.c: Likewise. c-family/ * c-common.h: Include diagnostic-core.h. Error if already included. * c-semantics.c: Do not define GCC_DIAG_STYLE here. cp/ * cp-tree.h: Do not include toplev.h. java/ * boehm.c: Include diagnostic-core.h in every file that includes toplev.h. * class.c: Likewise. * constants.c: Likewise. * decl.c: Likewise. * except.c: Likewise. * expr.c: Likewise. * jcf-parse.c: Likewise. * mangle.c: Likewise. * mangle_name.c: Likewise. * resource.c: Likewise. * typeck.c: Likewise. * verify-glue.c: Likewise. ada/ * gcc-interface/utils.c: Include diagnostic-core.h in every file that includes toplev.h. lto/ * lto-coff.c: Include diagnostic-core.h in every file that includes toplev.h. * lto-elf.c: Likewise. * lto-lang.c: Likewise. * lto-macho.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161943 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/implicit-zee.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/implicit-zee.c') diff --git a/gcc/implicit-zee.c b/gcc/implicit-zee.c index 40a270bf8d7..e2716d305a7 100644 --- a/gcc/implicit-zee.c +++ b/gcc/implicit-zee.c @@ -190,6 +190,7 @@ along with GCC; see the file COPYING3. If not see #include "expr.h" #include "insn-attr.h" #include "recog.h" +#include "diagnostic-core.h" #include "toplev.h" #include "target.h" #include "timevar.h" -- cgit v1.2.1