diff --git a/Big-endian-union-bitfield-bugfix.patch b/Big-endian-union-bitfield-bugfix.patch deleted file mode 100644 index a9dfcbba1fd1502bdcf99baab7d7fc8d24ccdd96..0000000000000000000000000000000000000000 --- a/Big-endian-union-bitfield-bugfix.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 900ccfa89dda3ab5f7e44a0dd4d1e9d108b5dc8b Mon Sep 17 00:00:00 2001 -From: rguenth -Date: Tue, 26 Mar 2019 13:18:23 +0000 -Subject: [PATCH] 2019-02-26 Richard Biener - - Backport from mainline - 2019-02-12 Richard Biener - - PR tree-optimization/89253 - * tree-ssa-loop-split.c (tree_ssa_split_loops): Check we can - duplicate the loop. - - * gfortran.dg/pr89253.f: New testcase. - - 2019-02-08 Richard Biener - - PR middle-end/89223 - * tree-data-ref.c (initialize_matrix_A): Fail if constant - doesn't fit in HWI. - (analyze_subscript_affine_affine): Handle failure from - initialize_matrix_A. - - * gcc.dg/torture/pr89223.c: New testcase. - - 2019-01-28 Richard Biener - - PR tree-optimization/88739 - * tree-ssa-sccvn.c (vn_reference_lookup_3): Avoid generating - BIT_FIELD_REFs of non-mode-precision integral operands. - - * gcc.c-torture/execute/pr88739.c: New test. - - -git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@269942 138bc75d-0d04-0410-961f-82ee72b054a4 ---- -diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c -index 2480f4e..a349e3e 100644 ---- a/gcc/tree-data-ref.c -+++ b/gcc/tree-data-ref.c -@@ -2118,6 +2118,8 @@ initialize_matrix_A (lambda_matrix A, tree chrec, unsigned index, int mult) - switch (TREE_CODE (chrec)) - { - case POLYNOMIAL_CHREC: -+ if (!cst_and_fits_in_hwi (CHREC_RIGHT (chrec))) -+ return chrec_dont_know; - A[index][0] = mult * int_cst_value (CHREC_RIGHT (chrec)); - return initialize_matrix_A (A, CHREC_LEFT (chrec), index + 1, mult); - -@@ -2499,7 +2501,7 @@ analyze_subscript_affine_affine (tree chrec_a, - tree *last_conflicts) - { - unsigned nb_vars_a, nb_vars_b, dim; -- HOST_WIDE_INT init_a, init_b, gamma, gcd_alpha_beta; -+ HOST_WIDE_INT gamma, gcd_alpha_beta; - lambda_matrix A, U, S; - struct obstack scratch_obstack; - -@@ -2536,9 +2538,20 @@ analyze_subscript_affine_affine (tree chrec_a, - A = lambda_matrix_new (dim, 1, &scratch_obstack); - S = lambda_matrix_new (dim, 1, &scratch_obstack); - -- init_a = int_cst_value (initialize_matrix_A (A, chrec_a, 0, 1)); -- init_b = int_cst_value (initialize_matrix_A (A, chrec_b, nb_vars_a, -1)); -- gamma = init_b - init_a; -+ tree init_a = initialize_matrix_A (A, chrec_a, 0, 1); -+ tree init_b = initialize_matrix_A (A, chrec_b, nb_vars_a, -1); -+ if (init_a == chrec_dont_know -+ || init_b == chrec_dont_know) -+ { -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ fprintf (dump_file, "affine-affine test failed: " -+ "representation issue.\n"); -+ *overlaps_a = conflict_fn_not_known (); -+ *overlaps_b = conflict_fn_not_known (); -+ *last_conflicts = chrec_dont_know; -+ goto end_analyze_subs_aa; -+ } -+ gamma = int_cst_value (init_b) - int_cst_value (init_a); - - /* Don't do all the hard work of solving the Diophantine equation - when we already know the solution: for example, -diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c -index fd97213..3992597 100644 ---- a/gcc/tree-ssa-loop-split.c -+++ b/gcc/tree-ssa-loop-split.c -@@ -649,7 +649,8 @@ tree_ssa_split_loops (void) - false, true) - && niter.cmp != ERROR_MARK - /* We can't yet handle loops controlled by a != predicate. */ -- && niter.cmp != NE_EXPR) -+ && niter.cmp != NE_EXPR -+ && can_duplicate_loop_p (loop)) - { - if (split_loop (loop, &niter)) - { -diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c -index c93f1f2..a2e3ce2 100644 ---- a/gcc/tree-ssa-sccvn.c -+++ b/gcc/tree-ssa-sccvn.c -@@ -2029,6 +2029,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, - base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), - &offset2, &size2, &maxsize2, - &reverse); -+ tree def_rhs = gimple_assign_rhs1 (def_stmt); - if (!reverse - && maxsize2 != -1 - && maxsize2 == size2 -@@ -2041,11 +2042,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, - according to endianness. */ - && (! INTEGRAL_TYPE_P (vr->type) - || ref->size == TYPE_PRECISION (vr->type)) -- && ref->size % BITS_PER_UNIT == 0) -+ && ref->size % BITS_PER_UNIT == 0 -+ && (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs)) -+ || (TYPE_PRECISION (TREE_TYPE (def_rhs)) -+ == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (def_rhs)))))) - { - code_helper rcode = BIT_FIELD_REF; - tree ops[3]; -- ops[0] = SSA_VAL (gimple_assign_rhs1 (def_stmt)); -+ ops[0] = SSA_VAL (def_rhs); - ops[1] = bitsize_int (ref->size); - ops[2] = bitsize_int (offset - offset2); - tree val = vn_nary_build_or_lookup (rcode, vr->type, ops); --- -2.9.3 diff --git a/CVE-2018-12886.patch b/CVE-2018-12886.patch deleted file mode 100644 index 5e782d67b8551fd21513a0b83aaf80f20dc8976a..0000000000000000000000000000000000000000 --- a/CVE-2018-12886.patch +++ /dev/null @@ -1,655 +0,0 @@ -diff -urpN a/gcc/cfgexpand.c b/gcc/cfgexpand.c ---- a/gcc/cfgexpand.c 2019-05-30 16:58:45.350508770 +0800 -+++ b/gcc/cfgexpand.c 2019-05-30 11:53:13.315156625 +0800 -@@ -6094,6 +6094,23 @@ stack_protect_prologue (void) - rtx x, y; - - x = expand_normal (crtl->stack_protect_guard); -+ -+ if (targetm.have_stack_protect_combined_set () && guard_decl) -+ { -+ gcc_assert (DECL_P (guard_decl)); -+ y = DECL_RTL (guard_decl); -+ -+ /* Allow the target to compute address of Y and copy it to X without -+ leaking Y into a register. This combined address + copy pattern -+ allows the target to prevent spilling of any intermediate results by -+ splitting it after register allocator. */ -+ if (rtx_insn *insn = targetm.gen_stack_protect_combined_set (x, y)) -+ { -+ emit_insn (insn); -+ return; -+ } -+ } -+ - if (guard_decl) - y = expand_normal (guard_decl); - else -diff -urpN a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c ---- a/gcc/config/arm/arm.c 2019-05-30 16:58:45.354508770 +0800 -+++ b/gcc/config/arm/arm.c 2019-05-30 16:59:05.058508073 +0800 -@@ -7236,21 +7236,34 @@ legitimate_pic_operand_p (rtx x) - return 1; - } - --/* Record that the current function needs a PIC register. Initialize -- cfun->machine->pic_reg if we have not already done so. */ -+/* Record that the current function needs a PIC register. If PIC_REG is null, -+ a new pseudo is allocated as PIC register, otherwise PIC_REG is used. In -+ both case cfun->machine->pic_reg is initialized if we have not already done -+ so. COMPUTE_NOW decide whether and where to set the PIC register. If true, -+ PIC register is reloaded in the current position of the instruction stream -+ irregardless of whether it was loaded before. Otherwise, it is only loaded -+ if not already done so (crtl->uses_pic_offset_table is null). Note that -+ nonnull PIC_REG is only supported iff COMPUTE_NOW is true and null PIC_REG -+ is only supported iff COMPUTE_NOW is false. */ - - static void --require_pic_register (void) -+require_pic_register (rtx pic_reg, bool compute_now) - { -+ gcc_assert (compute_now == (pic_reg != NULL_RTX)); -+ - /* A lot of the logic here is made obscure by the fact that this - routine gets called as part of the rtx cost estimation process. - We don't want those calls to affect any assumptions about the real - function; and further, we can't call entry_of_function() until we - start the real expansion process. */ -- if (!crtl->uses_pic_offset_table) -+ if (!crtl->uses_pic_offset_table || compute_now) - { -- gcc_assert (can_create_pseudo_p ()); -+ gcc_assert (can_create_pseudo_p () -+ || (pic_reg != NULL_RTX -+ && REG_P (pic_reg) -+ && GET_MODE (pic_reg) == Pmode)); - if (arm_pic_register != INVALID_REGNUM -+ && !compute_now - && !(TARGET_THUMB1 && arm_pic_register > LAST_LO_REGNUM)) - { - if (!cfun->machine->pic_reg) -@@ -7266,8 +7279,19 @@ require_pic_register (void) - { - rtx_insn *seq, *insn; - -- if (!cfun->machine->pic_reg) -- cfun->machine->pic_reg = gen_reg_rtx (Pmode); -+ if (pic_reg == NULL_RTX && cfun->machine->pic_reg == NULL_RTX) -+ { -+ pic_reg = gen_reg_rtx (Pmode); -+ cfun->machine->pic_reg = pic_reg; -+ } -+ else if (pic_reg == NULL_RTX) -+ { -+ pic_reg = cfun->machine->pic_reg; -+ } -+ else if (cfun->machine->pic_reg == NULL_RTX) -+ { -+ cfun->machine->pic_reg = pic_reg; -+ } - - /* Play games to avoid marking the function as needing pic - if we are being called as part of the cost-estimation -@@ -7278,11 +7306,12 @@ require_pic_register (void) - start_sequence (); - - if (TARGET_THUMB1 && arm_pic_register != INVALID_REGNUM -- && arm_pic_register > LAST_LO_REGNUM) -+ && arm_pic_register > LAST_LO_REGNUM -+ && !compute_now) - emit_move_insn (cfun->machine->pic_reg, - gen_rtx_REG (Pmode, arm_pic_register)); - else -- arm_load_pic_register (0UL); -+ arm_load_pic_register (0UL, pic_reg); - - seq = get_insns (); - end_sequence (); -@@ -7295,16 +7324,33 @@ require_pic_register (void) - we can't yet emit instructions directly in the final - insn stream. Queue the insns on the entry edge, they will - be committed after everything else is expanded. */ -- insert_insn_on_edge (seq, -- single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); -+ if (currently_expanding_to_rtl) -+ insert_insn_on_edge (seq, -+ single_succ_edge -+ (ENTRY_BLOCK_PTR_FOR_FN (cfun))); -+ else -+ emit_insn (seq); - } - } - } - } - -+/* Legitimize PIC load to ORIG into REG. If REG is NULL, a new pseudo is -+ created to hold the result of the load. If not NULL, PIC_REG indicates -+ which register to use as PIC register, otherwise it is decided by register -+ allocator. COMPUTE_NOW forces the PIC register to be loaded at the current -+ location in the instruction stream, irregardless of whether it was loaded -+ previously. Note that nonnull PIC_REG is only supported iff COMPUTE_NOW is -+ true and null PIC_REG is only supported iff COMPUTE_NOW is false. -+ -+ Returns the register REG into which the PIC load is performed. */ -+ - rtx --legitimize_pic_address (rtx orig, machine_mode mode, rtx reg) -+legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg, -+ bool compute_now) - { -+ gcc_assert (compute_now == (pic_reg != NULL_RTX)); -+ - if (GET_CODE (orig) == SYMBOL_REF - || GET_CODE (orig) == LABEL_REF) - { -@@ -7337,9 +7383,12 @@ legitimize_pic_address (rtx orig, machin - rtx mem; - - /* If this function doesn't have a pic register, create one now. */ -- require_pic_register (); -+ require_pic_register (pic_reg, compute_now); -+ -+ if (pic_reg == NULL_RTX) -+ pic_reg = cfun->machine->pic_reg; - -- pat = gen_calculate_pic_address (reg, cfun->machine->pic_reg, orig); -+ pat = gen_calculate_pic_address (reg, pic_reg, orig); - - /* Make the MEM as close to a constant as possible. */ - mem = SET_SRC (pat); -@@ -7388,9 +7437,11 @@ legitimize_pic_address (rtx orig, machin - - gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); - -- base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); -+ base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg, -+ pic_reg, compute_now); - offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, -- base == reg ? 0 : reg); -+ base == reg ? 0 : reg, pic_reg, -+ compute_now); - - if (CONST_INT_P (offset)) - { -@@ -7490,16 +7541,17 @@ static GTY(()) int pic_labelno; - low register. */ - - void --arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) -+arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED, rtx pic_reg) - { -- rtx l1, labelno, pic_tmp, pic_rtx, pic_reg; -+ rtx l1, labelno, pic_tmp, pic_rtx; - - if (crtl->uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE) - return; - - gcc_assert (flag_pic); - -- pic_reg = cfun->machine->pic_reg; -+ if (pic_reg == NULL_RTX) -+ pic_reg = cfun->machine->pic_reg; - if (TARGET_VXWORKS_RTP) - { - pic_rtx = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE); -@@ -8558,7 +8610,8 @@ arm_legitimize_address (rtx x, rtx orig_ - { - /* We need to find and carefully transform any SYMBOL and LABEL - references; so go back to the original address expression. */ -- rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX); -+ rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX, NULL_RTX, -+ false /*compute_now*/); - - if (new_x != orig_x) - x = new_x; -@@ -8626,7 +8679,8 @@ thumb_legitimize_address (rtx x, rtx ori - { - /* We need to find and carefully transform any SYMBOL and LABEL - references; so go back to the original address expression. */ -- rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX); -+ rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX, NULL_RTX, -+ false /*compute_now*/); - - if (new_x != orig_x) - x = new_x; -@@ -17800,7 +17854,7 @@ arm_emit_call_insn (rtx pat, rtx addr, b - ? !targetm.binds_local_p (SYMBOL_REF_DECL (addr)) - : !SYMBOL_REF_LOCAL_P (addr))) - { -- require_pic_register (); -+ require_pic_register (NULL_RTX, false /*compute_now*/); - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), cfun->machine->pic_reg); - } - -@@ -21706,7 +21760,7 @@ arm_expand_prologue (void) - mask &= THUMB2_WORK_REGS; - if (!IS_NESTED (func_type)) - mask |= (1 << IP_REGNUM); -- arm_load_pic_register (mask); -+ arm_load_pic_register (mask, NULL_RTX); - } - - /* If we are profiling, make sure no instructions are scheduled before -@@ -24909,7 +24963,7 @@ thumb1_expand_prologue (void) - /* Load the pic register before setting the frame pointer, - so we can use r7 as a temporary work register. */ - if (flag_pic && arm_pic_register != INVALID_REGNUM) -- arm_load_pic_register (live_regs_mask); -+ arm_load_pic_register (live_regs_mask, NULL_RTX); - - if (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0) - emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM), -diff -urpN a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md ---- a/gcc/config/arm/arm.md 2019-05-30 16:58:45.358508769 +0800 -+++ b/gcc/config/arm/arm.md 2019-05-30 11:52:58.491157149 +0800 -@@ -6051,7 +6051,8 @@ - operands[1] = legitimize_pic_address (operands[1], SImode, - (!can_create_pseudo_p () - ? operands[0] -- : 0)); -+ : NULL_RTX), NULL_RTX, -+ false /*compute_now*/); - } - " - ) -@@ -6340,7 +6341,7 @@ - /* r3 is clobbered by set/longjmp, so we can use it as a scratch - register. */ - if (arm_pic_register != INVALID_REGNUM) -- arm_load_pic_register (1UL << 3); -+ arm_load_pic_register (1UL << 3, NULL_RTX); - DONE; - }") - -@@ -8666,6 +8667,164 @@ - (set_attr "conds" "clob")] - ) - -+;; Named patterns for stack smashing protection. -+(define_expand "stack_protect_combined_set" -+ [(parallel -+ [(set (match_operand:SI 0 "memory_operand" "") -+ (unspec:SI [(match_operand:SI 1 "guard_operand" "")] -+ UNSPEC_SP_SET)) -+ (clobber (match_scratch:SI 2 "")) -+ (clobber (match_scratch:SI 3 ""))])] -+ "" -+ "" -+) -+ -+;; Use a separate insn from the above expand to be able to have the mem outside -+;; the operand #1 when register allocation comes. This is needed to avoid LRA -+;; try to reload the guard since we need to control how PIC access is done in -+;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling -+;; legitimize_pic_address ()). -+(define_insn_and_split "*stack_protect_combined_set_insn" -+ [(set (match_operand:SI 0 "memory_operand" "=m,m") -+ (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))] -+ UNSPEC_SP_SET)) -+ (clobber (match_scratch:SI 2 "=&l,&r")) -+ (clobber (match_scratch:SI 3 "=&l,&r"))] -+ "" -+ "#" -+ "reload_completed" -+ [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))] -+ UNSPEC_SP_SET)) -+ (clobber (match_dup 2))])] -+ " -+{ -+ if (flag_pic) -+ { -+ /* Forces recomputing of GOT base now. */ -+ legitimize_pic_address (operands[1], SImode, operands[2], operands[3], -+ true /*compute_now*/); -+ } -+ else -+ { -+ if (address_operand (operands[1], SImode)) -+ operands[2] = operands[1]; -+ else -+ { -+ rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0); -+ emit_move_insn (operands[2], mem); -+ } -+ } -+}" -+ [(set_attr "arch" "t1,32")] -+) -+ -+(define_insn "*stack_protect_set_insn" -+ [(set (match_operand:SI 0 "memory_operand" "=m,m") -+ (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))] -+ UNSPEC_SP_SET)) -+ (clobber (match_dup 1))] -+ "" -+ "@ -+ ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0 -+ ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0" -+ [(set_attr "length" "8,12") -+ (set_attr "conds" "clob,nocond") -+ (set_attr "type" "multiple") -+ (set_attr "arch" "t1,32")] -+) -+ -+(define_expand "stack_protect_combined_test" -+ [(parallel -+ [(set (pc) -+ (if_then_else -+ (eq (match_operand:SI 0 "memory_operand" "") -+ (unspec:SI [(match_operand:SI 1 "guard_operand" "")] -+ UNSPEC_SP_TEST)) -+ (label_ref (match_operand 2)) -+ (pc))) -+ (clobber (match_scratch:SI 3 "")) -+ (clobber (match_scratch:SI 4 "")) -+ (clobber (reg:CC CC_REGNUM))])] -+ "" -+ "" -+) -+ -+;; Use a separate insn from the above expand to be able to have the mem outside -+;; the operand #1 when register allocation comes. This is needed to avoid LRA -+;; try to reload the guard since we need to control how PIC access is done in -+;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling -+;; legitimize_pic_address ()). -+(define_insn_and_split "*stack_protect_combined_test_insn" -+ [(set (pc) -+ (if_then_else -+ (eq (match_operand:SI 0 "memory_operand" "m,m") -+ (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))] -+ UNSPEC_SP_TEST)) -+ (label_ref (match_operand 2)) -+ (pc))) -+ (clobber (match_scratch:SI 3 "=&l,&r")) -+ (clobber (match_scratch:SI 4 "=&l,&r")) -+ (clobber (reg:CC CC_REGNUM))] -+ "" -+ "#" -+ "reload_completed" -+ [(const_int 0)] -+{ -+ rtx eq; -+ -+ if (flag_pic) -+ { -+ /* Forces recomputing of GOT base now. */ -+ legitimize_pic_address (operands[1], SImode, operands[3], operands[4], -+ true /*compute_now*/); -+ } -+ else -+ { -+ if (address_operand (operands[1], SImode)) -+ operands[3] = operands[1]; -+ else -+ { -+ rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0); -+ emit_move_insn (operands[3], mem); -+ } -+ } -+ if (TARGET_32BIT) -+ { -+ emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0], -+ operands[3])); -+ rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM); -+ eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx); -+ emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg)); -+ } -+ else -+ { -+ emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0], -+ operands[3])); -+ eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx); -+ emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx, -+ operands[2])); -+ } -+ DONE; -+} -+ [(set_attr "arch" "t1,32")] -+) -+ -+(define_insn "arm_stack_protect_test_insn" -+ [(set (reg:CC_Z CC_REGNUM) -+ (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m") -+ (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))] -+ UNSPEC_SP_TEST) -+ (const_int 0))) -+ (clobber (match_operand:SI 0 "register_operand" "=&l,&r")) -+ (clobber (match_dup 2))] -+ "TARGET_32BIT" -+ "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0" -+ [(set_attr "length" "8,12") -+ (set_attr "conds" "set") -+ (set_attr "type" "multiple") -+ (set_attr "arch" "t,32")] -+) -+ - (define_expand "casesi" - [(match_operand:SI 0 "s_register_operand" "") ; index to jump on - (match_operand:SI 1 "const_int_operand" "") ; lower bound -diff -urpN a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h ---- a/gcc/config/arm/arm-protos.h 2019-05-30 16:58:45.358508769 +0800 -+++ b/gcc/config/arm/arm-protos.h 2019-05-30 11:52:58.491157149 +0800 -@@ -28,7 +28,7 @@ extern enum unwind_info_type arm_except_ - extern int use_return_insn (int, rtx); - extern bool use_simple_return_p (void); - extern enum reg_class arm_regno_class (int); --extern void arm_load_pic_register (unsigned long); -+extern void arm_load_pic_register (unsigned long, rtx); - extern int arm_volatile_func (void); - extern void arm_expand_prologue (void); - extern void arm_expand_epilogue (bool); -@@ -69,7 +69,7 @@ extern int const_ok_for_dimode_op (HOST_ - extern int arm_split_constant (RTX_CODE, machine_mode, rtx, - HOST_WIDE_INT, rtx, rtx, int); - extern int legitimate_pic_operand_p (rtx); --extern rtx legitimize_pic_address (rtx, machine_mode, rtx); -+extern rtx legitimize_pic_address (rtx, machine_mode, rtx, rtx, bool); - extern rtx legitimize_tls_address (rtx, rtx); - extern bool arm_legitimate_address_p (machine_mode, rtx, bool); - extern int arm_legitimate_address_outer_p (machine_mode, rtx, RTX_CODE, int); -diff -urpN a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md ---- a/gcc/config/arm/predicates.md 2019-05-30 16:58:45.358508769 +0800 -+++ b/gcc/config/arm/predicates.md 2019-05-30 11:52:58.491157149 +0800 -@@ -31,6 +31,23 @@ - || REGNO_REG_CLASS (REGNO (op)) != NO_REGS)); - }) - -+; Predicate for stack protector guard's address in -+; stack_protect_combined_set_insn and stack_protect_combined_test_insn patterns -+(define_predicate "guard_addr_operand" -+ (match_test "true") -+{ -+ return (CONSTANT_ADDRESS_P (op) -+ || !targetm.cannot_force_const_mem (mode, op)); -+}) -+ -+; Predicate for stack protector guard in stack_protect_combined_set and -+; stack_protect_combined_test patterns -+(define_predicate "guard_operand" -+ (match_code "mem") -+{ -+ return guard_addr_operand (XEXP (op, 0), mode); -+}) -+ - (define_predicate "imm_for_neon_inv_logic_operand" - (match_code "const_vector") - { -diff -urpN a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md ---- a/gcc/config/arm/thumb1.md 2019-05-30 16:58:45.358508769 +0800 -+++ b/gcc/config/arm/thumb1.md 2019-05-30 11:52:58.491157149 +0800 -@@ -1964,4 +1964,17 @@ - }" - [(set_attr "type" "mov_reg")] - ) -+ -+(define_insn "thumb1_stack_protect_test_insn" -+ [(set (match_operand:SI 0 "register_operand" "=&l") -+ (unspec:SI [(match_operand:SI 1 "memory_operand" "m") -+ (mem:SI (match_operand:SI 2 "register_operand" "+l"))] -+ UNSPEC_SP_TEST)) -+ (clobber (match_dup 2))] -+ "TARGET_THUMB1" -+ "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0" -+ [(set_attr "length" "8") -+ (set_attr "conds" "set") -+ (set_attr "type" "multiple")] -+) - -diff -urpN a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md ---- a/gcc/config/arm/unspecs.md 2019-05-30 16:58:45.358508769 +0800 -+++ b/gcc/config/arm/unspecs.md 2019-05-30 11:52:58.491157149 +0800 -@@ -86,6 +86,9 @@ - UNSPEC_PROBE_STACK ; Probe stack memory reference - UNSPEC_NONSECURE_MEM ; Represent non-secure memory in ARMv8-M with - ; security extension -+ UNSPEC_SP_SET ; Represent the setting of stack protector's canary -+ UNSPEC_SP_TEST ; Represent the testing of stack protector's canary -+ ; against the guard. - ]) - - (define_c_enum "unspec" [ -diff -urpN a/gcc/doc/md.texi b/gcc/doc/md.texi ---- a/gcc/doc/md.texi 2019-05-30 16:58:45.362508769 +0800 -+++ b/gcc/doc/md.texi 2019-05-30 11:52:58.491157149 +0800 -@@ -6955,22 +6955,61 @@ builtins. - The get/set patterns have a single output/input operand respectively, - with @var{mode} intended to be @code{Pmode}. - -+@cindex @code{stack_protect_combined_set} instruction pattern -+@item @samp{stack_protect_combined_set} -+This pattern, if defined, moves a @code{ptr_mode} value from an address -+whose declaration RTX is given in operand 1 to the memory in operand 0 -+without leaving the value in a register afterward. If several -+instructions are needed by the target to perform the operation (eg. to -+load the address from a GOT entry then load the @code{ptr_mode} value -+and finally store it), it is the backend's responsibility to ensure no -+intermediate result gets spilled. This is to avoid leaking the value -+some place that an attacker might use to rewrite the stack guard slot -+after having clobbered it. -+ -+If this pattern is not defined, then the address declaration is -+expanded first in the standard way and a @code{stack_protect_set} -+pattern is then generated to move the value from that address to the -+address in operand 0. -+ - @cindex @code{stack_protect_set} instruction pattern - @item @samp{stack_protect_set} --This pattern, if defined, moves a @code{ptr_mode} value from the memory --in operand 1 to the memory in operand 0 without leaving the value in --a register afterward. This is to avoid leaking the value some place --that an attacker might use to rewrite the stack guard slot after --having clobbered it. -+This pattern, if defined, moves a @code{ptr_mode} value from the valid -+memory location in operand 1 to the memory in operand 0 without leaving -+the value in a register afterward. This is to avoid leaking the value -+some place that an attacker might use to rewrite the stack guard slot -+after having clobbered it. -+ -+Note: on targets where the addressing modes do not allow to load -+directly from stack guard address, the address is expanded in a standard -+way first which could cause some spills. - - If this pattern is not defined, then a plain move pattern is generated. - -+@cindex @code{stack_protect_combined_test} instruction pattern -+@item @samp{stack_protect_combined_test} -+This pattern, if defined, compares a @code{ptr_mode} value from an -+address whose declaration RTX is given in operand 1 with the memory in -+operand 0 without leaving the value in a register afterward and -+branches to operand 2 if the values were equal. If several -+instructions are needed by the target to perform the operation (eg. to -+load the address from a GOT entry then load the @code{ptr_mode} value -+and finally store it), it is the backend's responsibility to ensure no -+intermediate result gets spilled. This is to avoid leaking the value -+some place that an attacker might use to rewrite the stack guard slot -+after having clobbered it. -+ -+If this pattern is not defined, then the address declaration is -+expanded first in the standard way and a @code{stack_protect_test} -+pattern is then generated to compare the value from that address to the -+value at the memory in operand 0. -+ - @cindex @code{stack_protect_test} instruction pattern - @item @samp{stack_protect_test} - This pattern, if defined, compares a @code{ptr_mode} value from the --memory in operand 1 with the memory in operand 0 without leaving the --value in a register afterward and branches to operand 2 if the values --were equal. -+valid memory location in operand 1 with the memory in operand 0 without -+leaving the value in a register afterward and branches to operand 2 if -+the values were equal. - - If this pattern is not defined, then a plain compare pattern and - conditional branch pattern is used. -diff -urpN a/gcc/function.c b/gcc/function.c ---- a/gcc/function.c 2019-05-30 16:58:45.362508769 +0800 -+++ b/gcc/function.c 2019-05-30 11:53:14.071156599 +0800 -@@ -5065,18 +5065,34 @@ stack_protect_epilogue (void) - tree guard_decl = targetm.stack_protect_guard (); - rtx_code_label *label = gen_label_rtx (); - rtx x, y; -- rtx_insn *seq; -+ rtx_insn *seq = NULL; - - x = expand_normal (crtl->stack_protect_guard); -- if (guard_decl) -- y = expand_normal (guard_decl); -+ -+ if (targetm.have_stack_protect_combined_test () && guard_decl) -+ { -+ gcc_assert (DECL_P (guard_decl)); -+ y = DECL_RTL (guard_decl); -+ /* Allow the target to compute address of Y and compare it with X without -+ leaking Y into a register. This combined address + compare pattern -+ allows the target to prevent spilling of any intermediate results by -+ splitting it after register allocator. */ -+ seq = targetm.gen_stack_protect_combined_test (x, y, label); -+ } - else -- y = const0_rtx; -+ { -+ if (guard_decl) -+ y = expand_normal (guard_decl); -+ else -+ y = const0_rtx; -+ -+ /* Allow the target to compare Y with X without leaking either into -+ a register. */ -+ if (targetm.have_stack_protect_test ()) -+ seq = targetm.gen_stack_protect_test (x, y, label); -+ } - -- /* Allow the target to compare Y with X without leaking either into -- a register. */ -- if (targetm.have_stack_protect_test () -- && ((seq = targetm.gen_stack_protect_test (x, y, label)) != NULL_RTX)) -+ if (seq) - emit_insn (seq); - else - emit_cmp_and_jump_insns (x, y, EQ, NULL_RTX, ptr_mode, 1, label); -diff -urpN a/gcc/genpreds.c b/gcc/genpreds.c ---- a/gcc/genpreds.c 2019-05-30 16:58:45.362508769 +0800 -+++ b/gcc/genpreds.c 2019-05-30 11:53:14.163156595 +0800 -@@ -1581,7 +1581,8 @@ write_insn_preds_c (void) - #include \"reload.h\"\n\ - #include \"regs.h\"\n\ - #include \"emit-rtl.h\"\n\ --#include \"tm-constrs.h\"\n"); -+#include \"tm-constrs.h\"\n\ -+#include \"target.h\"\n"); - - FOR_ALL_PREDICATES (p) - write_one_predicate_function (p); -diff -urpN a/gcc/target-insns.def b/gcc/target-insns.def ---- a/gcc/target-insns.def 2019-05-30 16:58:45.362508769 +0800 -+++ b/gcc/target-insns.def 2019-05-30 11:52:58.495157149 +0800 -@@ -96,7 +96,9 @@ DEF_TARGET_INSN (sibcall_value, (rtx x0, - DEF_TARGET_INSN (simple_return, (void)) - DEF_TARGET_INSN (split_stack_prologue, (void)) - DEF_TARGET_INSN (split_stack_space_check, (rtx x0, rtx x1)) -+DEF_TARGET_INSN (stack_protect_combined_set, (rtx x0, rtx x1)) - DEF_TARGET_INSN (stack_protect_set, (rtx x0, rtx x1)) -+DEF_TARGET_INSN (stack_protect_combined_test, (rtx x0, rtx x1, rtx x2)) - DEF_TARGET_INSN (stack_protect_test, (rtx x0, rtx x1, rtx x2)) - DEF_TARGET_INSN (store_multiple, (rtx x0, rtx x1, rtx x2)) - DEF_TARGET_INSN (tablejump, (rtx x0, rtx x1)) diff --git a/CVE-2019-15847.patch b/CVE-2019-15847.patch deleted file mode 100644 index 2bf0b097b75edb6e85616931dcbea37d081622a9..0000000000000000000000000000000000000000 --- a/CVE-2019-15847.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff -urpN a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md ---- a/gcc/config/rs6000/altivec.md 2018-01-15 01:47:30.483964000 +0800 -+++ b/gcc/config/rs6000/altivec.md 2019-09-09 00:01:25.770835633 +0800 -@@ -74,9 +74,6 @@ - UNSPEC_VUNPACK_LO_SIGN_DIRECT - UNSPEC_VUPKHPX - UNSPEC_VUPKLPX -- UNSPEC_DARN -- UNSPEC_DARN_32 -- UNSPEC_DARN_RAW - UNSPEC_DST - UNSPEC_DSTT - UNSPEC_DSTST -@@ -3770,21 +3767,21 @@ - - (define_insn "darn_32" - [(set (match_operand:SI 0 "register_operand" "=r") -- (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] -+ (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))] - "TARGET_P9_MISC" - "darn %0,0" - [(set_attr "type" "integer")]) - - (define_insn "darn_raw" - [(set (match_operand:DI 0 "register_operand" "=r") -- (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] -+ (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))] - "TARGET_P9_MISC && TARGET_64BIT" - "darn %0,2" - [(set_attr "type" "integer")]) - - (define_insn "darn" - [(set (match_operand:DI 0 "register_operand" "=r") -- (unspec:DI [(const_int 0)] UNSPEC_DARN))] -+ (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))] - "TARGET_P9_MISC && TARGET_64BIT" - "darn %0,1" - [(set_attr "type" "integer")]) -diff -urpN a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md ---- a/gcc/config/rs6000/rs6000.md 2018-01-21 21:32:58.843504000 +0800 -+++ b/gcc/config/rs6000/rs6000.md 2019-09-08 23:53:13.122859153 +0800 -@@ -163,6 +163,9 @@ - UNSPECV_EH_RR ; eh_reg_restore - UNSPECV_ISYNC ; isync instruction - UNSPECV_MFTB ; move from time base -+ UNSPECV_DARN ; darn 1 (deliver a random number) -+ UNSPECV_DARN_32 ; darn 2 -+ UNSPECV_DARN_RAW ; darn 0 - UNSPECV_NLGR ; non-local goto receiver - UNSPECV_MFFS ; Move from FPSCR - UNSPECV_MTFSF ; Move to FPSCR Fields diff --git a/aarch64-fix-tls-negative-offset.patch b/aarch64-fix-tls-negative-offset.patch deleted file mode 100644 index 3ca3c8fe872f4d812e4268aeb289358e05e51d76..0000000000000000000000000000000000000000 --- a/aarch64-fix-tls-negative-offset.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -urpN a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c ---- a/gcc/config/aarch64/aarch64.c 2018-10-09 11:49:19.000000000 +0800 -+++ b/gcc/config/aarch64/aarch64.c 2018-10-09 13:42:15.000000000 +0800 -@@ -1619,7 +1619,7 @@ aarch64_load_symref_appropriately (rtx d - case SYMBOL_SMALL_TLSDESC: - { - machine_mode mode = GET_MODE (dest); -- rtx x0 = gen_rtx_REG (mode, R0_REGNUM); -+ rtx x0 = gen_rtx_REG (ptr_mode, R0_REGNUM); - rtx tp; - - gcc_assert (mode == Pmode || mode == ptr_mode); -@@ -1635,6 +1635,11 @@ aarch64_load_symref_appropriately (rtx d - if (mode != Pmode) - tp = gen_lowpart (mode, tp); - -+ if (mode != ptr_mode) -+ { -+ x0 = force_reg (mode, gen_rtx_SIGN_EXTEND (mode, x0)); -+ } -+ - emit_insn (gen_rtx_SET (dest, gen_rtx_PLUS (mode, tp, x0))); - set_unique_reg_note (get_last_insn (), REG_EQUIV, imm); - return; diff --git a/aarch64-ilp32-call-addr-dimode.patch b/aarch64-ilp32-call-addr-dimode.patch deleted file mode 100644 index 0a04debb803cf81faeb6867016e635083db10fb4..0000000000000000000000000000000000000000 --- a/aarch64-ilp32-call-addr-dimode.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -urpN a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md ---- a/gcc/config/aarch64/aarch64.md 2018-10-09 11:30:50.000000000 +0800 -+++ b/gcc/config/aarch64/aarch64.md 2018-10-09 11:52:54.000000000 +0800 -@@ -857,6 +857,13 @@ - : !REG_P (callee)) - XEXP (operands[0], 0) = force_reg (Pmode, callee); - -+ if (TARGET_ILP32 -+ && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF -+ && GET_MODE (XEXP (operands[0], 0)) == SImode) -+ XEXP (operands[0], 0) = convert_memory_address (DImode, -+ XEXP (operands[0], 0)); -+ -+ - if (operands[2] == NULL_RTX) - operands[2] = const0_rtx; - -@@ -889,6 +896,13 @@ - : !REG_P (callee)) - XEXP (operands[1], 0) = force_reg (Pmode, callee); - -+ if (TARGET_ILP32 -+ && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF -+ && GET_MODE (XEXP (operands[1], 0)) == SImode) -+ XEXP (operands[1], 0) = convert_memory_address (DImode, -+ XEXP (operands[1], 0)); -+ -+ - if (operands[3] == NULL_RTX) - operands[3] = const0_rtx; - diff --git a/add-tsv110-pipeline-scheduling.patch b/add-tsv110-pipeline-scheduling.patch deleted file mode 100644 index 508de27e056b9686971b5f3fdc5e30c968c866e2..0000000000000000000000000000000000000000 --- a/add-tsv110-pipeline-scheduling.patch +++ /dev/null @@ -1,780 +0,0 @@ -diff -urpN a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c ---- a/gcc/config/aarch64/aarch64.c 2019-04-15 14:50:25.866378665 +0800 -+++ b/gcc/config/aarch64/aarch64.c 2019-04-15 14:49:21.986376983 +0800 -@@ -554,6 +554,31 @@ static const struct tune_params generic_ - (AARCH64_EXTRA_TUNE_NONE) /* tune_flags. */ - }; - -+static const struct tune_params tsv110_tunings = -+{ -+ &cortexa57_extra_costs, -+ &generic_addrcost_table, -+ &generic_regmove_cost, -+ &generic_vector_cost, -+ &generic_branch_cost, -+ &generic_approx_modes, -+ 4, /* memmov_cost */ -+ 4, /* issue_rate */ -+ AARCH64_FUSE_NOTHING, /* fusible_ops */ -+ 16, /* function_align. */ -+ 16, /* jump_align. */ -+ 8, /* loop_align. */ -+ 2, /* int_reassoc_width. */ -+ 4, /* fp_reassoc_width. */ -+ 1, /* vec_reassoc_width. */ -+ 2, /* min_div_recip_mul_sf. */ -+ 2, /* min_div_recip_mul_df. */ -+ 0, /* max_case_values. */ -+ 0, /* cache_line_size. */ -+ tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */ -+ (AARCH64_EXTRA_TUNE_NONE) /* tune_flags. */ -+}; -+ - static const struct tune_params cortexa35_tunings = - { - &cortexa53_extra_costs, -diff -urpN a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def ---- a/gcc/config/aarch64/aarch64-cores.def 2017-02-15 08:09:28.845771000 +0800 -+++ b/gcc/config/aarch64/aarch64-cores.def 2019-04-15 14:49:21.986376983 +0800 -@@ -78,6 +78,8 @@ AARCH64_CORE("xgene1", xgene1, x - AARCH64_CORE("thunderx2t99p1", thunderx2t99p1, thunderx2t99, 8_1A, AARCH64_FL_FOR_ARCH8_1 | AARCH64_FL_CRYPTO, thunderx2t99, 0x42, 0x516, -1) - AARCH64_CORE("vulcan", vulcan, thunderx2t99, 8_1A, AARCH64_FL_FOR_ARCH8_1 | AARCH64_FL_CRYPTO, thunderx2t99, 0x42, 0x516, -1) - -+AARCH64_CORE("tsv110", tsv110, tsv110, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, tsv110, 0x48, 0xd01, -1) -+ - /* V8 big.LITTLE implementations. */ - - AARCH64_CORE("cortex-a57.cortex-a53", cortexa57cortexa53, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa57, 0x41, AARCH64_BIG_LITTLE (0xd07, 0xd03), -1) -diff -urpN a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md ---- a/gcc/config/aarch64/aarch64.md 2019-04-15 14:50:25.870378665 +0800 -+++ b/gcc/config/aarch64/aarch64.md 2019-04-15 14:49:21.986376983 +0800 -@@ -226,6 +226,7 @@ - (include "thunderx.md") - (include "../arm/xgene1.md") - (include "thunderx2t99.md") -+(include "tsv110.md") - - ;; ------------------------------------------------------------------- - ;; Jumps and other miscellaneous insns -diff -urpN a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md ---- a/gcc/config/aarch64/aarch64-tune.md 2017-02-15 08:09:28.845771000 +0800 -+++ b/gcc/config/aarch64/aarch64-tune.md 2019-04-15 14:49:21.986376983 +0800 -@@ -1,5 +1,5 @@ - ;; -*- buffer-read-only: t -*- - ;; Generated automatically by gentune.sh from aarch64-cores.def - (define_attr "tune" -- "cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,exynosm1,falkor,qdf24xx,thunderx,thunderxt88p1,thunderxt88,thunderxt81,thunderxt83,thunderx2t99,xgene1,thunderx2t99p1,vulcan,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53" -+ "cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,exynosm1,falkor,qdf24xx,thunderx,thunderxt88p1,thunderxt88,thunderxt81,thunderxt83,thunderx2t99,xgene1,tsv110,thunderx2t99p1,vulcan,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53" - (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) -diff -urpN a/gcc/config/aarch64/tsv110.md b/gcc/config/aarch64/tsv110.md ---- a/gcc/config/aarch64/tsv110.md 1970-01-01 08:00:00.000000000 +0800 -+++ b/gcc/config/aarch64/tsv110.md 2019-04-15 14:55:30.420081420 +0800 -@@ -0,0 +1,708 @@ -+;; tsv110 pipeline description -+;; Copyright (C) 2018 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 -+;; . -+ -+(define_automaton "tsv110") -+ -+(define_attr "tsv110_neon_type" -+ "neon_arith_acc, neon_arith_acc_q, -+ neon_arith_basic, neon_arith_complex, -+ neon_reduc_add_acc, neon_multiply, neon_multiply_q, -+ neon_multiply_long, neon_mla, neon_mla_q, neon_mla_long, -+ neon_sat_mla_long, neon_shift_acc, neon_shift_imm_basic, -+ neon_shift_imm_complex, -+ neon_shift_reg_basic, neon_shift_reg_basic_q, neon_shift_reg_complex, -+ neon_shift_reg_complex_q, neon_fp_negabs, neon_fp_arith, -+ neon_fp_arith_q, neon_fp_reductions_q, neon_fp_cvt_int, -+ neon_fp_cvt_int_q, neon_fp_cvt16, neon_fp_minmax, neon_fp_mul, -+ neon_fp_mul_q, neon_fp_mla, neon_fp_mla_q, neon_fp_recpe_rsqrte, -+ neon_fp_recpe_rsqrte_q, neon_fp_recps_rsqrts, neon_fp_recps_rsqrts_q, -+ neon_bitops, neon_bitops_q, neon_from_gp, -+ neon_from_gp_q, neon_move, neon_tbl3_tbl4, neon_zip_q, neon_to_gp, -+ neon_load_a, neon_load_b, neon_load_c, neon_load_d, neon_load_e, -+ neon_load_f, neon_store_a, neon_store_b, neon_store_complex, -+ unknown" -+ (cond [ -+ (eq_attr "type" "neon_arith_acc, neon_reduc_add_acc,\ -+ neon_reduc_add_acc_q") -+ (const_string "neon_arith_acc") -+ (eq_attr "type" "neon_arith_acc_q") -+ (const_string "neon_arith_acc_q") -+ (eq_attr "type" "neon_abs,neon_abs_q,neon_add, neon_add_q, neon_add_long,\ -+ neon_add_widen, neon_neg, neon_neg_q,\ -+ neon_reduc_add, neon_reduc_add_q,\ -+ neon_reduc_add_long, neon_sub, neon_sub_q,\ -+ neon_sub_long, neon_sub_widen, neon_logic,\ -+ neon_logic_q, neon_tst, neon_tst_q,\ -+ neon_compare, neon_compare_q,\ -+ neon_compare_zero, neon_compare_zero_q,\ -+ neon_minmax, neon_minmax_q, neon_reduc_minmax,\ -+ neon_reduc_minmax_q") -+ (const_string "neon_arith_basic") -+ (eq_attr "type" "neon_add_halve_narrow_q,\ -+ neon_add_halve, neon_add_halve_q,\ -+ neon_sub_halve, neon_sub_halve_q, neon_qabs,\ -+ neon_qabs_q, neon_qadd, neon_qadd_q, neon_qneg,\ -+ neon_qneg_q, neon_qsub, neon_qsub_q,\ -+ neon_sub_halve_narrow_q") -+ (const_string "neon_arith_complex") -+ -+ (eq_attr "type" "neon_mul_b, neon_mul_h, neon_mul_s,\ -+ neon_mul_h_scalar, neon_mul_s_scalar,\ -+ neon_sat_mul_b, neon_sat_mul_h,\ -+ neon_sat_mul_s, neon_sat_mul_h_scalar,\ -+ neon_sat_mul_s_scalar,\ -+ neon_mul_b_long, neon_mul_h_long,\ -+ neon_mul_s_long,\ -+ neon_mul_h_scalar_long, neon_mul_s_scalar_long,\ -+ neon_sat_mul_b_long, neon_sat_mul_h_long,\ -+ neon_sat_mul_s_long, neon_sat_mul_h_scalar_long,\ -+ neon_sat_mul_s_scalar_long,\ -+ neon_mla_b, neon_mla_h, neon_mla_s,\ -+ neon_mla_h_scalar, neon_mla_s_scalar,\ -+ neon_mla_b_long, neon_mla_h_long,\ -+ neon_mla_s_long,\ -+ neon_mla_h_scalar_long, neon_mla_s_scalar_long,\ -+ neon_sat_mla_b_long, neon_sat_mla_h_long,\ -+ neon_sat_mla_s_long, neon_sat_mla_h_scalar_long,\ -+ neon_sat_mla_s_scalar_long") -+ (const_string "neon_multiply") -+ (eq_attr "type" "neon_mul_b_q, neon_mul_h_q, neon_mul_s_q,\ -+ neon_mul_h_scalar_q, neon_mul_s_scalar_q,\ -+ neon_sat_mul_b_q, neon_sat_mul_h_q,\ -+ neon_sat_mul_s_q, neon_sat_mul_h_scalar_q,\ -+ neon_sat_mul_s_scalar_q,\ -+ neon_mla_b_q, neon_mla_h_q, neon_mla_s_q,\ -+ neon_mla_h_scalar_q, neon_mla_s_scalar_q") -+ (const_string "neon_multiply_q") -+ -+ (eq_attr "type" "neon_shift_acc, neon_shift_acc_q") -+ (const_string "neon_shift_acc") -+ (eq_attr "type" "neon_shift_imm, neon_shift_imm_q,\ -+ neon_shift_imm_narrow_q, neon_shift_imm_long") -+ (const_string "neon_shift_imm_basic") -+ (eq_attr "type" "neon_sat_shift_imm, neon_sat_shift_imm_q,\ -+ neon_sat_shift_imm_narrow_q") -+ (const_string "neon_shift_imm_complex") -+ (eq_attr "type" "neon_shift_reg") -+ (const_string "neon_shift_reg_basic") -+ (eq_attr "type" "neon_shift_reg_q") -+ (const_string "neon_shift_reg_basic_q") -+ (eq_attr "type" "neon_sat_shift_reg") -+ (const_string "neon_shift_reg_complex") -+ (eq_attr "type" "neon_sat_shift_reg_q") -+ (const_string "neon_shift_reg_complex_q") -+ -+ (eq_attr "type" "neon_fp_neg_s, neon_fp_neg_s_q,\ -+ neon_fp_abs_s, neon_fp_abs_s_q,\ -+ neon_fp_neg_d, neon_fp_neg_d_q,\ -+ neon_fp_abs_d, neon_fp_abs_d_q,\ -+ neon_fp_minmax_s,neon_fp_minmax_d,\ -+ neon_fp_reduc_minmax_s,neon_fp_reduc_minmax_d") -+ (const_string "neon_fp_negabs") -+ (eq_attr "type" "neon_fp_addsub_s, neon_fp_abd_s,\ -+ neon_fp_reduc_add_s, neon_fp_compare_s,\ -+ neon_fp_round_s,\ -+ neon_fp_addsub_d, neon_fp_abd_d,\ -+ neon_fp_reduc_add_d, neon_fp_compare_d,\ -+ neon_fp_round_d") -+ (const_string "neon_fp_arith") -+ (eq_attr "type" "neon_fp_addsub_s_q, neon_fp_abd_s_q,\ -+ neon_fp_reduc_add_s_q, neon_fp_compare_s_q,\ -+ neon_fp_minmax_s_q, neon_fp_round_s_q,\ -+ neon_fp_addsub_d_q, neon_fp_abd_d_q,\ -+ neon_fp_reduc_add_d_q, neon_fp_compare_d_q,\ -+ neon_fp_minmax_d_q, neon_fp_round_d_q") -+ (const_string "neon_fp_arith_q") -+ (eq_attr "type" "neon_fp_reduc_minmax_s_q,\ -+ neon_fp_reduc_minmax_d_q,\ -+ neon_fp_reduc_add_s_q, neon_fp_reduc_add_d_q") -+ (const_string "neon_fp_reductions_q") -+ (eq_attr "type" "neon_fp_to_int_s, neon_int_to_fp_s,\ -+ neon_fp_to_int_d, neon_int_to_fp_d") -+ (const_string "neon_fp_cvt_int") -+ (eq_attr "type" "neon_fp_to_int_s_q, neon_int_to_fp_s_q,\ -+ neon_fp_to_int_d_q, neon_int_to_fp_d_q") -+ (const_string "neon_fp_cvt_int_q") -+ (eq_attr "type" "neon_fp_cvt_narrow_s_q, neon_fp_cvt_widen_h") -+ (const_string "neon_fp_cvt16") -+ (eq_attr "type" "neon_fp_mul_s, neon_fp_mul_s_scalar,\ -+ neon_fp_mul_d") -+ (const_string "neon_fp_mul") -+ (eq_attr "type" "neon_fp_mul_s_q, neon_fp_mul_s_scalar_q,\ -+ neon_fp_mul_d_q, neon_fp_mul_d_scalar_q") -+ (const_string "neon_fp_mul_q") -+ (eq_attr "type" "neon_fp_mla_s, neon_fp_mla_s_scalar,\ -+ neon_fp_mla_d") -+ (const_string "neon_fp_mla") -+ (eq_attr "type" "neon_fp_mla_s_q, neon_fp_mla_s_scalar_q, -+ neon_fp_mla_d_q, neon_fp_mla_d_scalar_q") -+ (const_string "neon_fp_mla_q") -+ (eq_attr "type" "neon_fp_recpe_s, neon_fp_rsqrte_s,\ -+ neon_fp_recpx_s,\ -+ neon_fp_recpe_d, neon_fp_rsqrte_d,\ -+ neon_fp_recpx_d") -+ (const_string "neon_fp_recpe_rsqrte") -+ (eq_attr "type" "neon_fp_recpe_s_q, neon_fp_rsqrte_s_q,\ -+ neon_fp_recpx_s_q,\ -+ neon_fp_recpe_d_q, neon_fp_rsqrte_d_q,\ -+ neon_fp_recpx_d_q") -+ (const_string "neon_fp_recpe_rsqrte_q") -+ (eq_attr "type" "neon_fp_recps_s, neon_fp_rsqrts_s,\ -+ neon_fp_recps_d, neon_fp_rsqrts_d") -+ (const_string "neon_fp_recps_rsqrts") -+ (eq_attr "type" "neon_fp_recps_s_q, neon_fp_rsqrts_s_q,\ -+ neon_fp_recps_d_q, neon_fp_rsqrts_d_q") -+ (const_string "neon_fp_recps_rsqrts_q") -+ (eq_attr "type" "neon_bsl, neon_cls, neon_cnt,\ -+ neon_rev, neon_permute, neon_rbit,\ -+ neon_tbl1, neon_tbl2, neon_zip,\ -+ neon_dup, neon_dup_q, neon_ext, neon_ext_q,\ -+ neon_move, neon_move_q, neon_move_narrow_q") -+ (const_string "neon_bitops") -+ (eq_attr "type" "neon_bsl_q, neon_cls_q, neon_cnt_q,\ -+ neon_rev_q, neon_permute_q, neon_rbit_q") -+ (const_string "neon_bitops_q") -+ (eq_attr "type" "neon_from_gp,f_mcr,f_mcrr") -+ (const_string "neon_from_gp") -+ (eq_attr "type" "neon_from_gp_q") -+ (const_string "neon_from_gp_q") -+ -+ (eq_attr "type" "f_loads, f_loadd,\ -+ neon_load1_1reg, neon_load1_1reg_q,\ -+ neon_load1_2reg, neon_load1_2reg_q") -+ (const_string "neon_load_a") -+ (eq_attr "type" "neon_load1_3reg, neon_load1_3reg_q,\ -+ neon_load1_4reg, neon_load1_4reg_q") -+ (const_string "neon_load_b") -+ (eq_attr "type" "neon_load1_one_lane, neon_load1_one_lane_q,\ -+ neon_load1_all_lanes, neon_load1_all_lanes_q,\ -+ neon_load2_2reg, neon_load2_2reg_q,\ -+ neon_load2_all_lanes, neon_load2_all_lanes_q") -+ (const_string "neon_load_c") -+ (eq_attr "type" "neon_load2_4reg, neon_load2_4reg_q,\ -+ neon_load3_3reg, neon_load3_3reg_q,\ -+ neon_load3_one_lane, neon_load3_one_lane_q,\ -+ neon_load4_4reg, neon_load4_4reg_q") -+ (const_string "neon_load_d") -+ (eq_attr "type" "neon_load2_one_lane, neon_load2_one_lane_q,\ -+ neon_load3_all_lanes, neon_load3_all_lanes_q,\ -+ neon_load4_all_lanes, neon_load4_all_lanes_q") -+ (const_string "neon_load_e") -+ (eq_attr "type" "neon_load4_one_lane, neon_load4_one_lane_q") -+ (const_string "neon_load_f") -+ -+ (eq_attr "type" "f_stores, f_stored,\ -+ neon_store1_1reg") -+ (const_string "neon_store_a") -+ (eq_attr "type" "neon_store1_2reg, neon_store1_1reg_q") -+ (const_string "neon_store_b") -+ (eq_attr "type" "neon_store1_3reg, neon_store1_3reg_q,\ -+ neon_store3_3reg, neon_store3_3reg_q,\ -+ neon_store2_4reg, neon_store2_4reg_q,\ -+ neon_store4_4reg, neon_store4_4reg_q,\ -+ neon_store2_2reg, neon_store2_2reg_q,\ -+ neon_store3_one_lane, neon_store3_one_lane_q,\ -+ neon_store4_one_lane, neon_store4_one_lane_q,\ -+ neon_store1_4reg, neon_store1_4reg_q,\ -+ neon_store1_one_lane, neon_store1_one_lane_q,\ -+ neon_store2_one_lane, neon_store2_one_lane_q") -+ (const_string "neon_store_complex")] -+ (const_string "unknown"))) -+ -+;; The tsv110 core is modelled as issues pipeline that has -+;; the following functional units. -+;; 1. Three pipelines for integer operations: ALU1, ALU2, ALU3 -+ -+(define_cpu_unit "tsv110_alu1_issue" "tsv110") -+(define_reservation "tsv110_alu1" "tsv110_alu1_issue") -+ -+(define_cpu_unit "tsv110_alu2_issue" "tsv110") -+(define_reservation "tsv110_alu2" "tsv110_alu2_issue") -+ -+(define_cpu_unit "tsv110_alu3_issue" "tsv110") -+(define_reservation "tsv110_alu3" "tsv110_alu3_issue") -+ -+;; 2. One pipeline for complex integer operations: MDU -+ -+(define_cpu_unit "tsv110_mdu_issue" "tsv110") -+(define_reservation "tsv110_mdu" "tsv110_mdu_issue") -+ -+;; 3. Two asymmetric pipelines for Asimd and FP operations: FSU1, FSU2 -+(define_automaton "tsv110_fsu") -+ -+(define_cpu_unit "tsv110_fsu1_issue" -+ "tsv110_fsu") -+(define_cpu_unit "tsv110_fsu2_issue" -+ "tsv110_fsu") -+ -+(define_reservation "tsv110_fsu1" "tsv110_fsu1_issue") -+(define_reservation "tsv110_fsu2" "tsv110_fsu2_issue") -+ -+;; 4. Two pipeline for branch operations but same with alu2 and alu3: BRU1, BRU2 -+ -+;; 5. Two pipelines for load and store operations: LS1, LS2. -+ -+(define_cpu_unit "tsv110_ls1_issue" "tsv110") -+(define_cpu_unit "tsv110_ls2_issue" "tsv110") -+(define_reservation "tsv110_ls1" "tsv110_ls1_issue") -+(define_reservation "tsv110_ls2" "tsv110_ls2_issue") -+ -+;; Block all issue queues. -+ -+(define_reservation "tsv110_block" "tsv110_fsu1_issue + tsv110_fsu2_issue -+ + tsv110_mdu_issue + tsv110_alu1_issue -+ + tsv110_alu2_issue + tsv110_alu3_issue + tsv110_ls1_issue + tsv110_ls2_issue") -+ -+;; Simple Execution Unit: -+;; -+;; Simple ALU without shift -+(define_insn_reservation "tsv110_alu" 1 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "alu_imm,logic_imm,\ -+ alu_sreg,logic_reg,\ -+ adc_imm,adc_reg,\ -+ adr,bfm,clz,rbit,rev,\ -+ shift_imm,shift_reg,\ -+ mov_imm,mov_reg,\ -+ mvn_imm,mvn_reg,\ -+ mrs,multiple,no_insn")) -+ "tsv110_alu1|tsv110_alu2|tsv110_alu3") -+ -+(define_insn_reservation "tsv110_alus" 1 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "alus_imm,logics_imm,\ -+ alus_sreg,logics_reg,\ -+ adcs_imm,adcs_reg")) -+ "tsv110_alu2|tsv110_alu3") -+ -+;; ALU ops with shift -+(define_insn_reservation "tsv110_alu_shift" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "extend,\ -+ alu_shift_imm,alu_shift_reg,\ -+ crc,logic_shift_imm,logic_shift_reg,\ -+ mov_shift,mvn_shift,\ -+ mov_shift_reg,mvn_shift_reg")) -+ "tsv110_mdu") -+ -+(define_insn_reservation "tsv110_alus_shift" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "alus_shift_imm,alus_shift_reg,\ -+ logics_shift_imm,logics_shift_reg")) -+ "tsv110_alu2|tsv110_alu3") -+ -+;; Multiplies instructions -+(define_insn_reservation "tsv110_mult" 3 -+ (and (eq_attr "tune" "tsv110") -+ (ior (eq_attr "mul32" "yes") -+ (eq_attr "mul64" "yes"))) -+ "tsv110_mdu") -+ -+;; Integer divide -+(define_insn_reservation "tsv110_div" 10 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "udiv,sdiv")) -+ "tsv110_mdu") -+ -+;; Block all issue pipes for a cycle -+(define_insn_reservation "tsv110_block" 1 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "block")) -+ "tsv110_block") -+ -+;; Branch execution Unit -+;; -+;; Branches take two issue slot. -+;; No latency as there is no result -+(define_insn_reservation "tsv110_branch" 0 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "branch")) -+ "tsv110_alu2|tsv110_alu3") -+ -+;; Load-store execution Unit -+;; -+;; Loads of up to two words. -+(define_insn_reservation "tsv110_load1" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "load1,load2")) -+ "tsv110_ls1|tsv110_ls2") -+ -+;; Stores of up to two words. -+(define_insn_reservation "tsv110_store1" 0 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "store1,store2")) -+ "tsv110_ls1|tsv110_ls2") -+ -+;; Advanced SIMD Unit - Integer Arithmetic Instructions. -+ -+(define_insn_reservation "tsv110_neon_abd_aba" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_abd,neon_arith_acc")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_neon_abd_aba_q" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_arith_acc_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_neon_arith_basic" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_arith_basic")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_neon_arith_complex" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_arith_complex")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+;; Integer Multiply Instructions. -+;; D-form -+(define_insn_reservation "tsv110_neon_multiply" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_multiply")) -+ "tsv110_fsu1") -+ -+(define_insn_reservation "tsv110_neon_multiply_dlong" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_mul_d_long")) -+ "tsv110_fsu1") -+ -+;; Q-form -+(define_insn_reservation "tsv110_neon_multiply_q" 8 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_multiply_q")) -+ "tsv110_fsu1") -+ -+;; Integer Shift Instructions. -+ -+(define_insn_reservation -+ "tsv110_neon_shift_acc" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_shift_acc,\ -+ neon_shift_imm_basic,neon_shift_imm_complex,neon_shift_reg_basic,\ -+ neon_shift_reg_complex")) -+ "tsv110_fsu1") -+ -+(define_insn_reservation -+ "tsv110_neon_shift_acc_q" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_shift_reg_basic_q,\ -+ neon_shift_reg_complex_q")) -+ "tsv110_fsu1") -+ -+;; Floating Point Instructions. -+ -+(define_insn_reservation -+ "tsv110_neon_fp_negabs" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_negabs")) -+ "(tsv110_fsu1|tsv110_fsu2)") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_arith" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_arith")) -+ "(tsv110_fsu1|tsv110_fsu2)") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_arith_q" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_arith_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_minmax_q" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_fp_minmax_s_q,neon_fp_minmax_d_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_reductions_q" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_reductions_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_cvt_int" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_cvt_int,neon_fp_cvt_int_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_mul" 5 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_mul")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_mul_q" 5 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_mul_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_mla" 7 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_mla,\ -+ neon_fp_recps_rsqrts")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_recpe_rsqrte" 3 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_recpe_rsqrte")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_mla_q" 7 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_mla_q,\ -+ neon_fp_recps_rsqrts_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_fp_recpe_rsqrte_q" 3 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_fp_recpe_rsqrte_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+;; Miscellaneous Instructions. -+ -+(define_insn_reservation -+ "tsv110_neon_bitops" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_bitops")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_dup" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_from_gp,f_mcr")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_mov" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "f_mcrr")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_bitops_q" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_bitops_q")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_from_gp_q" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_from_gp_q")) -+ "(tsv110_alu1+tsv110_fsu1)|(tsv110_alu1+tsv110_fsu2)") -+ -+(define_insn_reservation -+ "tsv110_neon_to_gp" 3 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_to_gp,neon_to_gp_q")) -+ "tsv110_fsu1") -+ -+;; Load Instructions. -+ -+(define_insn_reservation -+ "tsv110_neon_ld1_lane" 8 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load1_one_lane,neon_load1_one_lane_q,\ -+ neon_load1_all_lanes,neon_load1_all_lanes_q")) -+ "(tsv110_ls1 + tsv110_fsu1)|(tsv110_ls1 + tsv110_fsu2)|(tsv110_ls2 + tsv110_fsu1)|(tsv110_ls2 + tsv110_fsu2)") -+ -+(define_insn_reservation -+ "tsv110_neon_ld1_reg1" 6 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "f_loads,f_loadd,neon_load1_1reg,neon_load1_1reg_q")) -+ "tsv110_ls1|tsv110_ls2") -+ -+(define_insn_reservation -+ "tsv110_neon_ld1_reg2" 6 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load1_2reg,neon_load1_2reg_q")) -+ "tsv110_ls1|tsv110_ls2") -+ -+(define_insn_reservation -+ "tsv110_neon_ld1_reg3" 7 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load1_3reg,neon_load1_3reg_q")) -+ "tsv110_ls1|tsv110_ls2") -+ -+(define_insn_reservation -+ "tsv110_neon_ld1_reg4" 7 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load1_4reg,neon_load1_4reg_q")) -+ "tsv110_ls1|tsv110_ls2") -+ -+(define_insn_reservation -+ "tsv110_neon_ld2" 8 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load1_2reg,neon_load1_2reg_q,\ -+ neon_load2_2reg,neon_load2_2reg_q,neon_load2_all_lanes,\ -+ neon_load2_all_lanes_q,neon_load2_one_lane,neon_load2_one_lane_q")) -+ "(tsv110_ls1 + tsv110_fsu1)|(tsv110_ls1 + tsv110_fsu2)|(tsv110_ls2 + tsv110_fsu1)|(tsv110_ls2 + tsv110_fsu2)") -+ -+(define_insn_reservation -+ "tsv110_neon_ld3" 9 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load3_3reg,neon_load3_3reg_q,\ -+ neon_load3_one_lane,neon_load3_one_lane_q,\ -+ neon_load3_all_lanes,neon_load3_all_lanes_q")) -+ "(tsv110_ls1 + tsv110_fsu1)|(tsv110_ls1 + tsv110_fsu2)|(tsv110_ls2 + tsv110_fsu1)|(tsv110_ls2 + tsv110_fsu2)") -+ -+(define_insn_reservation -+ "tsv110_neon_ld4_lane" 9 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load4_all_lanes,neon_load4_all_lanes_q,\ -+ neon_load4_one_lane,neon_load4_one_lane_q")) -+ "(tsv110_ls1 + tsv110_fsu1)|(tsv110_ls1 + tsv110_fsu2)|(tsv110_ls2 + tsv110_fsu1)|(tsv110_ls2 + tsv110_fsu2)") -+ -+(define_insn_reservation -+ "tsv110_neon_ld4_reg" 11 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "neon_load4_all_lanes,neon_load4_all_lanes_q,\ -+ neon_load4_one_lane,neon_load4_one_lane_q")) -+ "(tsv110_ls1 + tsv110_fsu1)|(tsv110_ls1 + tsv110_fsu2)|(tsv110_ls2 + tsv110_fsu1)|(tsv110_ls2 + tsv110_fsu2)") -+ -+;; Store Instructions. -+ -+(define_insn_reservation -+ "tsv110_neon_store_a" 0 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_store_a")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation -+ "tsv110_neon_store_b" 0 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_store_b")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+;; These block issue for a number of cycles proportional to the number -+;; of 64-bit chunks they will store, we don't attempt to model that -+;; precisely, treat them as blocking execution for two cycles when -+;; issued. -+(define_insn_reservation -+ "tsv110_neon_store_complex" 0 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "tsv110_neon_type" "neon_store_complex")) -+ "tsv110_block*2") -+ -+;; Floating-Point Operations. -+ -+(define_insn_reservation "tsv110_fp_const" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "fconsts,fconstd,fmov")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_fp_add_sub" 5 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "fadds,faddd,fmuls,fmuld")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_fp_mac" 7 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "fmacs,ffmas,fmacd,ffmad")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_fp_cvt" 3 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "f_cvt")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_fp_cvtf2i" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "f_cvtf2i")) -+ "tsv110_fsu1") -+ -+(define_insn_reservation "tsv110_fp_cvti2f" 5 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "f_cvti2f")) -+ "(tsv110_alu1+tsv110_fsu1)|(tsv110_alu1+tsv110_fsu2)") -+ -+(define_insn_reservation "tsv110_fp_cmp" 4 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "fcmps,fcmpd")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_fp_arith" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "ffariths,ffarithd")) -+ "tsv110_fsu1|tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_fp_divs" 12 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "fdivs,neon_fp_div_s,fdivd,neon_fp_div_d,\ -+ neon_fp_div_s_q,neon_fp_div_d_q")) -+ "tsv110_fsu1") -+ -+(define_insn_reservation "tsv110_fp_sqrts" 24 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "fsqrts,neon_fp_sqrt_s,fsqrtd,neon_fp_sqrt_d,\ -+ neon_fp_sqrt_s_q,neon_fp_sqrt_d_q")) -+ "tsv110_fsu2") -+ -+(define_insn_reservation "tsv110_crypto_aes" 3 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "crypto_aese,crypto_aesmc")) -+ "tsv110_fsu1") -+ -+(define_insn_reservation "tsv110_crypto_sha1_fast" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "crypto_sha1_fast,crypto_sha1_xor")) -+ "(tsv110_fsu1|tsv110_fsu2)") -+ -+(define_insn_reservation "tsv110_crypto_sha256_fast" 2 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "crypto_sha256_fast")) -+ "tsv110_fsu1") -+ -+(define_insn_reservation "tsv110_crypto_complex" 5 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "crypto_sha1_slow,crypto_sha256_slow")) -+ "tsv110_fsu1") -+ -+;; We lie with calls. They take up all issue slots, but are otherwise -+;; not harmful. -+(define_insn_reservation "tsv110_call" 1 -+ (and (eq_attr "tune" "tsv110") -+ (eq_attr "type" "call")) -+ "tsv110_alu1_issue+tsv110_alu2_issue+tsv110_alu3_issue+tsv110_fsu1_issue+tsv110_fsu2_issue\ -+ +tsv110_mdu_issue+tsv110_ls1_issue+tsv110_ls2_issue" -+) -+ -+;; Simple execution unit bypasses -+(define_bypass 1 "tsv110_alu" -+ "tsv110_alu,tsv110_alu_shift") -+(define_bypass 2 "tsv110_alu_shift" -+ "tsv110_alu,tsv110_alu_shift") -+ -+;; An MLA or a MUL can feed a dependent MLA. -+(define_bypass 3 "tsv110_neon_*mla*,tsv110_neon_*mul*" -+ "tsv110_neon_*mla*") -+ -+;; We don't need to care about control hazards, either the branch is -+;; predicted in which case we pay no penalty, or the branch is -+;; mispredicted in which case instruction scheduling will be unlikely to -+;; help. -+(define_bypass 1 "tsv110_*" -+ "tsv110_call,tsv110_branch") diff --git a/address-calculation-optimization-within-loop.patch b/address-calculation-optimization-within-loop.patch new file mode 100644 index 0000000000000000000000000000000000000000..6a7e58cdaa6c0e43022f8e51a0d11b8a9119128b --- /dev/null +++ b/address-calculation-optimization-within-loop.patch @@ -0,0 +1,57 @@ +diff -Nurp a/gcc/testsuite/gcc.dg/pr94269.c b/gcc/testsuite/gcc.dg/pr94269.c +--- a/gcc/testsuite/gcc.dg/pr94269.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/gcc/testsuite/gcc.dg/pr94269.c 2020-04-17 17:04:50.608000000 +0800 +@@ -0,0 +1,26 @@ ++/* { dg-do compile { target aarch64*-*-* } } */ ++/* { dg-options "-O2 -ftree-loop-vectorize -funsafe-math-optimizations -march=armv8.2-a+sve -msve-vector-bits=256" } */ ++ ++float ++foo(long n, float *x, int inc_x, ++ float *y, int inc_y) ++{ ++ float dot = 0.0; ++ int ix = 0, iy = 0; ++ ++ if (n < 0) { ++ return dot; ++ } ++ ++ int i = 0; ++ while (i < n) { ++ dot += y[iy] * x[ix]; ++ ix += inc_x; ++ iy += inc_y; ++ i++; ++ } ++ ++ return dot; ++} ++ ++/* { dg-final { scan-assembler-not "smaddl" { target aarch64*-*-* } } } */ +diff -Nurp a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c +--- a/gcc/tree-ssa-math-opts.c 2020-04-17 16:43:59.540000000 +0800 ++++ b/gcc/tree-ssa-math-opts.c 2020-04-17 16:48:34.072036000 +0800 +@@ -2721,11 +2721,14 @@ convert_plusminus_to_widen (gimple_stmt_ + multiply-and-accumulate instructions. + + If the widened-multiplication result has more than one uses, it is +- probably wiser not to do the conversion. */ ++ probably wiser not to do the conversion. Also restrict this operation ++ to single basic block to avoid moving the multiply to a different block ++ with a higher execution frequency. */ + if (code == PLUS_EXPR + && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR)) + { + if (!has_single_use (rhs1) ++ || gimple_bb (rhs1_stmt) != gimple_bb (stmt) + || !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1, + &type2, &mult_rhs2)) + return false; +@@ -2735,6 +2738,7 @@ convert_plusminus_to_widen (gimple_stmt_ + else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR) + { + if (!has_single_use (rhs2) ++ || gimple_bb (rhs2_stmt) != gimple_bb (stmt) + || !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1, + &type2, &mult_rhs2)) + return false; diff --git a/arm-adjust-be-ldrd-strd.patch b/arm-adjust-be-ldrd-strd.patch deleted file mode 100644 index 90278d3e6e8af0f9a66bb68c4f92222043098d10..0000000000000000000000000000000000000000 --- a/arm-adjust-be-ldrd-strd.patch +++ /dev/null @@ -1,60 +0,0 @@ -diff -urp a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c ---- a/gcc/config/arm/arm.c 2019-01-18 11:25:20.840179114 +0800 -+++ b/gcc/config/arm/arm.c 2019-01-18 11:25:47.548179817 +0800 -@@ -14306,18 +14306,36 @@ gen_movmem_ldrd_strd (rtx *operands) - emit_move_insn (reg0, src); - else - { -- emit_insn (gen_unaligned_loadsi (low_reg, src)); -- src = next_consecutive_mem (src); -- emit_insn (gen_unaligned_loadsi (hi_reg, src)); -+ if (flag_lsrd_be_adjust && BYTES_BIG_ENDIAN && WORDS_BIG_ENDIAN) -+ { -+ emit_insn (gen_unaligned_loadsi (hi_reg, src)); -+ src = next_consecutive_mem (src); -+ emit_insn (gen_unaligned_loadsi (low_reg, src)); -+ } -+ else -+ { -+ emit_insn (gen_unaligned_loadsi (low_reg, src)); -+ src = next_consecutive_mem (src); -+ emit_insn (gen_unaligned_loadsi (hi_reg, src)); -+ } - } - - if (dst_aligned) - emit_move_insn (dst, reg0); - else - { -- emit_insn (gen_unaligned_storesi (dst, low_reg)); -- dst = next_consecutive_mem (dst); -- emit_insn (gen_unaligned_storesi (dst, hi_reg)); -+ if (flag_lsrd_be_adjust && BYTES_BIG_ENDIAN && WORDS_BIG_ENDIAN) -+ { -+ emit_insn (gen_unaligned_storesi (dst, hi_reg)); -+ dst = next_consecutive_mem (dst); -+ emit_insn (gen_unaligned_storesi (dst, low_reg)); -+ } -+ else -+ { -+ emit_insn (gen_unaligned_storesi (dst, low_reg)); -+ dst = next_consecutive_mem (dst); -+ emit_insn (gen_unaligned_storesi (dst, hi_reg)); -+ } - } - - src = next_consecutive_mem (src); -diff -urp a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt ---- a/gcc/config/arm/arm.opt 2019-01-18 11:25:20.840179114 +0800 -+++ b/gcc/config/arm/arm.opt 2019-01-18 11:28:51.744184666 +0800 -@@ -274,6 +274,10 @@ masm-syntax-unified - Target Report Var(inline_asm_unified) Init(0) Save - Assume unified syntax for inline assembly code. - -+mlsrd-be-adjust -+Target Report Var(flag_lsrd_be_adjust) Init(1) -+Adjust ldrd/strd splitting order when it's big-endian. -+ - mpure-code - Target Report Var(target_pure_code) Init(0) - Do not allow constant data to be placed in code sections. diff --git a/arm-bigendian-disable-interleaved-LS-vectorize.patch b/arm-bigendian-disable-interleaved-LS-vectorize.patch deleted file mode 100644 index 06c12c891d4856bd8c63de857fddba35590e14c1..0000000000000000000000000000000000000000 --- a/arm-bigendian-disable-interleaved-LS-vectorize.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff -urpN gcc-7.3.0-bak/gcc/config/arm/arm.c gcc-7.3.0/gcc/config/arm/arm.c ---- gcc-7.3.0-bak/gcc/config/arm/arm.c 2018-11-13 14:23:21.362347728 +0800 -+++ gcc-7.3.0/gcc/config/arm/arm.c 2018-11-13 14:31:15.722360215 +0800 -@@ -26853,7 +26853,14 @@ static bool - arm_array_mode_supported_p (machine_mode mode, - unsigned HOST_WIDE_INT nelems) - { -- if (TARGET_NEON -+ -+ -+ /* We don't want to enable interleaved loads and stores for BYTES_BIG_ENDIAN -+ for now, as the lane-swapping logic needs to be extended in the expanders. -+ See PR target/82518. */ -+ -+ -+ if (TARGET_NEON && !BYTES_BIG_ENDIAN - && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)) - && (nelems >= 2 && nelems <= 4)) - return true; diff --git a/arm-fix-push-minipool.patch b/arm-fix-push-minipool.patch deleted file mode 100644 index 126ee92e978598576df09879b25dfa8d694725d8..0000000000000000000000000000000000000000 --- a/arm-fix-push-minipool.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff -Nurp a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md ---- a/gcc/config/arm/arm.md 2019-08-10 00:21:12.658523444 +0800 -+++ b/gcc/config/arm/arm.md 2019-08-10 00:21:53.478521496 +0800 -@@ -5337,7 +5337,9 @@ - # - ldrh%?\\t%0, %1" - [(set_attr "type" "alu_shift_reg,load_byte") -- (set_attr "predicable" "yes")] -+ (set_attr "predicable" "yes") -+ (set_attr "pool_range" "*,256") -+ (set_attr "neg_pool_range" "*,244")] - ) - - (define_insn "*arm_zero_extendhisi2_v6" -@@ -5348,7 +5350,9 @@ - uxth%?\\t%0, %1 - ldrh%?\\t%0, %1" - [(set_attr "predicable" "yes") -- (set_attr "type" "extend,load_byte")] -+ (set_attr "type" "extend,load_byte") -+ (set_attr "pool_range" "*,256") -+ (set_attr "neg_pool_range" "*,244")] - ) - - (define_insn "*arm_zero_extendhisi2addsi" diff --git a/cloog-0.18.4.tar.gz b/cloog-0.18.4.tar.gz deleted file mode 100644 index f2208167d710c11120f8a1f67b14fa4e38a38306..0000000000000000000000000000000000000000 Binary files a/cloog-0.18.4.tar.gz and /dev/null differ diff --git a/constructor-priority-bugfix.patch b/constructor-priority-bugfix.patch deleted file mode 100644 index fbc3be0cf0ed865a46f78e31d69391e3ffc29394..0000000000000000000000000000000000000000 --- a/constructor-priority-bugfix.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -N -urp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c ---- a/gcc/config/aarch64/aarch64.c 2018-11-16 18:02:11.000000000 +0800 -+++ b/gcc/config/aarch64/aarch64.c 2018-11-16 18:07:39.000000000 +0800 -@@ -6102,7 +6102,7 @@ aarch64_elf_asm_constructor (rtx symbol, - -Wformat-truncation false positive, use a larger size. */ - char buf[23]; - snprintf (buf, sizeof (buf), ".init_array.%.5u", priority); -- s = get_section (buf, SECTION_WRITE, NULL); -+ s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL); - switch_to_section (s); - assemble_align (POINTER_SIZE); - assemble_aligned_integer (POINTER_BYTES, symbol); -@@ -6122,7 +6122,7 @@ aarch64_elf_asm_destructor (rtx symbol, - -Wformat-truncation false positive, use a larger size. */ - char buf[23]; - snprintf (buf, sizeof (buf), ".fini_array.%.5u", priority); -- s = get_section (buf, SECTION_WRITE, NULL); -+ s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL); - switch_to_section (s); - assemble_align (POINTER_SIZE); - assemble_aligned_integer (POINTER_BYTES, symbol); diff --git a/delete-incorrect-smw.patch b/delete-incorrect-smw.patch new file mode 100644 index 0000000000000000000000000000000000000000..087166f0c529af9b28acb062e6bcac73b2d1c33f --- /dev/null +++ b/delete-incorrect-smw.patch @@ -0,0 +1,52 @@ +diff -uprN a/gcc/testsuite/gcc.dg/pr91195.c b/gcc/testsuite/gcc.dg/pr91195.c +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/pr91195.c +@@ -0,0 +1,25 @@ ++/* PR middle-end/91195 */ ++/* { dg-do compile } */ ++/* { dg-options "-Wmaybe-uninitialized -O2" } */ ++ ++int bar (char*); ++ ++void ++foo (char *x, char *y) ++{ ++ char *a[2]; ++ int b = 0; ++ ++ if (x) ++ a[b++] = x; /* { dg-bogus "may be used uninitialized in this function" } */ ++ if (y) ++ a[b++] = y; ++ ++ for (int j = 0; j < 4; j++) ++ switch (j) ++ { ++ case 0: ++ if (b == 0 || bar (a[0])) ++ break; ++ } ++} +diff -uprN a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c +--- a/gcc/tree-ssa-phiopt.c ++++ b/gcc/tree-ssa-phiopt.c +@@ -2269,6 +2269,10 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, + name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore"); + new_stmt = gimple_build_assign (name, lhs); + gimple_set_location (new_stmt, locus); ++ lhs = unshare_expr (lhs); ++ /* Set TREE_NO_WARNING on the rhs of the load to avoid uninit ++ warnings. */ ++ TREE_NO_WARNING (gimple_assign_rhs1 (new_stmt)) = 1; + gsi_insert_on_edge (e1, new_stmt); + + /* 3) Create a PHI node at the join block, with one argument +@@ -2279,7 +2283,6 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, + add_phi_arg (newphi, rhs, e0, locus); + add_phi_arg (newphi, name, e1, locus); + +- lhs = unshare_expr (lhs); + new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi)); + + /* 4) Insert that PHI node. */ diff --git a/div-opti.patch b/div-opti.patch new file mode 100644 index 0000000000000000000000000000000000000000..11519970112084d81ee140759e6f050b5e49d130 --- /dev/null +++ b/div-opti.patch @@ -0,0 +1,69 @@ +From dbf3dc75888623e9d4bb7cc5e9c30caa9b24ffe7 Mon Sep 17 00:00:00 2001 +From: Bu Le +Date: Thu, 12 Mar 2020 22:39:12 +0000 +Subject: [PATCH] aarch64: Add --params to control the number of recip steps + [PR94154] + +-mlow-precision-div hard-coded the number of iterations to 2 for double +and 1 for float. This patch adds a --param to control the number. + +2020-03-13 Bu Le + +gcc/ + PR target/94154 + * config/aarch64/aarch64.opt (-param=aarch64-float-recp-precision=) + (-param=aarch64-double-recp-precision=): New options. + * doc/invoke.texi: Document them. + * config/aarch64/aarch64.c (aarch64_emit_approx_div): Use them + instead of hard-coding the choice of 1 for float and 2 for double. +--- + gcc/ChangeLog | 9 +++++++++ + gcc/config/aarch64/aarch64.c | 8 +++++--- + gcc/config/aarch64/aarch64.opt | 9 +++++++++ + gcc/doc/invoke.texi | 11 +++++++++++ + 4 files changed, 34 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c +index c320d5ba51d..2c81f86dd2a 100644 +--- a/gcc/config/aarch64/aarch64.c ++++ b/gcc/config/aarch64/aarch64.c +@@ -12911,10 +12911,12 @@ aarch64_emit_approx_div (rtx quo, rtx num, rtx den) + /* Iterate over the series twice for SF and thrice for DF. */ + int iterations = (GET_MODE_INNER (mode) == DFmode) ? 3 : 2; + +- /* Optionally iterate over the series once less for faster performance, +- while sacrificing the accuracy. */ ++ /* Optionally iterate over the series less for faster performance, ++ while sacrificing the accuracy. The default is 2 for DF and 1 for SF. */ + if (flag_mlow_precision_div) +- iterations--; ++ iterations = (GET_MODE_INNER (mode) == DFmode ++ ? PARAM_VALUE (PARAM_AARCH64_DOUBLE_RECP_PRECISION) ++ : PARAM_VALUE (PARAM_AARCH64_FLOAT_RECP_PRECISION)); + + /* Iterate over the series to calculate the approximate reciprocal. */ + rtx xtmp = gen_reg_rtx (mode); + +--- a/gcc/params.def 2020-04-15 17:24:31.984000000 +0800 ++++ b/gcc/params.def 2020-04-15 16:59:21.752000000 +0800 +@@ -1420,6 +1414,17 @@ DEFPARAM(PARAM_SSA_NAME_DEF_CHAIN_LIMIT, + "a value.", + 512, 0, 0) + ++DEFPARAM(PARAM_AARCH64_FLOAT_RECP_PRECISION, ++ "aarch64-float-recp-precision", ++ "The number of Newton iterations for calculating the reciprocal " ++ "for float type. ", ++ 1, 1, 5) ++ ++DEFPARAM(PARAM_AARCH64_DOUBLE_RECP_PRECISION, ++ "aarch64-double-recp-precision", ++ "The number of Newton iterations for calculating the reciprocal " ++ "for double type.", ++ 2, 1, 5) + /* + + Local variables: +-- +2.18.2 + diff --git a/dont-generate-IF_THEN_ELSE.patch b/dont-generate-IF_THEN_ELSE.patch new file mode 100644 index 0000000000000000000000000000000000000000..791b57ba4d0cbdb627aa1524cdcde23f152b2b4c --- /dev/null +++ b/dont-generate-IF_THEN_ELSE.patch @@ -0,0 +1,19 @@ +diff --git a/gcc/combine.c b/gcc/combine.c +index 4de759a8e6b..ce7aeecb5c2 100644 +--- a/gcc/combine.c ++++ b/gcc/combine.c +@@ -5909,14 +5909,6 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest, + mode, VOIDmode, + cond, cop1), + mode); +- else +- return gen_rtx_IF_THEN_ELSE (mode, +- simplify_gen_relational (cond_code, +- mode, +- VOIDmode, +- cond, +- cop1), +- true_rtx, false_rtx); + + code = GET_CODE (x); + op0_mode = VOIDmode; diff --git a/enable-aarch64-libquadmath.patch b/enable-aarch64-libquadmath.patch new file mode 100644 index 0000000000000000000000000000000000000000..c45b07822c052d4ac2fed8c8faf41cd0a32bb332 --- /dev/null +++ b/enable-aarch64-libquadmath.patch @@ -0,0 +1,460 @@ +diff -urpN a/libquadmath/Makefile.in b/libquadmath/Makefile.in +--- a/libquadmath/Makefile.in 2020-03-31 09:51:59.000000000 +0800 ++++ b/libquadmath/Makefile.in 2020-04-06 11:52:45.650793256 +0800 +@@ -90,7 +90,7 @@ POST_UNINSTALL = : + build_triplet = @build@ + host_triplet = @host@ + target_triplet = @target@ +-@BUILD_LIBQUADMATH_FALSE@libquadmath_la_DEPENDENCIES = ++#libquadmath_la_DEPENDENCIES = + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ +@@ -146,68 +146,68 @@ am__installdirs = "$(DESTDIR)$(toolexecl + "$(DESTDIR)$(libsubincludedir)" + LTLIBRARIES = $(toolexeclib_LTLIBRARIES) + am__dirstamp = $(am__leading_dot)dirstamp +-@BUILD_LIBQUADMATH_TRUE@am_libquadmath_la_OBJECTS = math/x2y2m1q.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/acoshq.lo math/fmodq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/acosq.lo math/frexpq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/rem_pio2q.lo math/asinhq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/hypotq.lo math/remainderq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/asinq.lo math/rintq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/atan2q.lo math/isinfq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/roundq.lo math/atanhq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/isnanq.lo math/scalblnq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/atanq.lo math/j0q.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/scalbnq.lo math/cbrtq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/j1q.lo math/signbitq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/ceilq.lo math/jnq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/sincos_table.lo math/complex.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/ldexpq.lo math/sincosq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/copysignq.lo math/lgammaq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/sincosq_kernel.lo math/coshq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/llroundq.lo math/sinhq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/cosq.lo math/log10q.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/sinq.lo math/cosq_kernel.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/log1pq.lo math/sinq_kernel.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/erfq.lo math/logq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/sqrtq.lo math/expm1q.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/lroundq.lo math/tanhq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/expq.lo math/modfq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/tanq.lo math/fabsq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/nanq.lo math/tgammaq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/finiteq.lo math/nextafterq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/truncq.lo math/floorq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/powq.lo math/fmaq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/logbq.lo math/exp2q.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/issignalingq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/lgammaq_neg.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/lgammaq_product.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/tanq_kernel.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/tgammaq_product.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/casinhq_kernel.lo math/cacoshq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/cacosq.lo math/casinhq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/casinq.lo math/catanhq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/catanq.lo math/cimagq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/conjq.lo math/cprojq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/crealq.lo math/fdimq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/fmaxq.lo math/fminq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/ilogbq.lo math/llrintq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/log2q.lo math/lrintq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/nearbyintq.lo math/remquoq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/ccoshq.lo math/cexpq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/clog10q.lo math/clogq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/csinq.lo math/csinhq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/csqrtq.lo math/ctanq.lo \ +-@BUILD_LIBQUADMATH_TRUE@ math/ctanhq.lo printf/addmul_1.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/add_n.lo printf/cmp.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/divrem.lo printf/flt1282mpn.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/fpioconst.lo printf/lshift.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/mul_1.lo printf/mul_n.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/mul.lo printf/printf_fphex.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/printf_fp.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/quadmath-printf.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/rshift.lo printf/submul_1.lo \ +-@BUILD_LIBQUADMATH_TRUE@ printf/sub_n.lo strtod/strtoflt128.lo \ +-@BUILD_LIBQUADMATH_TRUE@ strtod/mpn2flt128.lo \ +-@BUILD_LIBQUADMATH_TRUE@ strtod/tens_in_limb.lo ++am_libquadmath_la_OBJECTS = math/x2y2m1q.lo \ ++ math/acoshq.lo math/fmodq.lo \ ++ math/acosq.lo math/frexpq.lo \ ++ math/rem_pio2q.lo math/asinhq.lo \ ++ math/hypotq.lo math/remainderq.lo \ ++ math/asinq.lo math/rintq.lo \ ++ math/atan2q.lo math/isinfq.lo \ ++ math/roundq.lo math/atanhq.lo \ ++ math/isnanq.lo math/scalblnq.lo \ ++ math/atanq.lo math/j0q.lo \ ++ math/scalbnq.lo math/cbrtq.lo \ ++ math/j1q.lo math/signbitq.lo \ ++ math/ceilq.lo math/jnq.lo \ ++ math/sincos_table.lo math/complex.lo \ ++ math/ldexpq.lo math/sincosq.lo \ ++ math/copysignq.lo math/lgammaq.lo \ ++ math/sincosq_kernel.lo math/coshq.lo \ ++ math/llroundq.lo math/sinhq.lo \ ++ math/cosq.lo math/log10q.lo \ ++ math/sinq.lo math/cosq_kernel.lo \ ++ math/log1pq.lo math/sinq_kernel.lo \ ++ math/erfq.lo math/logq.lo \ ++ math/sqrtq.lo math/expm1q.lo \ ++ math/lroundq.lo math/tanhq.lo \ ++ math/expq.lo math/modfq.lo \ ++ math/tanq.lo math/fabsq.lo \ ++ math/nanq.lo math/tgammaq.lo \ ++ math/finiteq.lo math/nextafterq.lo \ ++ math/truncq.lo math/floorq.lo \ ++ math/powq.lo math/fmaq.lo \ ++ math/logbq.lo math/exp2q.lo \ ++ math/issignalingq.lo \ ++ math/lgammaq_neg.lo \ ++ math/lgammaq_product.lo \ ++ math/tanq_kernel.lo \ ++ math/tgammaq_product.lo \ ++ math/casinhq_kernel.lo math/cacoshq.lo \ ++ math/cacosq.lo math/casinhq.lo \ ++ math/casinq.lo math/catanhq.lo \ ++ math/catanq.lo math/cimagq.lo \ ++ math/conjq.lo math/cprojq.lo \ ++ math/crealq.lo math/fdimq.lo \ ++ math/fmaxq.lo math/fminq.lo \ ++ math/ilogbq.lo math/llrintq.lo \ ++ math/log2q.lo math/lrintq.lo \ ++ math/nearbyintq.lo math/remquoq.lo \ ++ math/ccoshq.lo math/cexpq.lo \ ++ math/clog10q.lo math/clogq.lo \ ++ math/csinq.lo math/csinhq.lo \ ++ math/csqrtq.lo math/ctanq.lo \ ++ math/ctanhq.lo printf/addmul_1.lo \ ++ printf/add_n.lo printf/cmp.lo \ ++ printf/divrem.lo printf/flt1282mpn.lo \ ++ printf/fpioconst.lo printf/lshift.lo \ ++ printf/mul_1.lo printf/mul_n.lo \ ++ printf/mul.lo printf/printf_fphex.lo \ ++ printf/printf_fp.lo \ ++ printf/quadmath-printf.lo \ ++ printf/rshift.lo printf/submul_1.lo \ ++ printf/sub_n.lo strtod/strtoflt128.lo \ ++ strtod/mpn2flt128.lo \ ++ strtod/tens_in_limb.lo + libquadmath_la_OBJECTS = $(am_libquadmath_la_OBJECTS) + AM_V_lt = $(am__v_lt_@AM_V@) + am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +@@ -217,8 +217,8 @@ libquadmath_la_LINK = $(LIBTOOL) $(AM_V_ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libquadmath_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +-@BUILD_LIBQUADMATH_TRUE@am_libquadmath_la_rpath = -rpath \ +-@BUILD_LIBQUADMATH_TRUE@ $(toolexeclibdir) ++am_libquadmath_la_rpath = -rpath \ ++ $(toolexeclibdir) + AM_V_P = $(am__v_P_@AM_V@) + am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) + am__v_P_0 = false +@@ -336,7 +336,7 @@ CFLAGS = @CFLAGS@ + CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ + CYGPATH_W = @CYGPATH_W@ +-DEFS = @DEFS@ ++DEFS = @DEFS@ -D__float128="long double" + DEPDIR = @DEPDIR@ + DSYMUTIL = @DSYMUTIL@ + DUMPBIN = @DUMPBIN@ +@@ -408,7 +408,7 @@ datadir = @datadir@ + datarootdir = @datarootdir@ + docdir = @docdir@ + dvidir = @dvidir@ +-enable_shared = @enable_shared@ ++enable_shared = yes + enable_static = @enable_static@ + exec_prefix = @exec_prefix@ + get_gcc_base_ver = @get_gcc_base_ver@ +@@ -450,109 +450,109 @@ top_build_prefix = @top_build_prefix@ + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + AUTOMAKE_OPTIONS = foreign info-in-builddir +-@BUILD_LIBQUADMATH_TRUE@ACLOCAL_AMFLAGS = -I .. -I ../config +-@BUILD_LIBQUADMATH_TRUE@AM_CPPFLAGS = -I $(top_srcdir)/../include +-@BUILD_LIBQUADMATH_TRUE@AM_CFLAGS = $(XCFLAGS) +-@BUILD_LIBQUADMATH_TRUE@gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_FALSE@version_arg = +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,--version-script=$(srcdir)/quadmath.map +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,-M,quadmath.map-sun +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_FALSE@version_dep = +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = $(srcdir)/quadmath.map +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = quadmath.map-sun +-@BUILD_LIBQUADMATH_TRUE@toolexeclib_LTLIBRARIES = libquadmath.la +-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_LIBADD = +-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ +-@BUILD_LIBQUADMATH_TRUE@ $(version_arg) $(lt_host_flags) -lm +- +-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) +-@BUILD_LIBQUADMATH_TRUE@nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h +-@BUILD_LIBQUADMATH_TRUE@libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include +-@BUILD_LIBQUADMATH_TRUE@libquadmath_la_SOURCES = \ +-@BUILD_LIBQUADMATH_TRUE@ math/x2y2m1q.c math/acoshq.c math/fmodq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/acosq.c math/frexpq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/rem_pio2q.c math/asinhq.c math/hypotq.c math/remainderq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/asinq.c math/rintq.c math/atan2q.c math/isinfq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/roundq.c math/atanhq.c math/isnanq.c math/scalblnq.c math/atanq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/j0q.c math/scalbnq.c math/cbrtq.c math/j1q.c math/signbitq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/ceilq.c math/jnq.c math/sincos_table.c math/complex.c math/ldexpq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/sincosq.c math/copysignq.c math/lgammaq.c math/sincosq_kernel.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/coshq.c math/llroundq.c math/sinhq.c math/cosq.c math/log10q.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/sinq.c math/cosq_kernel.c math/log1pq.c math/sinq_kernel.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/erfq.c math/logq.c math/sqrtq.c math/expm1q.c math/lroundq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/tanhq.c math/expq.c math/modfq.c math/tanq.c math/fabsq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/nanq.c math/tgammaq.c math/finiteq.c math/nextafterq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/truncq.c math/floorq.c math/powq.c math/fmaq.c math/logbq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/exp2q.c math/issignalingq.c math/lgammaq_neg.c math/lgammaq_product.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/tanq_kernel.c math/tgammaq_product.c math/casinhq_kernel.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/cacoshq.c math/cacosq.c math/casinhq.c math/casinq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/catanhq.c math/catanq.c math/cimagq.c math/conjq.c math/cprojq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/crealq.c math/fdimq.c math/fmaxq.c math/fminq.c math/ilogbq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/ccoshq.c math/cexpq.c math/clog10q.c math/clogq.c math/csinq.c \ +-@BUILD_LIBQUADMATH_TRUE@ math/csinhq.c math/csqrtq.c math/ctanq.c math/ctanhq.c \ +-@BUILD_LIBQUADMATH_TRUE@ printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \ +-@BUILD_LIBQUADMATH_TRUE@ printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \ +-@BUILD_LIBQUADMATH_TRUE@ printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \ +-@BUILD_LIBQUADMATH_TRUE@ printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c \ +-@BUILD_LIBQUADMATH_TRUE@ strtod/strtoflt128.c strtod/mpn2flt128.c strtod/tens_in_limb.c ++ACLOCAL_AMFLAGS = -I .. -I ../config ++AM_CPPFLAGS = -I $(top_srcdir)/../include ++AM_CFLAGS = $(XCFLAGS) ++gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) ++@LIBQUAD_USE_SYMVER_FALSE@version_arg = ++@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,--version-script=$(srcdir)/quadmath.map ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,-M,quadmath.map-sun ++@LIBQUAD_USE_SYMVER_FALSE@version_dep = ++@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = $(srcdir)/quadmath.map ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_dep = quadmath.map-sun ++toolexeclib_LTLIBRARIES = libquadmath.la ++libquadmath_la_LIBADD = ++libquadmath_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` \ ++ $(version_arg) $(lt_host_flags) -lm ++ ++libquadmath_la_DEPENDENCIES = $(version_dep) $(libquadmath_la_LIBADD) ++nodist_libsubinclude_HEADERS = quadmath.h quadmath_weak.h ++libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include ++libquadmath_la_SOURCES = \ ++ math/x2y2m1q.c math/acoshq.c math/fmodq.c \ ++ math/acosq.c math/frexpq.c \ ++ math/rem_pio2q.c math/asinhq.c math/hypotq.c math/remainderq.c \ ++ math/asinq.c math/rintq.c math/atan2q.c math/isinfq.c \ ++ math/roundq.c math/atanhq.c math/isnanq.c math/scalblnq.c math/atanq.c \ ++ math/j0q.c math/scalbnq.c math/cbrtq.c math/j1q.c math/signbitq.c \ ++ math/ceilq.c math/jnq.c math/sincos_table.c math/complex.c math/ldexpq.c \ ++ math/sincosq.c math/copysignq.c math/lgammaq.c math/sincosq_kernel.c \ ++ math/coshq.c math/llroundq.c math/sinhq.c math/cosq.c math/log10q.c \ ++ math/sinq.c math/cosq_kernel.c math/log1pq.c math/sinq_kernel.c \ ++ math/erfq.c math/logq.c math/sqrtq.c math/expm1q.c math/lroundq.c \ ++ math/tanhq.c math/expq.c math/modfq.c math/tanq.c math/fabsq.c \ ++ math/nanq.c math/tgammaq.c math/finiteq.c math/nextafterq.c \ ++ math/truncq.c math/floorq.c math/powq.c math/fmaq.c math/logbq.c \ ++ math/exp2q.c math/issignalingq.c math/lgammaq_neg.c math/lgammaq_product.c \ ++ math/tanq_kernel.c math/tgammaq_product.c math/casinhq_kernel.c \ ++ math/cacoshq.c math/cacosq.c math/casinhq.c math/casinq.c \ ++ math/catanhq.c math/catanq.c math/cimagq.c math/conjq.c math/cprojq.c \ ++ math/crealq.c math/fdimq.c math/fmaxq.c math/fminq.c math/ilogbq.c \ ++ math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \ ++ math/ccoshq.c math/cexpq.c math/clog10q.c math/clogq.c math/csinq.c \ ++ math/csinhq.c math/csqrtq.c math/ctanq.c math/ctanhq.c \ ++ printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \ ++ printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \ ++ printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \ ++ printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c \ ++ strtod/strtoflt128.c strtod/mpn2flt128.c strtod/tens_in_limb.c + + + # Work around what appears to be a GNU make bug handling MAKEFLAGS + # values defined in terms of make variables, as is the case for CC and + # friends when we are called from the top level Makefile. +-@BUILD_LIBQUADMATH_TRUE@AM_MAKEFLAGS = \ +-@BUILD_LIBQUADMATH_TRUE@ "AR_FLAGS=$(AR_FLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ +-@BUILD_LIBQUADMATH_TRUE@ "CFLAGS=$(CFLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "CXXFLAGS=$(CXXFLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ +-@BUILD_LIBQUADMATH_TRUE@ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ +-@BUILD_LIBQUADMATH_TRUE@ "INSTALL=$(INSTALL)" \ +-@BUILD_LIBQUADMATH_TRUE@ "INSTALL_DATA=$(INSTALL_DATA)" \ +-@BUILD_LIBQUADMATH_TRUE@ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ +-@BUILD_LIBQUADMATH_TRUE@ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ +-@BUILD_LIBQUADMATH_TRUE@ "JC1FLAGS=$(JC1FLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "LDFLAGS=$(LDFLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "LIBCFLAGS=$(LIBCFLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ +-@BUILD_LIBQUADMATH_TRUE@ "MAKE=$(MAKE)" \ +-@BUILD_LIBQUADMATH_TRUE@ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "PICFLAG=$(PICFLAG)" \ +-@BUILD_LIBQUADMATH_TRUE@ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ +-@BUILD_LIBQUADMATH_TRUE@ "SHELL=$(SHELL)" \ +-@BUILD_LIBQUADMATH_TRUE@ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "exec_prefix=$(exec_prefix)" \ +-@BUILD_LIBQUADMATH_TRUE@ "infodir=$(infodir)" \ +-@BUILD_LIBQUADMATH_TRUE@ "libdir=$(libdir)" \ +-@BUILD_LIBQUADMATH_TRUE@ "prefix=$(prefix)" \ +-@BUILD_LIBQUADMATH_TRUE@ "includedir=$(includedir)" \ +-@BUILD_LIBQUADMATH_TRUE@ "AR=$(AR)" \ +-@BUILD_LIBQUADMATH_TRUE@ "AS=$(AS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "CC=$(CC)" \ +-@BUILD_LIBQUADMATH_TRUE@ "CXX=$(CXX)" \ +-@BUILD_LIBQUADMATH_TRUE@ "LD=$(LD)" \ +-@BUILD_LIBQUADMATH_TRUE@ "LIBCFLAGS=$(LIBCFLAGS)" \ +-@BUILD_LIBQUADMATH_TRUE@ "NM=$(NM)" \ +-@BUILD_LIBQUADMATH_TRUE@ "PICFLAG=$(PICFLAG)" \ +-@BUILD_LIBQUADMATH_TRUE@ "RANLIB=$(RANLIB)" \ +-@BUILD_LIBQUADMATH_TRUE@ "DESTDIR=$(DESTDIR)" ++AM_MAKEFLAGS = \ ++ "AR_FLAGS=$(AR_FLAGS)" \ ++ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ ++ "CFLAGS=$(CFLAGS)" \ ++ "CXXFLAGS=$(CXXFLAGS)" \ ++ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ ++ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ ++ "INSTALL=$(INSTALL)" \ ++ "INSTALL_DATA=$(INSTALL_DATA)" \ ++ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ ++ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ ++ "JC1FLAGS=$(JC1FLAGS)" \ ++ "LDFLAGS=$(LDFLAGS)" \ ++ "LIBCFLAGS=$(LIBCFLAGS)" \ ++ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ ++ "MAKE=$(MAKE)" \ ++ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ ++ "PICFLAG=$(PICFLAG)" \ ++ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ ++ "SHELL=$(SHELL)" \ ++ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ ++ "exec_prefix=$(exec_prefix)" \ ++ "infodir=$(infodir)" \ ++ "libdir=$(libdir)" \ ++ "prefix=$(prefix)" \ ++ "includedir=$(includedir)" \ ++ "AR=$(AR)" \ ++ "AS=$(AS)" \ ++ "CC=$(CC)" \ ++ "CXX=$(CXX)" \ ++ "LD=$(LD)" \ ++ "LIBCFLAGS=$(LIBCFLAGS)" \ ++ "NM=$(NM)" \ ++ "PICFLAG=$(PICFLAG)" \ ++ "RANLIB=$(RANLIB)" \ ++ "DESTDIR=$(DESTDIR)" + + + # Subdir rules rely on $(FLAGS_TO_PASS) +-@BUILD_LIBQUADMATH_TRUE@FLAGS_TO_PASS = $(AM_MAKEFLAGS) +-@BUILD_LIBQUADMATH_TRUE@MAKEOVERRIDES = +-@BUILD_LIBQUADMATH_TRUE@@GENINSRC_FALSE@STAMP_GENINSRC = ++FLAGS_TO_PASS = $(AM_MAKEFLAGS) ++MAKEOVERRIDES = ++@GENINSRC_FALSE@STAMP_GENINSRC = + + # AM_CONDITIONAL on configure option --generated-files-in-srcdir +-@BUILD_LIBQUADMATH_TRUE@@GENINSRC_TRUE@STAMP_GENINSRC = stamp-geninsrc +-@BUILD_LIBQUADMATH_TRUE@ALL_LOCAL_DEPS = $(STAMP_GENINSRC) +-@BUILD_INFO_FALSE@@BUILD_LIBQUADMATH_TRUE@STAMP_BUILD_INFO = ++@GENINSRC_TRUE@STAMP_GENINSRC = stamp-geninsrc ++ALL_LOCAL_DEPS = $(STAMP_GENINSRC) ++@BUILD_INFO_FALSE@STAMP_BUILD_INFO = + + # AM_CONDITIONAL on configure check ACX_CHECK_PROG_VER([MAKEINFO]) +-@BUILD_INFO_TRUE@@BUILD_LIBQUADMATH_TRUE@STAMP_BUILD_INFO = stamp-build-info +-@BUILD_LIBQUADMATH_TRUE@CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO) +-@BUILD_LIBQUADMATH_TRUE@MAINTAINERCLEANFILES = $(srcdir)/libquadmath.info ++@BUILD_INFO_TRUE@STAMP_BUILD_INFO = stamp-build-info ++CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO) ++MAINTAINERCLEANFILES = $(srcdir)/libquadmath.info + + # Automake Documentation: + # If your package has Texinfo files in many directories, you can use the +@@ -563,8 +563,8 @@ TEXINFO_TEX = ../gcc/doc/include/texinfo + + # Defines info, dvi, pdf and html targets + MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include +-@BUILD_LIBQUADMATH_FALSE@info_TEXINFOS = +-@BUILD_LIBQUADMATH_TRUE@info_TEXINFOS = libquadmath.texi ++info_TEXINFOS = ++info_TEXINFOS = libquadmath.texi + libquadmath_TEXINFOS = libquadmath-vers.texi + MULTISRCTOP = + MULTIBUILDTOP = +@@ -1186,6 +1186,7 @@ distclean-tags: + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + check-am: all-am + check: check-am ++#all-local + all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(HEADERS) config.h \ + all-local + installdirs: +@@ -1424,22 +1425,22 @@ uninstall-am: uninstall-dvi-am uninstall + + .PRECIOUS: Makefile + +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@quadmath.map-sun : $(srcdir)/quadmath.map \ +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(top_srcdir)/../contrib/make_sunver.pl \ +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ perl $(top_srcdir)/../contrib/make_sunver.pl \ +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(srcdir)/quadmath.map \ +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ `echo $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) | \ +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ sed 's,\([^/ ]*\)\.l\([ao]\),.libs/\1.\2,g'` \ +-@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ > $@ || (rm -f $@ ; exit 1) +- +-@BUILD_LIBQUADMATH_TRUE@stamp-geninsrc: libquadmath.info +-@BUILD_LIBQUADMATH_TRUE@ cp -p $(top_builddir)/libquadmath.info $(srcdir)/libquadmath.info +-@BUILD_LIBQUADMATH_TRUE@ @touch $@ +- +-@BUILD_LIBQUADMATH_TRUE@stamp-build-info: libquadmath.texi $(libquadmath_TEXINFOS) +-@BUILD_LIBQUADMATH_TRUE@ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libquadmath.info $(srcdir)/libquadmath.texi +-@BUILD_LIBQUADMATH_TRUE@ @touch $@ ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@quadmath.map-sun : $(srcdir)/quadmath.map \ ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(top_srcdir)/../contrib/make_sunver.pl \ ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ perl $(top_srcdir)/../contrib/make_sunver.pl \ ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ $(srcdir)/quadmath.map \ ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ `echo $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) | \ ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ sed 's,\([^/ ]*\)\.l\([ao]\),.libs/\1.\2,g'` \ ++@LIBQUAD_USE_SYMVER_SUN_TRUE@@LIBQUAD_USE_SYMVER_TRUE@ > $@ || (rm -f $@ ; exit 1) ++ ++stamp-geninsrc: libquadmath.info ++ cp -p $(top_builddir)/libquadmath.info $(srcdir)/libquadmath.info ++ @touch $@ ++ ++stamp-build-info: libquadmath.texi $(libquadmath_TEXINFOS) ++ $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libquadmath.info $(srcdir)/libquadmath.texi ++ @touch $@ + + all-local: $(ALL_LOCAL_DEPS) + +diff -Nurp a/libquadmath/quadmath.h b/libquadmath/quadmath.h +--- a/libquadmath/quadmath.h 2020-03-31 09:51:59.000000000 +0800 ++++ b/libquadmath/quadmath.h 2020-04-06 11:52:45.650793256 +0800 +@@ -27,6 +27,9 @@ Boston, MA 02110-1301, USA. */ + extern "C" { + #endif + ++#ifdef AARCH64_QUADMATH ++typedef long double __float128; ++#endif + /* Define the complex type corresponding to __float128 + ("_Complex __float128" is not allowed) */ + #if (!defined(_ARCH_PPC)) || defined(__LONG_DOUBLE_IEEE128__) +diff -Nurp a/libquadmath/quadmath.h b/libquadmath/quadmath.h +--- a/libquadmath/quadmath.h 2015-08-09 16:46:52.541904000 +0800 ++++ b/libquadmath/quadmath.h 2019-08-17 18:25:51.923399149 +0800 +@@ -154,10 +154,9 @@ extern int quadmath_snprintf (char *str, + #define FLT128_MAX_10_EXP 4932 + + +-#define HUGE_VALQ __builtin_huge_valq() + /* The following alternative is valid, but brings the warning: + (floating constant exceeds range of ‘__float128’) */ +-/* #define HUGE_VALQ (__extension__ 0x1.0p32767Q) */ ++ #define HUGE_VALQ (__extension__ 0x1.0p32767Q) + + #define M_Eq 2.718281828459045235360287471352662498Q /* e */ + #define M_LOG2Eq 1.442695040888963407359924681001892137Q /* log_2 e */ + diff --git a/fix-ICE-during-pass-ccp.patch b/fix-ICE-during-pass-ccp.patch new file mode 100644 index 0000000000000000000000000000000000000000..67d332def5f79b7ce5392f3bf706f8483c41b2e5 --- /dev/null +++ b/fix-ICE-during-pass-ccp.patch @@ -0,0 +1,32 @@ +diff -uprN a/gcc/testsuite/gcc.dg/pr94574.c b/gcc/testsuite/gcc.dg/pr94574.c +--- a/gcc/testsuite/gcc.dg/pr94574.c 1970-01-01 00:00:00.000000000 +0000 ++++ b/gcc/testsuite/gcc.dg/pr94574.c 2020-04-15 21:08:48.972000000 +0000 +@@ -0,0 +1,15 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2" } */ ++ ++typedef unsigned int v4si __attribute__((vector_size(16))); ++typedef unsigned int v2si __attribute__((vector_size(8))); ++ ++/* The aliasing is somewhat dubious here, but it must compile. */ ++ ++v2si ++foo (v4si v) ++{ ++ v2si res; ++ *(v4si *) &res = v; ++ return res; ++} +diff -uprN a/gcc/tree-ssa.c b/gcc/tree-ssa.c +--- a/gcc/tree-ssa.c 2020-03-31 01:51:30.000000000 +0000 ++++ b/gcc/tree-ssa.c 2020-04-15 21:26:09.828000000 +0000 +@@ -1528,7 +1528,9 @@ non_rewritable_lvalue_p (tree lhs) + && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))), + mem_ref_offset (lhs)) + && multiple_of_p (sizetype, TREE_OPERAND (lhs, 1), +- TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) ++ TYPE_SIZE_UNIT (TREE_TYPE (lhs))) ++ && known_ge (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (decl))), ++ wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (lhs))))) + return false; + } diff --git a/fix-ICE-in-vectorizable-load.patch b/fix-ICE-in-vectorizable-load.patch new file mode 100644 index 0000000000000000000000000000000000000000..690ce6c7e74ee71b345aee9873daa4bc36336b2e --- /dev/null +++ b/fix-ICE-in-vectorizable-load.patch @@ -0,0 +1,65 @@ +diff -Nurp a/gcc/testsuite/gcc.target/aarch64/pr94398.c b/gcc/testsuite/gcc.target/aarch64/pr94398.c +--- a/gcc/testsuite/gcc.target/aarch64/pr94398.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/gcc/testsuite/gcc.target/aarch64/pr94398.c 2020-04-17 17:15:58.176000000 +0800 +@@ -0,0 +1,24 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -ftree-loop-vectorize -funsafe-math-optimizations -march=armv8.2-a+sve -mstrict-align" } */ ++ ++float ++foo(long n, float *x, int inc_x, ++ float *y, int inc_y) ++{ ++ float dot = 0.0; ++ int ix = 0, iy = 0; ++ ++ if (n < 0) { ++ return dot; ++ } ++ ++ int i = 0; ++ while (i < n) { ++ dot += y[iy] * x[ix]; ++ ix += inc_x; ++ iy += inc_y; ++ i++; ++ } ++ ++ return dot; ++} +diff -Nurp a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c +--- a/gcc/tree-vect-stmts.c 2020-04-17 17:10:14.796000000 +0800 ++++ b/gcc/tree-vect-stmts.c 2020-04-17 17:15:08.611850850 +0800 +@@ -7025,8 +7025,14 @@ vectorizable_store (stmt_vec_info stmt_i + auto_vec dr_chain (group_size); + oprnds.create (group_size); + +- alignment_support_scheme +- = vect_supportable_dr_alignment (first_dr_info, false); ++ /* Gather-scatter accesses perform only component accesses, alignment ++ is irrelevant for them. */ ++ if (memory_access_type == VMAT_GATHER_SCATTER) ++ alignment_support_scheme = dr_unaligned_supported; ++ else ++ alignment_support_scheme ++ = vect_supportable_dr_alignment (first_dr_info, false); ++ + gcc_assert (alignment_support_scheme); + vec_loop_masks *loop_masks + = (loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo) +@@ -8162,8 +8168,14 @@ vectorizable_load (stmt_vec_info stmt_in + ref_type = reference_alias_ptr_type (DR_REF (first_dr_info->dr)); + } + +- alignment_support_scheme +- = vect_supportable_dr_alignment (first_dr_info, false); ++ /* Gather-scatter accesses perform only component accesses, alignment ++ is irrelevant for them. */ ++ if (memory_access_type == VMAT_GATHER_SCATTER) ++ alignment_support_scheme = dr_unaligned_supported; ++ else ++ alignment_support_scheme ++ = vect_supportable_dr_alignment (first_dr_info, false); ++ + gcc_assert (alignment_support_scheme); + vec_loop_masks *loop_masks + = (loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo) diff --git a/fix-SYMBOL_TINY_GOT-handling-for-ILP32.patch b/fix-SYMBOL_TINY_GOT-handling-for-ILP32.patch new file mode 100644 index 0000000000000000000000000000000000000000..fccdea503b5f3c14c9778d77570a061365e64ffc --- /dev/null +++ b/fix-SYMBOL_TINY_GOT-handling-for-ILP32.patch @@ -0,0 +1,81 @@ +diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c +index b0cbb6e2d55..58d38f74bde 100644 +--- a/gcc/config/aarch64/aarch64.c ++++ b/gcc/config/aarch64/aarch64.c +@@ -2739,8 +2739,21 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm, + } + + case SYMBOL_TINY_GOT: +- emit_insn (gen_ldr_got_tiny (dest, imm)); +- return; ++ { ++ rtx insn; ++ machine_mode mode = GET_MODE (dest); ++ ++ if (mode == ptr_mode) ++ insn = gen_ldr_got_tiny (mode, dest, imm); ++ else ++ { ++ gcc_assert (mode == Pmode); ++ insn = gen_ldr_got_tiny_sidi (dest, imm); ++ } ++ ++ emit_insn (insn); ++ return; ++ } + + case SYMBOL_TINY_TLSIE: + { +diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md +index 7ad4e918578..c7c4d1dd519 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -6766,13 +6766,23 @@ + [(set_attr "type" "load_4")] + ) + +-(define_insn "ldr_got_tiny" +- [(set (match_operand:DI 0 "register_operand" "=r") +- (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] +- UNSPEC_GOTTINYPIC))] ++(define_insn "@ldr_got_tiny_" ++ [(set (match_operand:PTR 0 "register_operand" "=r") ++ (unspec:PTR [(match_operand:PTR 1 "aarch64_valid_symref" "S")] ++ UNSPEC_GOTTINYPIC))] + "" +- "ldr\\t%0, %L1" +- [(set_attr "type" "load_8")] ++ "ldr\t%0, %L1" ++ [(set_attr "type" "load_")] ++) ++ ++(define_insn "ldr_got_tiny_sidi" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (zero_extend:DI ++ (unspec:SI [(match_operand:DI 1 "aarch64_valid_symref" "S")] ++ UNSPEC_GOTTINYPIC)))] ++ "TARGET_ILP32" ++ "ldr\t%w0, %L1" ++ [(set_attr "type" "load_4")] + ) + + (define_insn "aarch64_load_tp_hard" +diff --git a/gcc/testsuite/gcc.target/aarch64/pr94201.c b/gcc/testsuite/gcc.target/aarch64/pr94201.c +new file mode 100644 +index 00000000000..69176169186 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/pr94201.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcmodel=tiny -mabi=ilp32 -fPIC" } */ ++ ++extern int bar (void *); ++extern long long a; ++ ++int ++foo (void) ++{ ++ a = 1; ++ return bar ((void *)bar); ++} ++ diff --git a/fix-cost-of-plus.patch b/fix-cost-of-plus.patch new file mode 100644 index 0000000000000000000000000000000000000000..7a34072bf1143ca90149bcdd24fb7790d526b46e --- /dev/null +++ b/fix-cost-of-plus.patch @@ -0,0 +1,13 @@ +diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c +index 56a4a47db73..71d44de1d0a 100644 +--- a/gcc/config/aarch64/aarch64.c ++++ b/gcc/config/aarch64/aarch64.c +@@ -10753,7 +10753,7 @@ cost_plus: + } + + if (GET_MODE_CLASS (mode) == MODE_INT +- && ((CONST_INT_P (op1) && aarch64_uimm12_shift (INTVAL (op1))) ++ && (aarch64_plus_immediate (op1, mode) + || aarch64_sve_addvl_addpl_immediate (op1, mode))) + { + *cost += rtx_cost (op0, mode, PLUS, 0, speed); diff --git a/fix-operand-size-mismatch-for-i386-sse.patch b/fix-operand-size-mismatch-for-i386-sse.patch deleted file mode 100644 index 90e526be842bbb5aacb6dd6bd82450034421120e..0000000000000000000000000000000000000000 --- a/fix-operand-size-mismatch-for-i386-sse.patch +++ /dev/null @@ -1,155 +0,0 @@ -diff -N -urp a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md ---- a/gcc/config/i386/sse.md 2019-10-30 10:02:45.894920908 +0800 -+++ b/gcc/config/i386/sse.md 2019-10-30 10:17:39.682887612 +0800 -@@ -16012,9 +16012,11 @@ - switch (INTVAL (operands[4])) - { - case 3: -- return "vgatherpf0ps\t{%5%{%0%}|%5%{%0%}}"; -+ /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+ gas changed what it requires incompatibly. */ -+ return "vgatherpf0ps\t{%5%{%0%}|%X5%{%0%}}"; - case 2: -- return "vgatherpf1ps\t{%5%{%0%}|%5%{%0%}}"; -+ return "vgatherpf1ps\t{%5%{%0%}|%X5%{%0%}}"; - default: - gcc_unreachable (); - } -@@ -16057,9 +16059,11 @@ - switch (INTVAL (operands[4])) - { - case 3: -- return "vgatherpf0pd\t{%5%{%0%}|%5%{%0%}}"; -+ /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+ gas changed what it requires incompatibly. */ -+ return "vgatherpf0pd\t{%5%{%0%}|%X5%{%0%}}"; - case 2: -- return "vgatherpf1pd\t{%5%{%0%}|%5%{%0%}}"; -+ return "vgatherpf1pd\t{%5%{%0%}|%X5%{%0%}}"; - default: - gcc_unreachable (); - } -@@ -16103,10 +16107,12 @@ - { - case 3: - case 7: -- return "vscatterpf0ps\t{%5%{%0%}|%5%{%0%}}"; -+ /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+ gas changed what it requires incompatibly. */ -+ return "vscatterpf0ps\t{%5%{%0%}|%X5%{%0%}}"; - case 2: - case 6: -- return "vscatterpf1ps\t{%5%{%0%}|%5%{%0%}}"; -+ return "vscatterpf1ps\t{%5%{%0%}|%X5%{%0%}}"; - default: - gcc_unreachable (); - } -@@ -16150,10 +16156,12 @@ - { - case 3: - case 7: -- return "vscatterpf0pd\t{%5%{%0%}|%5%{%0%}}"; -+ /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+ gas changed what it requires incompatibly. */ -+ return "vscatterpf0pd\t{%5%{%0%}|%X5%{%0%}}"; - case 2: - case 6: -- return "vscatterpf1pd\t{%5%{%0%}|%5%{%0%}}"; -+ return "vscatterpf1pd\t{%5%{%0%}|%X5%{%0%}}"; - default: - gcc_unreachable (); - } -@@ -19153,12 +19161,6 @@ - (set_attr "prefix" "vex") - (set_attr "mode" "")]) - --;; Memory operand override for -masm=intel of the v*gatherq* patterns. --(define_mode_attr gatherq_mode -- [(V4SI "q") (V2DI "x") (V4SF "q") (V2DF "x") -- (V8SI "x") (V4DI "t") (V8SF "x") (V4DF "t") -- (V16SI "t") (V8DI "g") (V16SF "t") (V8DF "g")]) -- - (define_expand "_gathersi" - [(parallel [(set (match_operand:VI48F 0 "register_operand") - (unspec:VI48F -@@ -19192,7 +19194,9 @@ - UNSPEC_GATHER)) - (clobber (match_scratch: 2 "=&Yk"))] - "TARGET_AVX512F" -- "vgatherd\t{%6, %0%{%2%}|%0%{%2%}, %6}" -+;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as -+;; gas changed what it requires incompatibly. -+ "vgatherd\t{%6, %0%{%2%}|%0%{%2%}, %X6}" - [(set_attr "type" "ssemov") - (set_attr "prefix" "evex") - (set_attr "mode" "")]) -@@ -19211,7 +19215,9 @@ - UNSPEC_GATHER)) - (clobber (match_scratch: 1 "=&Yk"))] - "TARGET_AVX512F" -- "vgatherd\t{%5, %0%{%1%}|%0%{%1%}, %5}" -+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+;; gas changed what it requires incompatibly. -+ "vgatherd\t{%5, %0%{%1%}|%0%{%1%}, %X5}" - [(set_attr "type" "ssemov") - (set_attr "prefix" "evex") - (set_attr "mode" "")]) -@@ -19250,9 +19256,9 @@ - UNSPEC_GATHER)) - (clobber (match_scratch:QI 2 "=&Yk"))] - "TARGET_AVX512F" --{ -- return "vgatherq\t{%6, %1%{%2%}|%1%{%2%}, %6}"; --} -+;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as -+;; gas changed what it requires incompatibly. -+ "vgatherq\t{%6, %1%{%2%}|%1%{%2%}, %X6}" - [(set_attr "type" "ssemov") - (set_attr "prefix" "evex") - (set_attr "mode" "")]) -@@ -19272,14 +19278,16 @@ - (clobber (match_scratch:QI 1 "=&Yk"))] - "TARGET_AVX512F" - { -+ /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+ gas changed what it requires incompatibly. */ - if (mode != mode) - { - if ( != 64) -- return "vgatherq\t{%5, %x0%{%1%}|%x0%{%1%}, %5}"; -+ return "vgatherq\t{%5, %x0%{%1%}|%x0%{%1%}, %X5}"; - else -- return "vgatherq\t{%5, %t0%{%1%}|%t0%{%1%}, %t5}"; -+ return "vgatherq\t{%5, %t0%{%1%}|%t0%{%1%}, %X5}"; - } -- return "vgatherq\t{%5, %0%{%1%}|%0%{%1%}, %5}"; -+ return "vgatherq\t{%5, %0%{%1%}|%0%{%1%}, %X5}"; - } - [(set_attr "type" "ssemov") - (set_attr "prefix" "evex") -@@ -19316,7 +19324,9 @@ - UNSPEC_SCATTER)) - (clobber (match_scratch: 1 "=&Yk"))] - "TARGET_AVX512F" -- "vscatterd\t{%3, %5%{%1%}|%5%{%1%}, %3}" -+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+;; gas changed what it requires incompatibly. -+ "vscatterd\t{%3, %5%{%1%}|%X5%{%1%}, %3}" - [(set_attr "type" "ssemov") - (set_attr "prefix" "evex") - (set_attr "mode" "")]) -@@ -19352,11 +19362,9 @@ - UNSPEC_SCATTER)) - (clobber (match_scratch:QI 1 "=&Yk"))] - "TARGET_AVX512F" --{ -- if (GET_MODE_SIZE (GET_MODE_INNER (mode)) == 8) -- return "vscatterq\t{%3, %5%{%1%}|%5%{%1%}, %3}"; -- return "vscatterq\t{%3, %5%{%1%}|%t5%{%1%}, %3}"; --} -+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as -+;; gas changed what it requires incompatibly. -+ "vscatterq\t{%3, %5%{%1%}|%X5%{%1%}, %3}" - [(set_attr "type" "ssemov") - (set_attr "prefix" "evex") - (set_attr "mode" "")]) diff --git a/fix-regno-out-of-range.patch b/fix-regno-out-of-range.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa8aaa5650a528a6a2d3c0ba97708f5481c29b9b --- /dev/null +++ b/fix-regno-out-of-range.patch @@ -0,0 +1,12 @@ +diff -Nurp a/gcc/lra-assigns.c b/gcc/lra-assigns.c +--- a/gcc/lra-assigns.c 2020-04-17 16:27:46.192000000 +0800 ++++ b/gcc/lra-assigns.c 2020-04-17 16:29:37.125688580 +0800 +@@ -968,6 +968,8 @@ spill_for (int regno, bitmap spilled_pse + bitmap_clear (&spill_pseudos_bitmap); + for (j = hard_regno_nregs (hard_regno, mode) - 1; j >= 0; j--) + { ++ if (hard_regno + j >= FIRST_PSEUDO_REGISTER) ++ break; + if (try_hard_reg_pseudos_check[hard_regno + j] != curr_pseudo_check) + continue; + lra_assert (!bitmap_empty_p (&try_hard_reg_pseudos[hard_regno + j])); diff --git a/floop-interchange.patch b/floop-interchange.patch deleted file mode 100644 index 6657eede161b6f1f3bdfe001e2e69ee70b15cb3d..0000000000000000000000000000000000000000 --- a/floop-interchange.patch +++ /dev/null @@ -1,2680 +0,0 @@ -diff -N -urp a/gcc/Makefile.in b/gcc/Makefile.in ---- a/gcc/Makefile.in 2018-11-15 15:59:30.435048460 +0800 -+++ b/gcc/Makefile.in 2018-11-15 16:04:16.735055997 +0800 -@@ -1293,6 +1293,7 @@ OBJS = \ - gimple-fold.o \ - gimple-laddress.o \ - gimple-loop-jam.o \ -+ gimple-loop-interchange.o \ - gimple-low.o \ - gimple-pretty-print.o \ - gimple-ssa-backprop.o \ -diff -N -urp a/gcc/cfgloop.h b/gcc/cfgloop.h ---- a/gcc/cfgloop.h 2018-11-15 15:59:30.439048461 +0800 -+++ b/gcc/cfgloop.h 2018-11-15 16:03:17.431054436 +0800 -@@ -225,6 +225,16 @@ struct GTY ((chain_next ("%h.next"))) lo - builtins. */ - tree simduid; - -+ /* In loop optimization, it's common to generate loops from the original -+ loop. This field records the index of the original loop which can be -+ used to track the original loop from newly generated loops. This can -+ be done by calling function get_loop (cfun, orig_loop_num). Note the -+ original loop could be destroyed for various reasons thus no longer -+ exists, as a result, function call to get_loop returns NULL pointer. -+ In this case, this field should not be used and needs to be cleared -+ whenever possible. */ -+ int orig_loop_num; -+ - /* Upper bound on number of iterations of a loop. */ - struct nb_iter_bound *bounds; - -diff -N -urp a/gcc/common.opt b/gcc/common.opt ---- a/gcc/common.opt 2018-11-15 15:59:30.447048461 +0800 -+++ b/gcc/common.opt 2018-11-15 16:03:17.431054436 +0800 -@@ -1488,8 +1488,8 @@ Common Alias(floop-nest-optimize) - Enable loop nest transforms. Same as -floop-nest-optimize. - - floop-interchange --Common Alias(floop-nest-optimize) --Enable loop nest transforms. Same as -floop-nest-optimize. -+Common Report Var(flag_loop_interchange) Optimization -+Enable loop interchange on trees. - - floop-block - Common Alias(floop-nest-optimize) -diff -N -urp a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi ---- a/gcc/doc/invoke.texi 2018-11-15 15:59:30.451048461 +0800 -+++ b/gcc/doc/invoke.texi 2018-11-15 16:05:06.803057315 +0800 -@@ -8224,11 +8224,9 @@ Perform loop optimizations on trees. Th - at @option{-O} and higher. - - @item -ftree-loop-linear --@itemx -floop-interchange - @itemx -floop-strip-mine - @itemx -floop-block - @opindex ftree-loop-linear --@opindex floop-interchange - @opindex floop-strip-mine - @opindex floop-block - Perform loop nest optimizations. Same as -@@ -8328,6 +8326,25 @@ Apply unroll and jam transformations on - nest this unrolls the outer loop by some factor and fuses the resulting - multiple inner loops. This flag is enabled by default at @option{-O3}. - -+@item -floop-interchange -+@opindex floop-interchange -+Perform loop interchange outside of graphite. This flag can improve cache -+performance on loop nest and allow further loop optimizations, like -+vectorization, to take place. For example, the loop -+@smallexample -+for (int i = 0; i < N; i++) -+ for (int j = 0; j < N; j++) -+ for (int k = 0; k < N; k++) -+ c[i][j] = c[i][j] + a[i][k]*b[k][j]; -+@end smallexample -+is transformed to -+@smallexample -+for (int i = 0; i < N; i++) -+ for (int k = 0; k < N; k++) -+ for (int j = 0; j < N; j++) -+ c[i][j] = c[i][j] + a[i][k]*b[k][j]; -+@end smallexample -+ - @item -ftree-loop-im - @opindex ftree-loop-im - Perform loop invariant motion on trees. This pass moves only invariants that -@@ -10203,6 +10220,12 @@ The size of L1 cache, in kilobytes. - @item l2-cache-size - The size of L2 cache, in kilobytes. - -+@item loop-interchange-max-num-stmts -+The maximum number of stmts in a loop to be interchanged. -+ -+@item loop-interchange-stride-ratio -+The minimum ratio between stride of two loops for interchange to be profitable. -+ - @item min-insn-to-prefetch-ratio - The minimum ratio between the number of instructions and the - number of prefetches to enable prefetching in a loop. -diff -N -urp a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc ---- a/gcc/gimple-loop-interchange.cc 1970-01-01 08:00:00.000000000 +0800 -+++ b/gcc/gimple-loop-interchange.cc 2018-11-15 16:03:17.443054436 +0800 -@@ -0,0 +1,2039 @@ -+/* Loop interchange. -+ Copyright (C) 2017 Free Software Foundation, Inc. -+ Contributed by ARM Ltd. -+ -+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 -+. */ -+ -+#include "config.h" -+#include "system.h" -+#include "coretypes.h" -+#include "backend.h" -+#include "is-a.h" -+#include "tree.h" -+#include "gimple.h" -+#include "tree-pass.h" -+#include "ssa.h" -+#include "gimple-pretty-print.h" -+#include "fold-const.h" -+#include "gimplify.h" -+#include "gimple-iterator.h" -+#include "gimplify-me.h" -+#include "cfgloop.h" -+#include "params.h" -+#include "tree-ssa.h" -+#include "tree-scalar-evolution.h" -+#include "tree-ssa-loop-manip.h" -+#include "tree-ssa-loop-niter.h" -+#include "tree-ssa-loop-ivopts.h" -+#include "tree-ssa-dce.h" -+#include "tree-data-ref.h" -+#include "tree-vectorizer.h" -+ -+/* This pass performs loop interchange: for example, the loop nest -+ -+ for (int j = 0; j < N; j++) -+ for (int k = 0; k < N; k++) -+ for (int i = 0; i < N; i++) -+ c[i][j] = c[i][j] + a[i][k]*b[k][j]; -+ -+ is transformed to -+ -+ for (int i = 0; i < N; i++) -+ for (int j = 0; j < N; j++) -+ for (int k = 0; k < N; k++) -+ c[i][j] = c[i][j] + a[i][k]*b[k][j]; -+ -+ This pass implements loop interchange in the following steps: -+ -+ 1) Find perfect loop nest for each innermost loop and compute data -+ dependence relations for it. For above example, loop nest is -+ . -+ 2) From innermost to outermost loop, this pass tries to interchange -+ each loop pair. For above case, it firstly tries to interchange -+ and loop nest becomes . -+ Then it tries to interchange and loop nest becomes -+ . The overall effect is to move innermost -+ loop to the outermost position. For loop pair -+ to be interchanged, we: -+ 3) Check if data dependence relations are valid for loop interchange. -+ 4) Check if both loops can be interchanged in terms of transformation. -+ 5) Check if interchanging the two loops is profitable. -+ 6) Interchange the two loops by mapping induction variables. -+ -+ This pass also handles reductions in loop nest. So far we only support -+ simple reduction of inner loop and double reduction of the loop nest. */ -+ -+/* Maximum number of stmts in each loop that should be interchanged. */ -+#define MAX_NUM_STMT (PARAM_VALUE (PARAM_LOOP_INTERCHANGE_MAX_NUM_STMTS)) -+/* Maximum number of data references in loop nest. */ -+#define MAX_DATAREFS (PARAM_VALUE (PARAM_LOOP_MAX_DATAREFS_FOR_DATADEPS)) -+ -+/* Comparison ratio of access stride between inner/outer loops to be -+ interchanged. This is the minimum stride ratio for loop interchange -+ to be profitable. */ -+#define OUTER_STRIDE_RATIO (PARAM_VALUE (PARAM_LOOP_INTERCHANGE_STRIDE_RATIO)) -+/* The same as above, but we require higher ratio for interchanging the -+ innermost two loops. */ -+#define INNER_STRIDE_RATIO ((OUTER_STRIDE_RATIO) + 1) -+ -+/* Vector of strides that DR accesses in each level loop of a loop nest. */ -+#define DR_ACCESS_STRIDE(dr) ((vec *) dr->aux) -+ -+/* Structure recording loop induction variable. */ -+typedef struct induction -+{ -+ /* IV itself. */ -+ tree var; -+ /* IV's initializing value, which is the init arg of the IV PHI node. */ -+ tree init_val; -+ /* IV's initializing expr, which is (the expanded result of) init_val. */ -+ tree init_expr; -+ /* IV's step. */ -+ tree step; -+} *induction_p; -+ -+/* Enum type for loop reduction variable. */ -+enum reduction_type -+{ -+ UNKNOWN_RTYPE = 0, -+ SIMPLE_RTYPE, -+ DOUBLE_RTYPE -+}; -+ -+/* Structure recording loop reduction variable. */ -+typedef struct reduction -+{ -+ /* Reduction itself. */ -+ tree var; -+ /* PHI node defining reduction variable. */ -+ gphi *phi; -+ /* Init and next variables of the reduction. */ -+ tree init; -+ tree next; -+ /* Lcssa PHI node if reduction is used outside of its definition loop. */ -+ gphi *lcssa_phi; -+ /* Stmts defining init and next. */ -+ gimple *producer; -+ gimple *consumer; -+ /* If init is loaded from memory, this is the loading memory reference. */ -+ tree init_ref; -+ /* If reduction is finally stored to memory, this is the stored memory -+ reference. */ -+ tree fini_ref; -+ enum reduction_type type; -+} *reduction_p; -+ -+ -+/* Dump reduction RE. */ -+ -+static void -+dump_reduction (reduction_p re) -+{ -+ if (re->type == SIMPLE_RTYPE) -+ fprintf (dump_file, " Simple reduction: "); -+ else if (re->type == DOUBLE_RTYPE) -+ fprintf (dump_file, " Double reduction: "); -+ else -+ fprintf (dump_file, " Unknown reduction: "); -+ -+ print_gimple_stmt (dump_file, re->phi, 0); -+} -+ -+/* Dump LOOP's induction IV. */ -+static void -+dump_induction (struct loop *loop, induction_p iv) -+{ -+ fprintf (dump_file, " Induction: "); -+ print_generic_expr (dump_file, iv->var, TDF_SLIM); -+ fprintf (dump_file, " = {"); -+ print_generic_expr (dump_file, iv->init_expr, TDF_SLIM); -+ fprintf (dump_file, ", "); -+ print_generic_expr (dump_file, iv->step, TDF_SLIM); -+ fprintf (dump_file, "}_%d\n", loop->num); -+} -+ -+/* Loop candidate for interchange. */ -+ -+struct loop_cand -+{ -+ loop_cand (struct loop *, struct loop *); -+ ~loop_cand (); -+ -+ reduction_p find_reduction_by_stmt (gimple *); -+ void classify_simple_reduction (reduction_p); -+ bool analyze_iloop_reduction_var (tree); -+ bool analyze_oloop_reduction_var (loop_cand *, tree); -+ bool analyze_induction_var (tree, tree); -+ bool analyze_carried_vars (loop_cand *); -+ bool analyze_lcssa_phis (void); -+ bool can_interchange_p (loop_cand *); -+ bool supported_operations (basic_block, loop_cand *, int *); -+ void undo_simple_reduction (reduction_p, bitmap); -+ -+ /* The loop itself. */ -+ struct loop *m_loop; -+ /* The outer loop for interchange. It equals to loop if this loop cand -+ itself represents the outer loop. */ -+ struct loop *m_outer; -+ /* Vector of induction variables in loop. */ -+ vec m_inductions; -+ /* Vector of reduction variables in loop. */ -+ vec m_reductions; -+ /* Lcssa PHI nodes of this loop. */ -+ vec m_lcssa_nodes; -+ /* Single exit edge of this loop. */ -+ edge m_exit; -+ /* Basic blocks of this loop. */ -+ basic_block *m_bbs; -+}; -+ -+/* Constructor. */ -+ -+loop_cand::loop_cand (struct loop *loop, struct loop *outer) -+ : m_loop (loop), m_outer (outer), -+ m_exit (single_exit (loop)), m_bbs (get_loop_body (loop)) -+{ -+ m_inductions.create (3); -+ m_reductions.create (3); -+ m_lcssa_nodes.create (3); -+} -+ -+/* Destructor. */ -+ -+loop_cand::~loop_cand () -+{ -+ induction_p iv; -+ for (unsigned i = 0; m_inductions.iterate (i, &iv); ++i) -+ free (iv); -+ -+ reduction_p re; -+ for (unsigned i = 0; m_reductions.iterate (i, &re); ++i) -+ free (re); -+ -+ m_inductions.release (); -+ m_reductions.release (); -+ m_lcssa_nodes.release (); -+ free (m_bbs); -+} -+ -+/* Return single use stmt of VAR in LOOP, otherwise return NULL. */ -+ -+static gimple * -+single_use_in_loop (tree var, struct loop *loop) -+{ -+ gimple *stmt, *res = NULL; -+ use_operand_p use_p; -+ imm_use_iterator iterator; -+ -+ FOR_EACH_IMM_USE_FAST (use_p, iterator, var) -+ { -+ stmt = USE_STMT (use_p); -+ if (is_gimple_debug (stmt)) -+ continue; -+ -+ if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt))) -+ continue; -+ -+ if (res) -+ return NULL; -+ -+ res = stmt; -+ } -+ return res; -+} -+ -+/* Return true if E is unsupported in loop interchange, i.e, E is a complex -+ edge or part of irreducible loop. */ -+ -+static inline bool -+unsupported_edge (edge e) -+{ -+ return (e->flags & (EDGE_COMPLEX | EDGE_IRREDUCIBLE_LOOP)); -+} -+ -+/* Return the reduction if STMT is one of its lcssa PHI, producer or consumer -+ stmt. */ -+ -+reduction_p -+loop_cand::find_reduction_by_stmt (gimple *stmt) -+{ -+ gphi *phi = dyn_cast (stmt); -+ reduction_p re; -+ -+ for (unsigned i = 0; m_reductions.iterate (i, &re); ++i) -+ if ((phi != NULL && phi == re->lcssa_phi) -+ || (stmt == re->producer || stmt == re->consumer)) -+ return re; -+ -+ return NULL; -+} -+ -+/* Return true if all stmts in BB can be supported by loop interchange, -+ otherwise return false. ILOOP is not NULL if this loop_cand is the -+ outer loop in loop nest. Add the number of supported statements to -+ NUM_STMTS. */ -+ -+bool -+loop_cand::supported_operations (basic_block bb, loop_cand *iloop, -+ int *num_stmts) -+{ -+ int bb_num_stmts = 0; -+ gphi_iterator psi; -+ gimple_stmt_iterator gsi; -+ -+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) -+ { -+ gimple *stmt = gsi_stmt (gsi); -+ if (is_gimple_debug (stmt)) -+ continue; -+ -+ if (gimple_has_side_effects (stmt)) -+ return false; -+ -+ bb_num_stmts++; -+ if (gcall *call = dyn_cast (stmt)) -+ { -+ /* In basic block of outer loop, the call should be cheap since -+ it will be moved to inner loop. */ -+ if (iloop != NULL -+ && !gimple_inexpensive_call_p (call)) -+ return false; -+ continue; -+ } -+ -+ if (!iloop || !gimple_vuse (stmt)) -+ continue; -+ -+ /* Support stmt accessing memory in outer loop only if it is for inner -+ loop's reduction. */ -+ if (iloop->find_reduction_by_stmt (stmt)) -+ continue; -+ -+ tree lhs; -+ /* Support loop invariant memory reference if it's only used once by -+ inner loop. */ -+ /* ??? How's this checking for invariantness? */ -+ if (gimple_assign_single_p (stmt) -+ && (lhs = gimple_assign_lhs (stmt)) != NULL_TREE -+ && TREE_CODE (lhs) == SSA_NAME -+ && single_use_in_loop (lhs, iloop->m_loop)) -+ continue; -+ -+ return false; -+ } -+ *num_stmts += bb_num_stmts; -+ -+ /* Allow PHI nodes in any basic block of inner loop, PHI nodes in outer -+ loop's header, or PHI nodes in dest bb of inner loop's exit edge. */ -+ if (!iloop || bb == m_loop->header -+ || bb == iloop->m_exit->dest) -+ return true; -+ -+ /* Don't allow any other PHI nodes. */ -+ for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi)) -+ if (!virtual_operand_p (PHI_RESULT (psi.phi ()))) -+ return false; -+ -+ return true; -+} -+ -+/* Return true if current loop_cand be interchanged. ILOOP is not NULL if -+ current loop_cand is outer loop in loop nest. */ -+ -+bool -+loop_cand::can_interchange_p (loop_cand *iloop) -+{ -+ /* For now we only support at most one reduction. */ -+ unsigned allowed_reduction_num = 1; -+ -+ /* Only support reduction if the loop nest to be interchanged is the -+ innermostin two loops. */ -+ if ((iloop == NULL && m_loop->inner != NULL) -+ || (iloop != NULL && iloop->m_loop->inner != NULL)) -+ allowed_reduction_num = 0; -+ -+ if (m_reductions.length () > allowed_reduction_num -+ || (m_reductions.length () == 1 -+ && m_reductions[0]->type == UNKNOWN_RTYPE)) -+ return false; -+ -+ /* Only support lcssa PHI node which is for reduction. */ -+ if (m_lcssa_nodes.length () > allowed_reduction_num) -+ return false; -+ -+ int num_stmts = 0; -+ /* Check basic blocks other than loop header/exit. */ -+ for (unsigned i = 0; i < m_loop->num_nodes; i++) -+ { -+ basic_block bb = m_bbs[i]; -+ -+ /* Skip basic blocks of inner loops. */ -+ if (bb->loop_father != m_loop) -+ continue; -+ -+ /* Check if basic block has any unsupported operation. */ -+ if (!supported_operations (bb, iloop, &num_stmts)) -+ return false; -+ -+ /* Check if loop has too many stmts. */ -+ if (num_stmts > MAX_NUM_STMT) -+ return false; -+ } -+ -+ return true; -+} -+ -+/* Programmers and optimizers (like loop store motion) may optimize code: -+ -+ for (int i = 0; i < N; i++) -+ for (int j = 0; j < N; j++) -+ a[i] += b[j][i] * c[j][i]; -+ -+ into reduction: -+ -+ for (int i = 0; i < N; i++) -+ { -+ // producer. Note sum can be intitialized to a constant. -+ int sum = a[i]; -+ for (int j = 0; j < N; j++) -+ { -+ sum += b[j][i] * c[j][i]; -+ } -+ // consumer. -+ a[i] = sum; -+ } -+ -+ The result code can't be interchanged without undoing the optimization. -+ This function classifies this kind reduction and records information so -+ that we can undo the store motion during interchange. */ -+ -+void -+loop_cand::classify_simple_reduction (reduction_p re) -+{ -+ gimple *producer, *consumer; -+ -+ /* Check init variable of reduction and how it is initialized. */ -+ if (TREE_CODE (re->init) == SSA_NAME) -+ { -+ producer = SSA_NAME_DEF_STMT (re->init); -+ re->producer = producer; -+ basic_block bb = gimple_bb (producer); -+ if (!bb || bb->loop_father != m_outer) -+ return; -+ -+ if (!gimple_assign_load_p (producer)) -+ return; -+ -+ re->init_ref = gimple_assign_rhs1 (producer); -+ } -+ else if (!CONSTANT_CLASS_P (re->init)) -+ return; -+ -+ /* Check how reduction variable is used. */ -+ consumer = single_use_in_loop (PHI_RESULT (re->lcssa_phi), m_outer); -+ if (!consumer -+ || !gimple_store_p (consumer)) -+ return; -+ -+ re->fini_ref = gimple_get_lhs (consumer); -+ re->consumer = consumer; -+ -+ /* Simple reduction with constant initializer. */ -+ if (!re->init_ref) -+ { -+ gcc_assert (CONSTANT_CLASS_P (re->init)); -+ re->init_ref = unshare_expr (re->fini_ref); -+ } -+ -+ /* Require memory references in producer and consumer are the same so -+ that we can undo reduction during interchange. */ -+ if (re->init_ref && !operand_equal_p (re->init_ref, re->fini_ref, 0)) -+ return; -+ -+ re->type = SIMPLE_RTYPE; -+} -+ -+/* Analyze reduction variable VAR for inner loop of the loop nest to be -+ interchanged. Return true if analysis succeeds. */ -+ -+bool -+loop_cand::analyze_iloop_reduction_var (tree var) -+{ -+ gphi *phi = as_a (SSA_NAME_DEF_STMT (var)); -+ gphi *lcssa_phi = NULL, *use_phi; -+ tree init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (m_loop)); -+ tree next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (m_loop)); -+ reduction_p re; -+ gimple *stmt, *next_def, *single_use = NULL; -+ use_operand_p use_p; -+ imm_use_iterator iterator; -+ -+ if (TREE_CODE (next) != SSA_NAME) -+ return false; -+ -+ next_def = SSA_NAME_DEF_STMT (next); -+ basic_block bb = gimple_bb (next_def); -+ if (!bb || !flow_bb_inside_loop_p (m_loop, bb)) -+ return false; -+ -+ /* In restricted reduction, the var is (and must be) used in defining -+ the updated var. The process can be depicted as below: -+ -+ var ;; = PHI -+ | -+ | -+ v -+ +---------------------+ -+ | reduction operators | <-- other operands -+ +---------------------+ -+ | -+ | -+ v -+ next -+ -+ In terms loop interchange, we don't change how NEXT is computed based -+ on VAR and OTHER OPERANDS. In case of double reduction in loop nest -+ to be interchanged, we don't changed it at all. In the case of simple -+ reduction in inner loop, we only make change how VAR/NEXT is loaded or -+ stored. With these conditions, we can relax restrictions on reduction -+ in a way that reduction operation is seen as black box. In general, -+ we can ignore reassociation of reduction operator; we can handle fake -+ reductions in which VAR is not even used to compute NEXT. */ -+ if (! single_imm_use (var, &use_p, &single_use) -+ || ! flow_bb_inside_loop_p (m_loop, gimple_bb (single_use))) -+ return false; -+ -+ /* Check the reduction operation. We require a left-associative operation. -+ For FP math we also need to be allowed to associate operations. */ -+ if (gassign *ass = dyn_cast (single_use)) -+ { -+ enum tree_code code = gimple_assign_rhs_code (ass); -+ if (! (associative_tree_code (code) -+ || (code == MINUS_EXPR -+ && use_p->use == gimple_assign_rhs1_ptr (ass))) -+ || (FLOAT_TYPE_P (TREE_TYPE (var)) -+ && ! flag_associative_math)) -+ return false; -+ } -+ else -+ return false; -+ -+ /* Handle and verify a series of stmts feeding the reduction op. */ -+ if (single_use != next_def -+ && !check_reduction_path (UNKNOWN_LOCATION, m_loop, phi, next, -+ gimple_assign_rhs_code (single_use))) -+ return false; -+ -+ /* Only support cases in which INIT is used in inner loop. */ -+ if (TREE_CODE (init) == SSA_NAME) -+ FOR_EACH_IMM_USE_FAST (use_p, iterator, init) -+ { -+ stmt = USE_STMT (use_p); -+ if (is_gimple_debug (stmt)) -+ continue; -+ -+ if (!flow_bb_inside_loop_p (m_loop, gimple_bb (stmt))) -+ return false; -+ } -+ -+ FOR_EACH_IMM_USE_FAST (use_p, iterator, next) -+ { -+ stmt = USE_STMT (use_p); -+ if (is_gimple_debug (stmt)) -+ continue; -+ -+ /* Or else it's used in PHI itself. */ -+ use_phi = dyn_cast (stmt); -+ if (use_phi == phi) -+ continue; -+ -+ if (use_phi != NULL -+ && lcssa_phi == NULL -+ && gimple_bb (stmt) == m_exit->dest -+ && PHI_ARG_DEF_FROM_EDGE (use_phi, m_exit) == next) -+ lcssa_phi = use_phi; -+ else -+ return false; -+ } -+ if (!lcssa_phi) -+ return false; -+ -+ re = XCNEW (struct reduction); -+ re->var = var; -+ re->init = init; -+ re->next = next; -+ re->phi = phi; -+ re->lcssa_phi = lcssa_phi; -+ -+ classify_simple_reduction (re); -+ -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ dump_reduction (re); -+ -+ m_reductions.safe_push (re); -+ return true; -+} -+ -+/* Analyze reduction variable VAR for outer loop of the loop nest to be -+ interchanged. ILOOP is not NULL and points to inner loop. For the -+ moment, we only support double reduction for outer loop, like: -+ -+ for (int i = 0; i < n; i++) -+ { -+ int sum = 0; -+ -+ for (int j = 0; j < n; j++) // outer loop -+ for (int k = 0; k < n; k++) // inner loop -+ sum += a[i][k]*b[k][j]; -+ -+ s[i] = sum; -+ } -+ -+ Note the innermost two loops are the loop nest to be interchanged. -+ Return true if analysis succeeds. */ -+ -+bool -+loop_cand::analyze_oloop_reduction_var (loop_cand *iloop, tree var) -+{ -+ gphi *phi = as_a (SSA_NAME_DEF_STMT (var)); -+ gphi *lcssa_phi = NULL, *use_phi; -+ tree init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (m_loop)); -+ tree next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (m_loop)); -+ reduction_p re; -+ gimple *stmt, *next_def; -+ use_operand_p use_p; -+ imm_use_iterator iterator; -+ -+ if (TREE_CODE (next) != SSA_NAME) -+ return false; -+ -+ next_def = SSA_NAME_DEF_STMT (next); -+ basic_block bb = gimple_bb (next_def); -+ if (!bb || !flow_bb_inside_loop_p (m_loop, bb)) -+ return false; -+ -+ /* Find inner loop's simple reduction that uses var as initializer. */ -+ reduction_p inner_re = NULL; -+ for (unsigned i = 0; iloop->m_reductions.iterate (i, &inner_re); ++i) -+ if (inner_re->init == var || operand_equal_p (inner_re->init, var, 0)) -+ break; -+ -+ if (inner_re == NULL -+ || inner_re->type != UNKNOWN_RTYPE -+ || inner_re->producer != phi) -+ return false; -+ -+ /* In case of double reduction, outer loop's reduction should be updated -+ by inner loop's simple reduction. */ -+ if (next_def != inner_re->lcssa_phi) -+ return false; -+ -+ /* Outer loop's reduction should only be used to initialize inner loop's -+ simple reduction. */ -+ if (! single_imm_use (var, &use_p, &stmt) -+ || stmt != inner_re->phi) -+ return false; -+ -+ /* Check this reduction is correctly used outside of loop via lcssa phi. */ -+ FOR_EACH_IMM_USE_FAST (use_p, iterator, next) -+ { -+ stmt = USE_STMT (use_p); -+ if (is_gimple_debug (stmt)) -+ continue; -+ -+ /* Or else it's used in PHI itself. */ -+ use_phi = dyn_cast (stmt); -+ if (use_phi == phi) -+ continue; -+ -+ if (lcssa_phi == NULL -+ && use_phi != NULL -+ && gimple_bb (stmt) == m_exit->dest -+ && PHI_ARG_DEF_FROM_EDGE (use_phi, m_exit) == next) -+ lcssa_phi = use_phi; -+ else -+ return false; -+ } -+ if (!lcssa_phi) -+ return false; -+ -+ re = XCNEW (struct reduction); -+ re->var = var; -+ re->init = init; -+ re->next = next; -+ re->phi = phi; -+ re->lcssa_phi = lcssa_phi; -+ re->type = DOUBLE_RTYPE; -+ inner_re->type = DOUBLE_RTYPE; -+ -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ dump_reduction (re); -+ -+ m_reductions.safe_push (re); -+ return true; -+} -+ -+/* Return true if VAR is induction variable of current loop whose scev is -+ specified by CHREC. */ -+ -+bool -+loop_cand::analyze_induction_var (tree var, tree chrec) -+{ -+ gphi *phi = as_a (SSA_NAME_DEF_STMT (var)); -+ tree init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (m_loop)); -+ -+ /* Var is loop invariant, though it's unlikely to happen. */ -+ if (tree_does_not_contain_chrecs (chrec)) -+ { -+ struct induction *iv = XCNEW (struct induction); -+ iv->var = var; -+ iv->init_val = init; -+ iv->init_expr = chrec; -+ iv->step = build_int_cst (TREE_TYPE (chrec), 0); -+ m_inductions.safe_push (iv); -+ return true; -+ } -+ -+ if (TREE_CODE (chrec) != POLYNOMIAL_CHREC -+ || CHREC_VARIABLE (chrec) != (unsigned) m_loop->num -+ || tree_contains_chrecs (CHREC_LEFT (chrec), NULL) -+ || tree_contains_chrecs (CHREC_RIGHT (chrec), NULL)) -+ return false; -+ -+ struct induction *iv = XCNEW (struct induction); -+ iv->var = var; -+ iv->init_val = init; -+ iv->init_expr = CHREC_LEFT (chrec); -+ iv->step = CHREC_RIGHT (chrec); -+ -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ dump_induction (m_loop, iv); -+ -+ m_inductions.safe_push (iv); -+ return true; -+} -+ -+/* Return true if all loop carried variables defined in loop header can -+ be successfully analyzed. */ -+ -+bool -+loop_cand::analyze_carried_vars (loop_cand *iloop) -+{ -+ edge e = loop_preheader_edge (m_outer); -+ gphi_iterator gsi; -+ -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ fprintf (dump_file, "\nLoop(%d) carried vars:\n", m_loop->num); -+ -+ for (gsi = gsi_start_phis (m_loop->header); !gsi_end_p (gsi); gsi_next (&gsi)) -+ { -+ gphi *phi = gsi.phi (); -+ -+ tree var = PHI_RESULT (phi); -+ if (virtual_operand_p (var)) -+ continue; -+ -+ tree chrec = analyze_scalar_evolution (m_loop, var); -+ chrec = instantiate_scev (e, m_loop, chrec); -+ -+ /* Analyze var as reduction variable. */ -+ if (chrec_contains_undetermined (chrec) -+ || chrec_contains_symbols_defined_in_loop (chrec, m_outer->num)) -+ { -+ if (iloop && !analyze_oloop_reduction_var (iloop, var)) -+ return false; -+ if (!iloop && !analyze_iloop_reduction_var (var)) -+ return false; -+ } -+ /* Analyze var as induction variable. */ -+ else if (!analyze_induction_var (var, chrec)) -+ return false; -+ } -+ -+ return true; -+} -+ -+/* Return TRUE if loop closed PHI nodes can be analyzed successfully. */ -+ -+bool -+loop_cand::analyze_lcssa_phis (void) -+{ -+ gphi_iterator gsi; -+ for (gsi = gsi_start_phis (m_exit->dest); !gsi_end_p (gsi); gsi_next (&gsi)) -+ { -+ gphi *phi = gsi.phi (); -+ -+ if (virtual_operand_p (PHI_RESULT (phi))) -+ continue; -+ -+ /* TODO: We only support lcssa phi for reduction for now. */ -+ if (!find_reduction_by_stmt (phi)) -+ return false; -+ } -+ -+ return true; -+} -+ -+/* CONSUMER is a stmt in BB storing reduction result into memory object. -+ When the reduction is intialized from constant value, we need to add -+ a stmt loading from the memory object to target basic block in inner -+ loop during undoing the reduction. Problem is that memory reference -+ may use ssa variables not dominating the target basic block. This -+ function finds all stmts on which CONSUMER depends in basic block BB, -+ records and returns them via STMTS. */ -+ -+static void -+find_deps_in_bb_for_stmt (gimple_seq *stmts, basic_block bb, gimple *consumer) -+{ -+ auto_vec worklist; -+ use_operand_p use_p; -+ ssa_op_iter iter; -+ gimple *stmt, *def_stmt; -+ gimple_stmt_iterator gsi; -+ -+ /* First clear flag for stmts in bb. */ -+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) -+ gimple_set_plf (gsi_stmt (gsi), GF_PLF_1, false); -+ -+ /* DFS search all depended stmts in bb and mark flag for these stmts. */ -+ worklist.safe_push (consumer); -+ while (!worklist.is_empty ()) -+ { -+ stmt = worklist.pop (); -+ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) -+ { -+ def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p)); -+ -+ if (is_a (def_stmt) -+ || gimple_bb (def_stmt) != bb -+ || gimple_plf (def_stmt, GF_PLF_1)) -+ continue; -+ -+ worklist.safe_push (def_stmt); -+ } -+ gimple_set_plf (stmt, GF_PLF_1, true); -+ } -+ for (gsi = gsi_start_bb_nondebug (bb); -+ !gsi_end_p (gsi) && (stmt = gsi_stmt (gsi)) != consumer;) -+ { -+ /* Move dep stmts to sequence STMTS. */ -+ if (gimple_plf (stmt, GF_PLF_1)) -+ { -+ gsi_remove (&gsi, false); -+ gimple_seq_add_stmt_without_update (stmts, stmt); -+ } -+ else -+ gsi_next_nondebug (&gsi); -+ } -+} -+ -+/* User can write, optimizers can generate simple reduction RE for inner -+ loop. In order to make interchange valid, we have to undo reduction by -+ moving producer and consumer stmts into the inner loop. For example, -+ below code: -+ -+ init = MEM_REF[idx]; //producer -+ loop: -+ var = phi -+ next = var op ... -+ reduc_sum = phi -+ MEM_REF[idx] = reduc_sum //consumer -+ -+ is transformed into: -+ -+ loop: -+ new_var = MEM_REF[idx]; //producer after moving -+ next = new_var op ... -+ MEM_REF[idx] = next; //consumer after moving -+ -+ Note if the reduction variable is initialized to constant, like: -+ -+ var = phi<0.0, next> -+ -+ we compute new_var as below: -+ -+ loop: -+ tmp = MEM_REF[idx]; -+ new_var = !first_iteration ? tmp : 0.0; -+ -+ so that the initial const is used in the first iteration of loop. Also -+ record ssa variables for dead code elimination in DCE_SEEDS. */ -+ -+void -+loop_cand::undo_simple_reduction (reduction_p re, bitmap dce_seeds) -+{ -+ gimple *stmt; -+ gimple_stmt_iterator from, to = gsi_after_labels (m_loop->header); -+ gimple_seq stmts = NULL; -+ tree new_var; -+ -+ /* Prepare the initialization stmts and insert it to inner loop. */ -+ if (re->producer != NULL) -+ { -+ gimple_set_vuse (re->producer, NULL_TREE); -+ from = gsi_for_stmt (re->producer); -+ gsi_remove (&from, false); -+ gimple_seq_add_stmt_without_update (&stmts, re->producer); -+ new_var = re->init; -+ } -+ else -+ { -+ /* Find all stmts on which expression "MEM_REF[idx]" depends. */ -+ find_deps_in_bb_for_stmt (&stmts, gimple_bb (re->consumer), re->consumer); -+ /* Because we generate new stmt loading from the MEM_REF to TMP. */ -+ tree cond, tmp = copy_ssa_name (re->var); -+ stmt = gimple_build_assign (tmp, re->init_ref); -+ gimple_seq_add_stmt_without_update (&stmts, stmt); -+ -+ /* Init new_var to MEM_REF or CONST depending on if it is the first -+ iteration. */ -+ induction_p iv = m_inductions[0]; -+ cond = fold_build2 (NE_EXPR, boolean_type_node, iv->var, iv->init_val); -+ new_var = copy_ssa_name (re->var); -+ stmt = gimple_build_assign (new_var, COND_EXPR, cond, tmp, re->init); -+ gimple_seq_add_stmt_without_update (&stmts, stmt); -+ } -+ gsi_insert_seq_before (&to, stmts, GSI_SAME_STMT); -+ -+ /* Replace all uses of reduction var with new variable. */ -+ use_operand_p use_p; -+ imm_use_iterator iterator; -+ FOR_EACH_IMM_USE_STMT (stmt, iterator, re->var) -+ { -+ FOR_EACH_IMM_USE_ON_STMT (use_p, iterator) -+ SET_USE (use_p, new_var); -+ -+ update_stmt (stmt); -+ } -+ -+ /* Move consumer stmt into inner loop, just after reduction next's def. */ -+ unlink_stmt_vdef (re->consumer); -+ release_ssa_name (gimple_vdef (re->consumer)); -+ gimple_set_vdef (re->consumer, NULL_TREE); -+ gimple_set_vuse (re->consumer, NULL_TREE); -+ gimple_assign_set_rhs1 (re->consumer, re->next); -+ from = gsi_for_stmt (re->consumer); -+ to = gsi_for_stmt (SSA_NAME_DEF_STMT (re->next)); -+ gsi_move_after (&from, &to); -+ -+ /* Mark the reduction variables for DCE. */ -+ bitmap_set_bit (dce_seeds, SSA_NAME_VERSION (re->var)); -+ bitmap_set_bit (dce_seeds, SSA_NAME_VERSION (PHI_RESULT (re->lcssa_phi))); -+} -+ -+/* Free DATAREFS and its auxiliary memory. */ -+ -+static void -+free_data_refs_with_aux (vec datarefs) -+{ -+ data_reference_p dr; -+ for (unsigned i = 0; datarefs.iterate (i, &dr); ++i) -+ if (dr->aux != NULL) -+ { -+ DR_ACCESS_STRIDE (dr)->release (); -+ free (dr->aux); -+ } -+ -+ free_data_refs (datarefs); -+} -+ -+/* Class for loop interchange transformation. */ -+ -+class tree_loop_interchange -+{ -+public: -+ tree_loop_interchange (vec loop_nest) -+ : m_loop_nest (loop_nest), m_niters_iv_var (NULL_TREE), -+ m_dce_seeds (BITMAP_ALLOC (NULL)) { } -+ ~tree_loop_interchange () { BITMAP_FREE (m_dce_seeds); } -+ bool interchange (vec, vec); -+ -+private: -+ void update_data_info (unsigned, unsigned, vec, vec); -+ bool valid_data_dependences (unsigned, unsigned, vec); -+ void interchange_loops (loop_cand &, loop_cand &); -+ void map_inductions_to_loop (loop_cand &, loop_cand &); -+ void move_code_to_inner_loop (struct loop *, struct loop *, basic_block *); -+ -+ /* The whole loop nest in which interchange is ongoing. */ -+ vec m_loop_nest; -+ /* We create new IV which is only used in loop's exit condition check. -+ In case of 3-level loop nest interchange, when we interchange the -+ innermost two loops, new IV created in the middle level loop does -+ not need to be preserved in interchanging the outermost two loops -+ later. We record the IV so that it can be skipped. */ -+ tree m_niters_iv_var; -+ /* Bitmap of seed variables for dead code elimination after interchange. */ -+ bitmap m_dce_seeds; -+}; -+ -+/* Update data refs' access stride and dependence information after loop -+ interchange. I_IDX/O_IDX gives indices of interchanged loops in loop -+ nest. DATAREFS are data references. DDRS are data dependences. */ -+ -+void -+tree_loop_interchange::update_data_info (unsigned i_idx, unsigned o_idx, -+ vec datarefs, -+ vec ddrs) -+{ -+ struct data_reference *dr; -+ struct data_dependence_relation *ddr; -+ -+ /* Update strides of data references. */ -+ for (unsigned i = 0; datarefs.iterate (i, &dr); ++i) -+ { -+ vec *stride = DR_ACCESS_STRIDE (dr); -+ gcc_assert (stride->length () > i_idx); -+ std::swap ((*stride)[i_idx], (*stride)[o_idx]); -+ } -+ /* Update data dependences. */ -+ for (unsigned i = 0; ddrs.iterate (i, &ddr); ++i) -+ if (DDR_ARE_DEPENDENT (ddr) != chrec_known) -+ { -+ for (unsigned j = 0; j < DDR_NUM_DIST_VECTS (ddr); ++j) -+ { -+ lambda_vector dist_vect = DDR_DIST_VECT (ddr, j); -+ std::swap (dist_vect[i_idx], dist_vect[o_idx]); -+ } -+ } -+} -+ -+/* Check data dependence relations, return TRUE if it's valid to interchange -+ two loops specified by I_IDX/O_IDX. Theoretically, interchanging the two -+ loops is valid only if dist vector, after interchanging, doesn't have '>' -+ as the leftmost non-'=' direction. Practically, this function have been -+ conservative here by not checking some valid cases. */ -+ -+bool -+tree_loop_interchange::valid_data_dependences (unsigned i_idx, unsigned o_idx, -+ vec ddrs) -+{ -+ struct data_dependence_relation *ddr; -+ -+ for (unsigned i = 0; ddrs.iterate (i, &ddr); ++i) -+ { -+ /* Skip no-dependence case. */ -+ if (DDR_ARE_DEPENDENT (ddr) == chrec_known) -+ continue; -+ -+ for (unsigned j = 0; j < DDR_NUM_DIST_VECTS (ddr); ++j) -+ { -+ lambda_vector dist_vect = DDR_DIST_VECT (ddr, j); -+ unsigned level = dependence_level (dist_vect, m_loop_nest.length ()); -+ -+ /* If there is no carried dependence. */ -+ if (level == 0) -+ continue; -+ -+ level --; -+ -+ /* If dependence is not carried by any loop in between the two -+ loops [oloop, iloop] to interchange. */ -+ if (level < o_idx || level > i_idx) -+ continue; -+ -+ /* Be conservative, skip case if either direction at i_idx/o_idx -+ levels is not '=' or '<'. */ -+ if (dist_vect[i_idx] < 0 || dist_vect[o_idx] < 0) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+/* Interchange two loops specified by ILOOP and OLOOP. */ -+ -+void -+tree_loop_interchange::interchange_loops (loop_cand &iloop, loop_cand &oloop) -+{ -+ reduction_p re; -+ gimple_stmt_iterator gsi; -+ tree i_niters, o_niters, var_after; -+ -+ /* Undo inner loop's simple reduction. */ -+ for (unsigned i = 0; iloop.m_reductions.iterate (i, &re); ++i) -+ if (re->type != DOUBLE_RTYPE) -+ { -+ if (re->producer) -+ reset_debug_uses (re->producer); -+ -+ iloop.undo_simple_reduction (re, m_dce_seeds); -+ } -+ -+ /* Only need to reset debug uses for double reduction. */ -+ for (unsigned i = 0; oloop.m_reductions.iterate (i, &re); ++i) -+ { -+ gcc_assert (re->type == DOUBLE_RTYPE); -+ reset_debug_uses (SSA_NAME_DEF_STMT (re->var)); -+ reset_debug_uses (SSA_NAME_DEF_STMT (re->next)); -+ } -+ -+ /* Prepare niters for both loops. */ -+ struct loop *loop_nest = m_loop_nest[0]; -+ edge instantiate_below = loop_preheader_edge (loop_nest); -+ gsi = gsi_last_bb (loop_preheader_edge (loop_nest)->src); -+ i_niters = number_of_latch_executions (iloop.m_loop); -+ i_niters = analyze_scalar_evolution (loop_outer (iloop.m_loop), i_niters); -+ i_niters = instantiate_scev (instantiate_below, loop_outer (iloop.m_loop), -+ i_niters); -+ i_niters = force_gimple_operand_gsi (&gsi, unshare_expr (i_niters), true, -+ NULL_TREE, false, GSI_CONTINUE_LINKING); -+ o_niters = number_of_latch_executions (oloop.m_loop); -+ if (oloop.m_loop != loop_nest) -+ { -+ o_niters = analyze_scalar_evolution (loop_outer (oloop.m_loop), o_niters); -+ o_niters = instantiate_scev (instantiate_below, loop_outer (oloop.m_loop), -+ o_niters); -+ } -+ o_niters = force_gimple_operand_gsi (&gsi, unshare_expr (o_niters), true, -+ NULL_TREE, false, GSI_CONTINUE_LINKING); -+ -+ /* Move src's code to tgt loop. This is necessary when src is the outer -+ loop and tgt is the inner loop. */ -+ move_code_to_inner_loop (oloop.m_loop, iloop.m_loop, oloop.m_bbs); -+ -+ /* Map outer loop's IV to inner loop, and vice versa. */ -+ map_inductions_to_loop (oloop, iloop); -+ map_inductions_to_loop (iloop, oloop); -+ -+ /* Create canonical IV for both loops. Note canonical IV for outer/inner -+ loop is actually from inner/outer loop. Also we record the new IV -+ created for the outer loop so that it can be skipped in later loop -+ interchange. */ -+ create_canonical_iv (oloop.m_loop, oloop.m_exit, -+ i_niters, &m_niters_iv_var, &var_after); -+ bitmap_set_bit (m_dce_seeds, SSA_NAME_VERSION (var_after)); -+ create_canonical_iv (iloop.m_loop, iloop.m_exit, -+ o_niters, NULL, &var_after); -+ bitmap_set_bit (m_dce_seeds, SSA_NAME_VERSION (var_after)); -+ -+ /* Scrap niters estimation of interchanged loops. */ -+ iloop.m_loop->any_upper_bound = false; -+ iloop.m_loop->any_likely_upper_bound = false; -+ free_numbers_of_iterations_estimates_loop (iloop.m_loop); -+ oloop.m_loop->any_upper_bound = false; -+ oloop.m_loop->any_likely_upper_bound = false; -+ free_numbers_of_iterations_estimates_loop (oloop.m_loop); -+ -+ /* ??? The association between the loop data structure and the -+ CFG changed, so what was loop N at the source level is now -+ loop M. We should think of retaining the association or breaking -+ it fully by creating a new loop instead of re-using the "wrong" one. */ -+} -+ -+/* Map induction variables of SRC loop to TGT loop. The function firstly -+ creates the same IV of SRC loop in TGT loop, then deletes the original -+ IV and re-initialize it using the newly created IV. For example, loop -+ nest: -+ -+ for (i = 0; i < N; i++) -+ for (j = 0; j < M; j++) -+ { -+ //use of i; -+ //use of j; -+ } -+ -+ will be transformed into: -+ -+ for (jj = 0; jj < M; jj++) -+ for (ii = 0; ii < N; ii++) -+ { -+ //use of ii; -+ //use of jj; -+ } -+ -+ after loop interchange. */ -+ -+void -+tree_loop_interchange::map_inductions_to_loop (loop_cand &src, loop_cand &tgt) -+{ -+ induction_p iv; -+ edge e = tgt.m_exit; -+ gimple_stmt_iterator incr_pos = gsi_last_bb (e->src), gsi; -+ -+ /* Map source loop's IV to target loop. */ -+ for (unsigned i = 0; src.m_inductions.iterate (i, &iv); ++i) -+ { -+ gimple *use_stmt, *stmt = SSA_NAME_DEF_STMT (iv->var); -+ gcc_assert (is_a (stmt)); -+ -+ use_operand_p use_p; -+ /* Only map original IV to target loop. */ -+ if (m_niters_iv_var != iv->var) -+ { -+ /* Map the IV by creating the same one in target loop. */ -+ tree var_before, var_after; -+ tree base = unshare_expr (iv->init_expr); -+ tree step = unshare_expr (iv->step); -+ create_iv (base, step, SSA_NAME_VAR (iv->var), -+ tgt.m_loop, &incr_pos, false, &var_before, &var_after); -+ bitmap_set_bit (m_dce_seeds, SSA_NAME_VERSION (var_before)); -+ bitmap_set_bit (m_dce_seeds, SSA_NAME_VERSION (var_after)); -+ -+ /* Replace uses of the original IV var with newly created IV var. */ -+ imm_use_iterator imm_iter; -+ FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, iv->var) -+ { -+ FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) -+ SET_USE (use_p, var_before); -+ -+ update_stmt (use_stmt); -+ } -+ } -+ -+ /* Mark all uses for DCE. */ -+ ssa_op_iter op_iter; -+ FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, op_iter, SSA_OP_USE) -+ { -+ tree use = USE_FROM_PTR (use_p); -+ if (TREE_CODE (use) == SSA_NAME -+ && ! SSA_NAME_IS_DEFAULT_DEF (use)) -+ bitmap_set_bit (m_dce_seeds, SSA_NAME_VERSION (use)); -+ } -+ -+ /* Delete definition of the original IV in the source loop. */ -+ gsi = gsi_for_stmt (stmt); -+ remove_phi_node (&gsi, true); -+ } -+} -+ -+/* Move stmts of outer loop to inner loop. */ -+ -+void -+tree_loop_interchange::move_code_to_inner_loop (struct loop *outer, -+ struct loop *inner, -+ basic_block *outer_bbs) -+{ -+ basic_block oloop_exit_bb = single_exit (outer)->src; -+ gimple_stmt_iterator gsi, to; -+ -+ for (unsigned i = 0; i < outer->num_nodes; i++) -+ { -+ basic_block bb = outer_bbs[i]; -+ -+ /* Skip basic blocks of inner loop. */ -+ if (flow_bb_inside_loop_p (inner, bb)) -+ continue; -+ -+ /* Move code from header/latch to header/latch. */ -+ if (bb == outer->header) -+ to = gsi_after_labels (inner->header); -+ else if (bb == outer->latch) -+ to = gsi_after_labels (inner->latch); -+ else -+ /* Otherwise, simply move to exit->src. */ -+ to = gsi_last_bb (single_exit (inner)->src); -+ -+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);) -+ { -+ gimple *stmt = gsi_stmt (gsi); -+ -+ if (oloop_exit_bb == bb -+ && stmt == gsi_stmt (gsi_last_bb (oloop_exit_bb))) -+ { -+ gsi_next (&gsi); -+ continue; -+ } -+ -+ if (gimple_vuse (stmt)) -+ gimple_set_vuse (stmt, NULL_TREE); -+ if (gimple_vdef (stmt)) -+ { -+ unlink_stmt_vdef (stmt); -+ release_ssa_name (gimple_vdef (stmt)); -+ gimple_set_vdef (stmt, NULL_TREE); -+ } -+ -+ reset_debug_uses (stmt); -+ gsi_move_before (&gsi, &to); -+ } -+ } -+} -+ -+/* Given data reference DR in LOOP_NEST, the function computes DR's access -+ stride at each level of loop from innermost LOOP to outer. On success, -+ it saves access stride at each level loop in a vector which is pointed -+ by DR->aux. For example: -+ -+ int arr[100][100][100]; -+ for (i = 0; i < 100; i++) ;(DR->aux)strides[0] = 40000 -+ for (j = 100; j > 0; j--) ;(DR->aux)strides[1] = 400 -+ for (k = 0; k < 100; k++) ;(DR->aux)strides[2] = 4 -+ arr[i][j - 1][k] = 0; */ -+ -+static void -+compute_access_stride (struct loop *loop_nest, struct loop *loop, -+ data_reference_p dr) -+{ -+ vec *strides = new vec (); -+ basic_block bb = gimple_bb (DR_STMT (dr)); -+ -+ while (!flow_bb_inside_loop_p (loop, bb)) -+ { -+ strides->safe_push (build_int_cst (sizetype, 0)); -+ loop = loop_outer (loop); -+ } -+ gcc_assert (loop == bb->loop_father); -+ -+ tree ref = DR_REF (dr); -+ tree scev_base = build_fold_addr_expr (ref); -+ tree scev = analyze_scalar_evolution (loop, scev_base); -+ scev = instantiate_scev (loop_preheader_edge (loop_nest), loop, scev); -+ if (! chrec_contains_undetermined (scev)) -+ { -+ tree sl = scev; -+ struct loop *expected = loop; -+ while (TREE_CODE (sl) == POLYNOMIAL_CHREC) -+ { -+ struct loop *sl_loop = get_chrec_loop (sl); -+ while (sl_loop != expected) -+ { -+ strides->safe_push (size_int (0)); -+ expected = loop_outer (expected); -+ } -+ strides->safe_push (CHREC_RIGHT (sl)); -+ sl = CHREC_LEFT (sl); -+ expected = loop_outer (expected); -+ } -+ if (! tree_contains_chrecs (sl, NULL)) -+ while (expected != loop_outer (loop_nest)) -+ { -+ strides->safe_push (size_int (0)); -+ expected = loop_outer (expected); -+ } -+ } -+ -+ dr->aux = strides; -+} -+ -+/* Given loop nest LOOP_NEST with innermost LOOP, the function computes -+ access strides with respect to each level loop for all data refs in -+ DATAREFS from inner loop to outer loop. On success, it returns the -+ outermost loop that access strides can be computed successfully for -+ all data references. If access strides cannot be computed at least -+ for two levels of loop for any data reference, it returns NULL. */ -+ -+static struct loop * -+compute_access_strides (struct loop *loop_nest, struct loop *loop, -+ vec datarefs) -+{ -+ unsigned i, j, num_loops = (unsigned) -1; -+ data_reference_p dr; -+ vec *stride; -+ -+ for (i = 0; datarefs.iterate (i, &dr); ++i) -+ { -+ compute_access_stride (loop_nest, loop, dr); -+ stride = DR_ACCESS_STRIDE (dr); -+ if (stride->length () < num_loops) -+ { -+ num_loops = stride->length (); -+ if (num_loops < 2) -+ return NULL; -+ } -+ } -+ -+ for (i = 0; datarefs.iterate (i, &dr); ++i) -+ { -+ stride = DR_ACCESS_STRIDE (dr); -+ if (stride->length () > num_loops) -+ stride->truncate (num_loops); -+ -+ for (j = 0; j < (num_loops >> 1); ++j) -+ std::swap ((*stride)[j], (*stride)[num_loops - j - 1]); -+ } -+ -+ loop = superloop_at_depth (loop, loop_depth (loop) + 1 - num_loops); -+ gcc_assert (loop_nest == loop || flow_loop_nested_p (loop_nest, loop)); -+ return loop; -+} -+ -+/* Prune access strides for data references in DATAREFS by removing strides -+ of loops that isn't in current LOOP_NEST. */ -+ -+static void -+prune_access_strides_not_in_loop (struct loop *loop_nest, -+ struct loop *innermost, -+ vec datarefs) -+{ -+ data_reference_p dr; -+ unsigned num_loops = loop_depth (innermost) - loop_depth (loop_nest) + 1; -+ gcc_assert (num_loops > 1); -+ -+ /* Block remove strides of loops that is not in current loop nest. */ -+ for (unsigned i = 0; datarefs.iterate (i, &dr); ++i) -+ { -+ vec *stride = DR_ACCESS_STRIDE (dr); -+ if (stride->length () > num_loops) -+ stride->block_remove (0, stride->length () - num_loops); -+ } -+} -+ -+/* Dump access strides for all DATAREFS. */ -+ -+static void -+dump_access_strides (vec datarefs) -+{ -+ data_reference_p dr; -+ fprintf (dump_file, "Access Strides for DRs:\n"); -+ for (unsigned i = 0; datarefs.iterate (i, &dr); ++i) -+ { -+ fprintf (dump_file, " "); -+ print_generic_expr (dump_file, DR_REF (dr), TDF_SLIM); -+ fprintf (dump_file, ":\t\t<"); -+ -+ vec *stride = DR_ACCESS_STRIDE (dr); -+ unsigned num_loops = stride->length (); -+ for (unsigned j = 0; j < num_loops; ++j) -+ { -+ print_generic_expr (dump_file, (*stride)[j], TDF_SLIM); -+ fprintf (dump_file, "%s", (j < num_loops - 1) ? ",\t" : ">\n"); -+ } -+ } -+} -+ -+/* Return true if it's profitable to interchange two loops whose index -+ in whole loop nest vector are I_IDX/O_IDX respectively. The function -+ computes and compares three types information from all DATAREFS: -+ 1) Access stride for loop I_IDX and O_IDX. -+ 2) Number of invariant memory references with respect to I_IDX before -+ and after loop interchange. -+ 3) Flags indicating if all memory references access sequential memory -+ in ILOOP, before and after loop interchange. -+ If INNMOST_LOOP_P is true, the two loops for interchanging are the two -+ innermost loops in loop nest. This function also dumps information if -+ DUMP_INFO_P is true. */ -+ -+static bool -+should_interchange_loops (unsigned i_idx, unsigned o_idx, -+ vec datarefs, -+ bool innermost_loops_p, bool dump_info_p = true) -+{ -+ unsigned HOST_WIDE_INT ratio; -+ unsigned i, j, num_old_inv_drs = 0, num_new_inv_drs = 0; -+ struct data_reference *dr; -+ bool all_seq_dr_before_p = true, all_seq_dr_after_p = true; -+ widest_int iloop_strides = 0, oloop_strides = 0; -+ unsigned num_unresolved_drs = 0; -+ unsigned num_resolved_ok_drs = 0; -+ unsigned num_resolved_not_ok_drs = 0; -+ -+ if (dump_info_p && dump_file && (dump_flags & TDF_DETAILS)) -+ fprintf (dump_file, "\nData ref strides:\n\tmem_ref:\t\tiloop\toloop\n"); -+ -+ for (i = 0; datarefs.iterate (i, &dr); ++i) -+ { -+ vec *stride = DR_ACCESS_STRIDE (dr); -+ tree iloop_stride = (*stride)[i_idx], oloop_stride = (*stride)[o_idx]; -+ -+ bool subloop_stride_p = false; -+ /* Data ref can't be invariant or sequential access at current loop if -+ its address changes with respect to any subloops. */ -+ for (j = i_idx + 1; j < stride->length (); ++j) -+ if (!integer_zerop ((*stride)[j])) -+ { -+ subloop_stride_p = true; -+ break; -+ } -+ -+ if (integer_zerop (iloop_stride)) -+ { -+ if (!subloop_stride_p) -+ num_old_inv_drs++; -+ } -+ if (integer_zerop (oloop_stride)) -+ { -+ if (!subloop_stride_p) -+ num_new_inv_drs++; -+ } -+ -+ if (TREE_CODE (iloop_stride) == INTEGER_CST -+ && TREE_CODE (oloop_stride) == INTEGER_CST) -+ { -+ iloop_strides = wi::add (iloop_strides, wi::to_widest (iloop_stride)); -+ oloop_strides = wi::add (oloop_strides, wi::to_widest (oloop_stride)); -+ } -+ else if (multiple_of_p (TREE_TYPE (iloop_stride), -+ iloop_stride, oloop_stride)) -+ num_resolved_ok_drs++; -+ else if (multiple_of_p (TREE_TYPE (iloop_stride), -+ oloop_stride, iloop_stride)) -+ num_resolved_not_ok_drs++; -+ else -+ num_unresolved_drs++; -+ -+ /* Data ref can't be sequential access if its address changes in sub -+ loop. */ -+ if (subloop_stride_p) -+ { -+ all_seq_dr_before_p = false; -+ all_seq_dr_after_p = false; -+ continue; -+ } -+ /* Track if all data references are sequential accesses before/after loop -+ interchange. Note invariant is considered sequential here. */ -+ tree access_size = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))); -+ if (all_seq_dr_before_p -+ && ! (integer_zerop (iloop_stride) -+ || operand_equal_p (access_size, iloop_stride, 0))) -+ all_seq_dr_before_p = false; -+ if (all_seq_dr_after_p -+ && ! (integer_zerop (oloop_stride) -+ || operand_equal_p (access_size, oloop_stride, 0))) -+ all_seq_dr_after_p = false; -+ } -+ -+ if (dump_info_p && dump_file && (dump_flags & TDF_DETAILS)) -+ { -+ fprintf (dump_file, "\toverall:\t\t"); -+ print_decu (iloop_strides, dump_file); -+ fprintf (dump_file, "\t"); -+ print_decu (oloop_strides, dump_file); -+ fprintf (dump_file, "\n"); -+ -+ fprintf (dump_file, "Invariant data ref: before(%d), after(%d)\n", -+ num_old_inv_drs, num_new_inv_drs); -+ fprintf (dump_file, "All consecutive stride: before(%s), after(%s)\n", -+ all_seq_dr_before_p ? "true" : "false", -+ all_seq_dr_after_p ? "true" : "false"); -+ fprintf (dump_file, "OK to interchage with variable strides: %d\n", -+ num_resolved_ok_drs); -+ fprintf (dump_file, "Not OK to interchage with variable strides: %d\n", -+ num_resolved_not_ok_drs); -+ fprintf (dump_file, "Variable strides we cannot decide: %d\n", -+ num_unresolved_drs); -+ } -+ -+ if (num_unresolved_drs != 0 || num_resolved_not_ok_drs != 0) -+ return false; -+ -+ /* We use different stride comparison ratio for interchanging innermost -+ two loops or not. The idea is to be conservative in interchange for -+ the innermost loops. */ -+ ratio = innermost_loops_p ? INNER_STRIDE_RATIO : OUTER_STRIDE_RATIO; -+ /* Do interchange if it gives better data locality behavior. */ -+ if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides, ratio))) -+ return true; -+ if (wi::gtu_p (iloop_strides, oloop_strides)) -+ { -+ /* Or it creates more invariant memory references. */ -+ if ((!all_seq_dr_before_p || all_seq_dr_after_p) -+ && num_new_inv_drs > num_old_inv_drs) -+ return true; -+ /* Or it makes all memory references sequential. */ -+ if (num_new_inv_drs >= num_old_inv_drs -+ && !all_seq_dr_before_p && all_seq_dr_after_p) -+ return true; -+ } -+ -+ return false; -+} -+ -+/* Try to interchange inner loop of a loop nest to outer level. */ -+ -+bool -+tree_loop_interchange::interchange (vec datarefs, -+ vec ddrs) -+{ -+ bool changed_p = false; -+ /* In each iteration we try to interchange I-th loop with (I+1)-th loop. -+ The overall effect is to push inner loop to outermost level in whole -+ loop nest. */ -+ for (unsigned i = m_loop_nest.length (); i > 1; --i) -+ { -+ unsigned i_idx = i - 1, o_idx = i - 2; -+ -+ /* Check validity for loop interchange. */ -+ if (!valid_data_dependences (i_idx, o_idx, ddrs)) -+ break; -+ -+ loop_cand iloop (m_loop_nest[i_idx], m_loop_nest[o_idx]); -+ loop_cand oloop (m_loop_nest[o_idx], m_loop_nest[o_idx]); -+ -+ /* Check if we can do transformation for loop interchange. */ -+ if (!iloop.analyze_carried_vars (NULL) -+ || !iloop.analyze_lcssa_phis () -+ || !oloop.analyze_carried_vars (&iloop) -+ || !oloop.analyze_lcssa_phis () -+ || !iloop.can_interchange_p (NULL) -+ || !oloop.can_interchange_p (&iloop)) -+ break; -+ -+ /* Check profitability for loop interchange. */ -+ if (should_interchange_loops (i_idx, o_idx, datarefs, -+ iloop.m_loop->inner == NULL)) -+ { -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ fprintf (dump_file, -+ "Loop_pair is interchanged\n\n", -+ oloop.m_loop->num, iloop.m_loop->num); -+ -+ changed_p = true; -+ interchange_loops (iloop, oloop); -+ /* No need to update if there is no further loop interchange. */ -+ if (o_idx > 0) -+ update_data_info (i_idx, o_idx, datarefs, ddrs); -+ } -+ else -+ { -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ fprintf (dump_file, -+ "Loop_pair is not interchanged\n\n", -+ oloop.m_loop->num, iloop.m_loop->num); -+ } -+ } -+ -+ simple_dce_from_worklist (m_dce_seeds); -+ return changed_p; -+} -+ -+ -+/* Loop interchange pass. */ -+ -+namespace { -+ -+const pass_data pass_data_linterchange = -+{ -+ GIMPLE_PASS, /* type */ -+ "linterchange", /* name */ -+ OPTGROUP_LOOP, /* optinfo_flags */ -+ TV_LINTERCHANGE, /* tv_id */ -+ PROP_cfg, /* properties_required */ -+ 0, /* properties_provided */ -+ 0, /* properties_destroyed */ -+ 0, /* todo_flags_start */ -+ 0, /* todo_flags_finish */ -+}; -+ -+class pass_linterchange : public gimple_opt_pass -+{ -+public: -+ pass_linterchange (gcc::context *ctxt) -+ : gimple_opt_pass (pass_data_linterchange, ctxt) -+ {} -+ -+ /* opt_pass methods: */ -+ opt_pass * clone () { return new pass_linterchange (m_ctxt); } -+ virtual bool gate (function *) { return flag_loop_interchange; } -+ virtual unsigned int execute (function *); -+ -+}; // class pass_linterchange -+ -+ -+/* Return true if LOOP has proper form for interchange. We check three -+ conditions in the function: -+ 1) In general, a loop can be interchanged only if it doesn't have -+ basic blocks other than header, exit and latch besides possible -+ inner loop nest. This basically restricts loop interchange to -+ below form loop nests: -+ -+ header<---+ -+ | | -+ v | -+ INNER_LOOP | -+ | | -+ v | -+ exit--->latch -+ -+ 2) Data reference in basic block that executes in different times -+ than loop head/exit is not allowed. -+ 3) Record the innermost outer loop that doesn't form rectangle loop -+ nest with LOOP. */ -+ -+static bool -+proper_loop_form_for_interchange (struct loop *loop, struct loop **min_outer) -+{ -+ edge e0, e1, exit; -+ -+ /* Don't interchange if loop has unsupported information for the moment. */ -+ if (loop->safelen > 0 -+ || loop->constraints != 0 -+ || loop->can_be_parallel -+ || loop->dont_vectorize -+ || loop->force_vectorize -+ || loop->in_oacc_kernels_region -+ || loop->orig_loop_num != 0 -+ || loop->simduid != NULL_TREE) -+ return false; -+ -+ /* Don't interchange if outer loop has basic block other than header, exit -+ and latch. */ -+ if (loop->inner != NULL -+ && loop->num_nodes != loop->inner->num_nodes + 3) -+ return false; -+ -+ if ((exit = single_dom_exit (loop)) == NULL) -+ return false; -+ -+ /* Check control flow on loop header/exit blocks. */ -+ if (loop->header == exit->src -+ && (EDGE_COUNT (loop->header->preds) != 2 -+ || EDGE_COUNT (loop->header->succs) != 2)) -+ return false; -+ else if (loop->header != exit->src -+ && (EDGE_COUNT (loop->header->preds) != 2 -+ || !single_succ_p (loop->header) -+ || unsupported_edge (single_succ_edge (loop->header)) -+ || EDGE_COUNT (exit->src->succs) != 2 -+ || !single_pred_p (exit->src) -+ || unsupported_edge (single_pred_edge (exit->src)))) -+ return false; -+ -+ e0 = EDGE_PRED (loop->header, 0); -+ e1 = EDGE_PRED (loop->header, 1); -+ if (unsupported_edge (e0) || unsupported_edge (e1) -+ || (e0->src != loop->latch && e1->src != loop->latch) -+ || (e0->src->loop_father == loop && e1->src->loop_father == loop)) -+ return false; -+ -+ e0 = EDGE_SUCC (exit->src, 0); -+ e1 = EDGE_SUCC (exit->src, 1); -+ if (unsupported_edge (e0) || unsupported_edge (e1) -+ || (e0->dest != loop->latch && e1->dest != loop->latch) -+ || (e0->dest->loop_father == loop && e1->dest->loop_father == loop)) -+ return false; -+ -+ /* Don't interchange if any reference is in basic block that doesn't -+ dominate exit block. */ -+ basic_block *bbs = get_loop_body (loop); -+ for (unsigned i = 0; i < loop->num_nodes; i++) -+ { -+ basic_block bb = bbs[i]; -+ -+ if (bb->loop_father != loop -+ || bb == loop->header || bb == exit->src -+ || dominated_by_p (CDI_DOMINATORS, exit->src, bb)) -+ continue; -+ -+ for (gimple_stmt_iterator gsi = gsi_start_bb_nondebug (bb); -+ !gsi_end_p (gsi); gsi_next_nondebug (&gsi)) -+ if (gimple_vuse (gsi_stmt (gsi))) -+ { -+ free (bbs); -+ return false; -+ } -+ } -+ free (bbs); -+ -+ tree niters = number_of_latch_executions (loop); -+ niters = analyze_scalar_evolution (loop_outer (loop), niters); -+ if (!niters || chrec_contains_undetermined (niters)) -+ return false; -+ -+ /* Record the innermost outer loop that doesn't form rectangle loop nest. */ -+ for (loop_p loop2 = loop_outer (loop); -+ loop2 && flow_loop_nested_p (*min_outer, loop2); -+ loop2 = loop_outer (loop2)) -+ { -+ niters = instantiate_scev (loop_preheader_edge (loop2), -+ loop_outer (loop), niters); -+ if (!evolution_function_is_invariant_p (niters, loop2->num)) -+ { -+ *min_outer = loop2; -+ break; -+ } -+ } -+ return true; -+} -+ -+/* Return true if any two adjacent loops in loop nest [INNERMOST, LOOP_NEST] -+ should be interchanged by looking into all DATAREFS. */ -+ -+static bool -+should_interchange_loop_nest (struct loop *loop_nest, struct loop *innermost, -+ vec datarefs) -+{ -+ unsigned idx = loop_depth (innermost) - loop_depth (loop_nest); -+ gcc_assert (idx > 0); -+ -+ /* Check if any two adjacent loops should be interchanged. */ -+ for (struct loop *loop = innermost; -+ loop != loop_nest; loop = loop_outer (loop), idx--) -+ if (should_interchange_loops (idx, idx - 1, datarefs, -+ loop == innermost, false)) -+ return true; -+ -+ return false; -+} -+ -+/* Given loop nest LOOP_NEST and data references DATAREFS, compute data -+ dependences for loop interchange and store it in DDRS. Note we compute -+ dependences directly rather than call generic interface so that we can -+ return on unknown dependence instantly. */ -+ -+static bool -+tree_loop_interchange_compute_ddrs (vec loop_nest, -+ vec datarefs, -+ vec *ddrs) -+{ -+ struct data_reference *a, *b; -+ struct loop *innermost = loop_nest.last (); -+ -+ for (unsigned i = 0; datarefs.iterate (i, &a); ++i) -+ { -+ bool a_outer_p = gimple_bb (DR_STMT (a))->loop_father != innermost; -+ for (unsigned j = i + 1; datarefs.iterate (j, &b); ++j) -+ if (DR_IS_WRITE (a) || DR_IS_WRITE (b)) -+ { -+ bool b_outer_p = gimple_bb (DR_STMT (b))->loop_father != innermost; -+ /* Don't support multiple write references in outer loop. */ -+ if (a_outer_p && b_outer_p && DR_IS_WRITE (a) && DR_IS_WRITE (b)) -+ return false; -+ -+ ddr_p ddr = initialize_data_dependence_relation (a, b, loop_nest); -+ ddrs->safe_push (ddr); -+ compute_affine_dependence (ddr, loop_nest[0]); -+ -+ /* Give up if ddr is unknown dependence or classic direct vector -+ is not available. */ -+ if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know -+ || (DDR_ARE_DEPENDENT (ddr) == NULL_TREE -+ && DDR_NUM_DIR_VECTS (ddr) == 0)) -+ return false; -+ -+ /* If either data references is in outer loop of nest, we require -+ no dependence here because the data reference need to be moved -+ into inner loop during interchange. */ -+ if (a_outer_p && b_outer_p -+ && operand_equal_p (DR_REF (a), DR_REF (b), 0)) -+ continue; -+ if (DDR_ARE_DEPENDENT (ddr) != chrec_known -+ && (a_outer_p || b_outer_p)) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+/* Prune DATAREFS by removing any data reference not inside of LOOP. */ -+ -+static inline void -+prune_datarefs_not_in_loop (struct loop *loop, vec datarefs) -+{ -+ unsigned i, j; -+ struct data_reference *dr; -+ -+ for (i = 0, j = 0; datarefs.iterate (i, &dr); ++i) -+ { -+ if (flow_bb_inside_loop_p (loop, gimple_bb (DR_STMT (dr)))) -+ datarefs[j++] = dr; -+ else -+ { -+ if (dr->aux) -+ { -+ DR_ACCESS_STRIDE (dr)->release (); -+ free (dr->aux); -+ } -+ free_data_ref (dr); -+ } -+ } -+ datarefs.truncate (j); -+} -+ -+/* Find and store data references in DATAREFS for LOOP nest. If there's -+ difficult data reference in a basic block, we shrink the loop nest to -+ inner loop of that basic block's father loop. On success, return the -+ outer loop of the result loop nest. */ -+ -+static struct loop * -+prepare_data_references (struct loop *loop, vec *datarefs) -+{ -+ struct loop *loop_nest = loop; -+ vec *bb_refs; -+ basic_block bb, *bbs = get_loop_body_in_dom_order (loop); -+ -+ for (unsigned i = 0; i < loop->num_nodes; i++) -+ bbs[i]->aux = NULL; -+ -+ /* Find data references for all basic blocks. Shrink loop nest on difficult -+ data reference. */ -+ for (unsigned i = 0; loop_nest && i < loop->num_nodes; ++i) -+ { -+ bb = bbs[i]; -+ if (!flow_bb_inside_loop_p (loop_nest, bb)) -+ continue; -+ -+ bb_refs = new vec (); -+ if (find_data_references_in_bb (loop, bb, bb_refs) == chrec_dont_know) -+ { -+ loop_nest = bb->loop_father->inner; -+ if (loop_nest && !loop_nest->inner) -+ loop_nest = NULL; -+ -+ free_data_refs (*bb_refs); -+ delete bb_refs; -+ } -+ else if (bb_refs->is_empty ()) -+ delete bb_refs; -+ else -+ bb->aux = bb_refs; -+ } -+ -+ /* Collect all data references in loop nest. */ -+ for (unsigned i = 0; i < loop->num_nodes; i++) -+ { -+ bb = bbs[i]; -+ if (!bb->aux) -+ continue; -+ -+ bb_refs = (vec *) bb->aux; -+ if (loop_nest && flow_bb_inside_loop_p (loop_nest, bb)) -+ datarefs->safe_splice (*bb_refs); -+ else -+ free_data_refs (*bb_refs); -+ -+ delete bb_refs; -+ bb->aux = NULL; -+ } -+ free (bbs); -+ -+ return loop_nest; -+} -+ -+/* Given innermost LOOP, return true if perfect loop nest can be found and -+ data dependences can be computed. If succeed, record the perfect loop -+ nest in LOOP_NEST; record all data references in DATAREFS and record all -+ data dependence relations in DDRS. -+ -+ We do support a restricted form of imperfect loop nest, i.e, loop nest -+ with load/store in outer loop initializing/finalizing simple reduction -+ of the innermost loop. For such outer loop reference, we require that -+ it has no dependence with others sinve it will be moved to inner loop -+ in interchange. */ -+ -+static bool -+prepare_perfect_loop_nest (struct loop *loop, vec *loop_nest, -+ vec *datarefs, vec *ddrs) -+{ -+ struct loop *start_loop = NULL, *innermost = loop; -+ struct loop *outermost = loops_for_fn (cfun)->tree_root; -+ -+ /* Find loop nest from the innermost loop. The outermost is the innermost -+ outer*/ -+ while (loop->num != 0 && loop->inner == start_loop -+ && flow_loop_nested_p (outermost, loop)) -+ { -+ if (!proper_loop_form_for_interchange (loop, &outermost)) -+ break; -+ -+ start_loop = loop; -+ /* If this loop has sibling loop, the father loop won't be in perfect -+ loop nest. */ -+ if (loop->next != NULL) -+ break; -+ -+ loop = loop_outer (loop); -+ } -+ if (!start_loop || !start_loop->inner) -+ return false; -+ -+ /* Prepare the data reference vector for the loop nest, pruning outer -+ loops we cannot handle. */ -+ start_loop = prepare_data_references (start_loop, datarefs); -+ if (!start_loop -+ /* Check if there is no data reference. */ -+ || datarefs->is_empty () -+ /* Check if there are too many of data references. */ -+ || (int) datarefs->length () > MAX_DATAREFS) -+ return false; -+ -+ /* Compute access strides for all data references, pruning outer -+ loops we cannot analyze refs in. */ -+ start_loop = compute_access_strides (start_loop, innermost, *datarefs); -+ if (!start_loop) -+ return false; -+ -+ /* Check if any interchange is profitable in the loop nest. */ -+ if (!should_interchange_loop_nest (start_loop, innermost, *datarefs)) -+ return false; -+ -+ /* Check if data dependences can be computed for loop nest starting from -+ start_loop. */ -+ loop = start_loop; -+ do { -+ loop_nest->truncate (0); -+ -+ if (loop != start_loop) -+ prune_datarefs_not_in_loop (start_loop, *datarefs); -+ -+ if (find_loop_nest (start_loop, loop_nest) -+ && tree_loop_interchange_compute_ddrs (*loop_nest, *datarefs, ddrs)) -+ { -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ fprintf (dump_file, -+ "\nConsider loop interchange for loop_nest<%d - %d>\n", -+ start_loop->num, innermost->num); -+ -+ if (loop != start_loop) -+ prune_access_strides_not_in_loop (start_loop, innermost, *datarefs); -+ -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ dump_access_strides (*datarefs); -+ -+ return true; -+ } -+ -+ free_dependence_relations (*ddrs); -+ *ddrs = vNULL; -+ /* Try to compute data dependences with the outermost loop stripped. */ -+ loop = start_loop; -+ start_loop = start_loop->inner; -+ } while (start_loop && start_loop->inner); -+ -+ return false; -+} -+ -+/* Main entry for loop interchange pass. */ -+ -+unsigned int -+pass_linterchange::execute (function *fun) -+{ -+ if (number_of_loops (fun) <= 2) -+ return 0; -+ -+ bool changed_p = false; -+ struct loop *loop; -+ FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST) -+ { -+ vec loop_nest = vNULL; -+ vec datarefs = vNULL; -+ vec ddrs = vNULL; -+ if (prepare_perfect_loop_nest (loop, &loop_nest, &datarefs, &ddrs)) -+ { -+ tree_loop_interchange loop_interchange (loop_nest); -+ changed_p |= loop_interchange.interchange (datarefs, ddrs); -+ } -+ free_dependence_relations (ddrs); -+ free_data_refs_with_aux (datarefs); -+ loop_nest.release (); -+ } -+ -+ if (changed_p) -+ scev_reset_htab (); -+ -+ return changed_p ? (TODO_update_ssa_only_virtuals) : 0; -+} -+ -+} // anon namespace -+ -+gimple_opt_pass * -+make_pass_linterchange (gcc::context *ctxt) -+{ -+ return new pass_linterchange (ctxt); -+} -diff -N -urp a/gcc/gimple-pretty-print.h b/gcc/gimple-pretty-print.h ---- a/gcc/gimple-pretty-print.h 2018-11-15 15:54:01.223039794 +0800 -+++ b/gcc/gimple-pretty-print.h 2018-11-15 16:03:17.447054436 +0800 -@@ -27,10 +27,10 @@ along with GCC; see the file COPYING3. - extern void debug_gimple_stmt (gimple *); - extern void debug_gimple_seq (gimple_seq); - extern void print_gimple_seq (FILE *, gimple_seq, int, int); --extern void print_gimple_stmt (FILE *, gimple *, int, int); -+extern void print_gimple_stmt (FILE *, gimple *, int, int = 0); - extern void debug (gimple &ref); - extern void debug (gimple *ptr); --extern void print_gimple_expr (FILE *, gimple *, int, int); -+extern void print_gimple_expr (FILE *, gimple *, int, int = 0); - extern void pp_gimple_stmt_1 (pretty_printer *, gimple *, int, int); - extern void gimple_dump_bb (FILE *, basic_block, int, int); - extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block); -diff -N -urp a/gcc/opts.c b/gcc/opts.c ---- a/gcc/opts.c 2018-11-15 15:59:30.459048461 +0800 -+++ b/gcc/opts.c 2018-11-15 16:03:17.447054436 +0800 -@@ -538,6 +538,7 @@ static const struct default_options defa - { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 }, -+ { OPT_LEVELS_3_PLUS, OPT_floop_interchange, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC }, - { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 }, -diff -N -urp a/gcc/params.def b/gcc/params.def ---- a/gcc/params.def 2018-11-15 15:59:30.459048461 +0800 -+++ b/gcc/params.def 2018-11-15 16:03:17.451054437 +0800 -@@ -780,6 +780,20 @@ DEFPARAM (PARAM_L2_CACHE_SIZE, - "The size of L2 cache.", - 512, 0, 0) - -+/* Maximum number of statements in loop nest for loop interchange. */ -+ -+DEFPARAM (PARAM_LOOP_INTERCHANGE_MAX_NUM_STMTS, -+ "loop-interchange-max-num-stmts", -+ "The maximum number of stmts in loop nest for loop interchange.", -+ 64, 0, 0) -+ -+/* Minimum stride ratio for loop interchange to be profitiable. */ -+ -+DEFPARAM (PARAM_LOOP_INTERCHANGE_STRIDE_RATIO, -+ "loop-interchange-stride-ratio", -+ "The minimum stride ratio for loop interchange to be profitable", -+ 2, 0, 0) -+ - /* Whether we should use canonical types rather than deep "structural" - type checking. Setting this value to 1 (the default) improves - compilation performance in the C++ and Objective-C++ front end; -diff -N -urp a/gcc/passes.def b/gcc/passes.def ---- a/gcc/passes.def 2018-11-15 15:59:30.463048461 +0800 -+++ b/gcc/passes.def 2018-11-15 16:03:17.451054437 +0800 -@@ -278,6 +278,7 @@ along with GCC; see the file COPYING3. - NEXT_PASS (pass_cd_dce); - NEXT_PASS (pass_record_bounds); - NEXT_PASS (pass_loop_distribution); -+ NEXT_PASS (pass_linterchange); - NEXT_PASS (pass_copy_prop); - NEXT_PASS (pass_graphite); - PUSH_INSERT_PASSES_WITHIN (pass_graphite) -diff -N -urp a/gcc/timevar.def b/gcc/timevar.def ---- a/gcc/timevar.def 2018-11-15 15:59:30.463048461 +0800 -+++ b/gcc/timevar.def 2018-11-15 16:03:17.455054437 +0800 -@@ -182,6 +182,7 @@ DEFTIMEVAR (TV_TREE_LOOP , "tree lo - DEFTIMEVAR (TV_TREE_NOLOOP , "loopless fn") - DEFTIMEVAR (TV_TREE_LOOP_BOUNDS , "tree loop bounds") - DEFTIMEVAR (TV_LIM , "tree loop invariant motion") -+DEFTIMEVAR (TV_LINTERCHANGE , "tree loop interchange") - DEFTIMEVAR (TV_TREE_LOOP_IVCANON , "tree canonical iv") - DEFTIMEVAR (TV_SCEV_CONST , "scev constant prop") - DEFTIMEVAR (TV_TREE_LOOP_UNSWITCH , "tree loop unswitching") -diff -N -urp a/gcc/tree-pass.h b/gcc/tree-pass.h ---- a/gcc/tree-pass.h 2018-11-15 15:59:30.467048461 +0800 -+++ b/gcc/tree-pass.h 2018-11-15 16:03:17.455054437 +0800 -@@ -367,6 +367,7 @@ extern gimple_opt_pass *make_pass_tree_l - extern gimple_opt_pass *make_pass_tree_no_loop (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_tree_loop_init (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_lim (gcc::context *ctxt); -+extern gimple_opt_pass *make_pass_linterchange (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_tree_unswitch (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_loop_split (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_loop_jam (gcc::context *ctxt); -diff -N -urp a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h ---- a/gcc/tree-pretty-print.h 2018-11-15 15:54:01.439039800 +0800 -+++ b/gcc/tree-pretty-print.h 2018-11-15 16:03:17.455054437 +0800 -@@ -37,7 +37,7 @@ extern void debug_tree_chain (tree); - extern void print_generic_decl (FILE *, tree, int); - extern void print_generic_stmt (FILE *, tree, int); - extern void print_generic_stmt_indented (FILE *, tree, int, int); --extern void print_generic_expr (FILE *, tree, int); -+extern void print_generic_expr (FILE *, tree, int = 0); - extern void dump_omp_clauses (pretty_printer *, tree, int, int); - extern int dump_generic_node (pretty_printer *, tree, int, int, bool); - extern void print_declaration (pretty_printer *, tree, int, int); -diff -N -urp a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c ---- a/gcc/tree-scalar-evolution.c 2018-11-15 15:54:01.443039800 +0800 -+++ b/gcc/tree-scalar-evolution.c 2018-11-15 16:03:17.459054437 +0800 -@@ -3000,6 +3000,50 @@ instantiate_scev (basic_block instantiat - return res; - } - -+tree -+instantiate_scev (edge instantiate_below, struct loop *evolution_loop, -+ tree chrec) -+{ -+ tree res; -+ -+ if (dump_file && (dump_flags & TDF_SCEV)) -+ { -+ fprintf (dump_file, "(instantiate_scev \n"); -+ fprintf (dump_file, " (instantiate_below = %d -> %d)\n", -+ instantiate_below->src->index, instantiate_below->dest->index); -+ if (evolution_loop) -+ fprintf (dump_file, " (evolution_loop = %d)\n", evolution_loop->num); -+ fprintf (dump_file, " (chrec = "); -+ print_generic_expr (dump_file, chrec); -+ fprintf (dump_file, ")\n"); -+ } -+ -+ bool destr = false; -+ if (!global_cache) -+ { -+ global_cache = new instantiate_cache_type; -+ destr = true; -+ } -+ -+ res = instantiate_scev_r (instantiate_below->src, evolution_loop, -+ NULL, chrec, NULL, 0); -+ -+ if (destr) -+ { -+ delete global_cache; -+ global_cache = NULL; -+ } -+ -+ if (dump_file && (dump_flags & TDF_SCEV)) -+ { -+ fprintf (dump_file, " (res = "); -+ print_generic_expr (dump_file, res); -+ fprintf (dump_file, "))\n"); -+ } -+ -+ return res; -+} -+ - /* Similar to instantiate_parameters, but does not introduce the - evolutions in outer loops for LOOP invariants in CHREC, and does not - care about causing overflows, as long as they do not affect value -diff -N -urp a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h ---- a/gcc/tree-scalar-evolution.h 2018-11-15 15:54:01.443039800 +0800 -+++ b/gcc/tree-scalar-evolution.h 2018-11-15 16:03:17.459054437 +0800 -@@ -31,6 +31,7 @@ extern void scev_reset_htab (void); - extern void scev_finalize (void); - extern tree analyze_scalar_evolution (struct loop *, tree); - extern tree instantiate_scev (basic_block, struct loop *, tree); -+extern tree instantiate_scev (edge, struct loop *, tree); - extern tree resolve_mixers (struct loop *, tree, bool *); - extern void gather_stats_on_scev_database (void); - extern void final_value_replacement_loop (struct loop *); -diff -N -urp a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c ---- a/gcc/tree-ssa-dce.c 2018-11-15 15:54:01.443039800 +0800 -+++ b/gcc/tree-ssa-dce.c 2018-11-15 16:03:17.463054437 +0800 -@@ -1729,3 +1729,55 @@ make_pass_cd_dce (gcc::context *ctxt) - { - return new pass_cd_dce (ctxt); - } -+ -+ -+/* A cheap DCE interface. WORKLIST is a list of possibly dead stmts and -+ is consumed by this function. The function has linear complexity in -+ the number of dead stmts with a constant factor like the average SSA -+ use operands number. */ -+ -+void -+simple_dce_from_worklist (bitmap worklist) -+{ -+ while (! bitmap_empty_p (worklist)) -+ { -+ /* Pop item. */ -+ unsigned i = bitmap_first_set_bit (worklist); -+ bitmap_clear_bit (worklist, i); -+ -+ tree def = ssa_name (i); -+ /* Removed by somebody else or still in use. */ -+ if (! def || ! has_zero_uses (def)) -+ continue; -+ -+ gimple *t = SSA_NAME_DEF_STMT (def); -+ if (gimple_has_side_effects (t)) -+ continue; -+ -+ /* Add uses to the worklist. */ -+ ssa_op_iter iter; -+ use_operand_p use_p; -+ FOR_EACH_PHI_OR_STMT_USE (use_p, t, iter, SSA_OP_USE) -+ { -+ tree use = USE_FROM_PTR (use_p); -+ if (TREE_CODE (use) == SSA_NAME -+ && ! SSA_NAME_IS_DEFAULT_DEF (use)) -+ bitmap_set_bit (worklist, SSA_NAME_VERSION (use)); -+ } -+ -+ /* Remove stmt. */ -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ { -+ fprintf (dump_file, "Removing dead stmt:"); -+ print_gimple_stmt (dump_file, t, 0); -+ } -+ gimple_stmt_iterator gsi = gsi_for_stmt (t); -+ if (gimple_code (t) == GIMPLE_PHI) -+ remove_phi_node (&gsi, true); -+ else -+ { -+ gsi_remove (&gsi, true); -+ release_defs (t); -+ } -+ } -+} -diff -N -urp a/gcc/tree-ssa-dce.h b/gcc/tree-ssa-dce.h ---- a/gcc/tree-ssa-dce.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/gcc/tree-ssa-dce.h 2018-11-15 16:03:17.463054437 +0800 -@@ -0,0 +1,22 @@ -+/* Copyright (C) 2017 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 -+. */ -+ -+#ifndef TREE_SSA_DCE_H -+#define TREE_SSA_DCE_H -+extern void simple_dce_from_worklist (bitmap); -+#endif -diff -N -urp a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c ---- a/gcc/tree-ssa-loop-ivcanon.c 2018-11-15 15:54:01.447039800 +0800 -+++ b/gcc/tree-ssa-loop-ivcanon.c 2018-11-15 16:03:17.467054437 +0800 -@@ -76,10 +76,13 @@ enum unroll_level - }; - - /* Adds a canonical induction variable to LOOP iterating NITER times. EXIT -- is the exit edge whose condition is replaced. */ -- --static void --create_canonical_iv (struct loop *loop, edge exit, tree niter) -+ is the exit edge whose condition is replaced. The ssa versions of the new -+ IV before and after increment will be stored in VAR_BEFORE and VAR_AFTER -+ if they are not NULL. */ -+ -+void -+create_canonical_iv (struct loop *loop, edge exit, tree niter, -+ tree *var_before = NULL, tree *var_after = NULL) - { - edge in; - tree type, var; -@@ -112,7 +115,9 @@ create_canonical_iv (struct loop *loop, - create_iv (niter, - build_int_cst (type, -1), - NULL_TREE, loop, -- &incr_at, false, NULL, &var); -+ &incr_at, false, var_before, &var); -+ if (var_after) -+ *var_after = var; - - cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR; - gimple_cond_set_code (cond, cmp); -diff -N -urp a/gcc/tree-ssa-loop-ivopts.h b/gcc/tree-ssa-loop-ivopts.h ---- a/gcc/tree-ssa-loop-ivopts.h 2018-11-15 15:54:01.447039800 +0800 -+++ b/gcc/tree-ssa-loop-ivopts.h 2018-11-15 16:03:17.467054437 +0800 -@@ -33,4 +33,6 @@ bool multiplier_allowed_in_address_p (HO - addr_space_t); - void tree_ssa_iv_optimize (void); - -+void create_canonical_iv (struct loop *, edge, tree, -+ tree * = NULL, tree * = NULL); - #endif /* GCC_TREE_SSA_LOOP_IVOPTS_H */ -diff -N -urp a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c ---- a/gcc/tree-ssa-pre.c 2018-11-15 15:54:01.447039800 +0800 -+++ b/gcc/tree-ssa-pre.c 2018-11-15 16:03:17.471054437 +0800 -@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. - #include "gimplify.h" - #include "gimple-iterator.h" - #include "tree-cfg.h" -+#include "tree-ssa-dce.h" - #include "tree-ssa-loop.h" - #include "tree-into-ssa.h" - #include "tree-dfa.h" -@@ -4908,99 +4909,6 @@ mark_operand_necessary (tree op) - return stmt; - } - --/* Because we don't follow exactly the standard PRE algorithm, and decide not -- to insert PHI nodes sometimes, and because value numbering of casts isn't -- perfect, we sometimes end up inserting dead code. This simple DCE-like -- pass removes any insertions we made that weren't actually used. */ -- --static void --remove_dead_inserted_code (void) --{ -- bitmap worklist; -- unsigned i; -- bitmap_iterator bi; -- gimple *t; -- -- worklist = BITMAP_ALLOC (NULL); -- EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi) -- { -- t = SSA_NAME_DEF_STMT (ssa_name (i)); -- if (gimple_plf (t, NECESSARY)) -- bitmap_set_bit (worklist, i); -- } -- while (!bitmap_empty_p (worklist)) -- { -- i = bitmap_first_set_bit (worklist); -- bitmap_clear_bit (worklist, i); -- t = SSA_NAME_DEF_STMT (ssa_name (i)); -- -- /* PHI nodes are somewhat special in that each PHI alternative has -- data and control dependencies. All the statements feeding the -- PHI node's arguments are always necessary. */ -- if (gimple_code (t) == GIMPLE_PHI) -- { -- unsigned k; -- -- for (k = 0; k < gimple_phi_num_args (t); k++) -- { -- tree arg = PHI_ARG_DEF (t, k); -- if (TREE_CODE (arg) == SSA_NAME) -- { -- gimple *n = mark_operand_necessary (arg); -- if (n) -- bitmap_set_bit (worklist, SSA_NAME_VERSION (arg)); -- } -- } -- } -- else -- { -- /* Propagate through the operands. Examine all the USE, VUSE and -- VDEF operands in this statement. Mark all the statements -- which feed this statement's uses as necessary. */ -- ssa_op_iter iter; -- tree use; -- -- /* The operands of VDEF expressions are also needed as they -- represent potential definitions that may reach this -- statement (VDEF operands allow us to follow def-def -- links). */ -- -- FOR_EACH_SSA_TREE_OPERAND (use, t, iter, SSA_OP_ALL_USES) -- { -- gimple *n = mark_operand_necessary (use); -- if (n) -- bitmap_set_bit (worklist, SSA_NAME_VERSION (use)); -- } -- } -- } -- -- EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi) -- { -- t = SSA_NAME_DEF_STMT (ssa_name (i)); -- if (!gimple_plf (t, NECESSARY)) -- { -- gimple_stmt_iterator gsi; -- -- if (dump_file && (dump_flags & TDF_DETAILS)) -- { -- fprintf (dump_file, "Removing unnecessary insertion:"); -- print_gimple_stmt (dump_file, t, 0, 0); -- } -- -- gsi = gsi_for_stmt (t); -- if (gimple_code (t) == GIMPLE_PHI) -- remove_phi_node (&gsi, true); -- else -- { -- gsi_remove (&gsi, true); -- release_defs (t); -- } -- } -- } -- BITMAP_FREE (worklist); --} -- -- - /* Initialize data structures used by PRE. */ - - static void -@@ -5142,8 +5050,7 @@ pass_pre::execute (function *fun) - statistics_counter_event (fun, "Eliminated", pre_stats.eliminations); - - clear_expression_ids (); -- remove_dead_inserted_code (); -- -+ - scev_finalize (); - fini_pre (); - todo |= fini_eliminate (); -diff -N -urp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c ---- a/gcc/tree-vect-loop.c 2018-11-15 15:54:01.447039800 +0800 -+++ b/gcc/tree-vect-loop.c 2018-11-15 16:03:17.471054437 +0800 -@@ -2632,6 +2632,112 @@ vect_is_slp_reduction (loop_vec_info loo - return true; - } - -+/* Return true if the reduction PHI in LOOP with latch arg LOOP_ARG and -+ reduction operation CODE has a handled computation expression. */ -+ -+bool -+check_reduction_path (location_t loc, loop_p loop, gphi *phi, tree loop_arg, -+ enum tree_code code) -+{ -+ auto_vec > path; -+ auto_bitmap visited; -+ tree lookfor = PHI_RESULT (phi); -+ ssa_op_iter curri; -+ use_operand_p curr = op_iter_init_phiuse (&curri, phi, SSA_OP_USE); -+ while (USE_FROM_PTR (curr) != loop_arg) -+ curr = op_iter_next_use (&curri); -+ curri.i = curri.numops; -+ do -+ { -+ path.safe_push (std::make_pair (curri, curr)); -+ tree use = USE_FROM_PTR (curr); -+ if (use == lookfor) -+ break; -+ gimple *def = SSA_NAME_DEF_STMT (use); -+ if (gimple_nop_p (def) -+ || ! flow_bb_inside_loop_p (loop, gimple_bb (def))) -+ { -+pop: -+ do -+ { -+ std::pair x = path.pop (); -+ curri = x.first; -+ curr = x.second; -+ do -+ curr = op_iter_next_use (&curri); -+ /* Skip already visited or non-SSA operands (from iterating -+ over PHI args). */ -+ while (curr != NULL_USE_OPERAND_P -+ && (TREE_CODE (USE_FROM_PTR (curr)) != SSA_NAME -+ || ! bitmap_set_bit (visited, -+ SSA_NAME_VERSION -+ (USE_FROM_PTR (curr))))); -+ } -+ while (curr == NULL_USE_OPERAND_P && ! path.is_empty ()); -+ if (curr == NULL_USE_OPERAND_P) -+ break; -+ } -+ else -+ { -+ if (gimple_code (def) == GIMPLE_PHI) -+ curr = op_iter_init_phiuse (&curri, as_a (def), SSA_OP_USE); -+ else -+ curr = op_iter_init_use (&curri, def, SSA_OP_USE); -+ while (curr != NULL_USE_OPERAND_P -+ && (TREE_CODE (USE_FROM_PTR (curr)) != SSA_NAME -+ || ! bitmap_set_bit (visited, -+ SSA_NAME_VERSION -+ (USE_FROM_PTR (curr))))) -+ curr = op_iter_next_use (&curri); -+ if (curr == NULL_USE_OPERAND_P) -+ goto pop; -+ } -+ } -+ while (1); -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ { -+ dump_printf_loc (MSG_NOTE, loc, "reduction path: "); -+ unsigned i; -+ std::pair *x; -+ FOR_EACH_VEC_ELT (path, i, x) -+ { -+ dump_generic_expr (MSG_NOTE, TDF_SLIM, USE_FROM_PTR (x->second)); -+ dump_printf (MSG_NOTE, " "); -+ } -+ dump_printf (MSG_NOTE, "\n"); -+ } -+ -+ /* Check whether the reduction path detected is valid. */ -+ bool fail = path.length () == 0; -+ bool neg = false; -+ for (unsigned i = 1; i < path.length (); ++i) -+ { -+ gimple *use_stmt = USE_STMT (path[i].second); -+ tree op = USE_FROM_PTR (path[i].second); -+ if (! has_single_use (op) -+ || ! is_gimple_assign (use_stmt)) -+ { -+ fail = true; -+ break; -+ } -+ if (gimple_assign_rhs_code (use_stmt) != code) -+ { -+ if (code == PLUS_EXPR -+ && gimple_assign_rhs_code (use_stmt) == MINUS_EXPR) -+ { -+ /* Track whether we negate the reduction value each iteration. */ -+ if (gimple_assign_rhs2 (use_stmt) == op) -+ neg = ! neg; -+ } -+ else -+ { -+ fail = true; -+ break; -+ } -+ } -+ } -+ return ! fail && ! neg; -+} - - /* Function vect_is_simple_reduction_1 - -diff -N -urp a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h ---- a/gcc/tree-vectorizer.h 2018-11-15 15:54:01.451039800 +0800 -+++ b/gcc/tree-vectorizer.h 2018-11-15 16:03:17.475054437 +0800 -@@ -1166,6 +1166,9 @@ extern tree vect_create_addr_base_for_ve - extern void destroy_loop_vec_info (loop_vec_info, bool); - extern gimple *vect_force_simple_reduction (loop_vec_info, gimple *, bool, - bool *, bool); -+/* Used in gimple-loop-interchange.c. */ -+extern bool check_reduction_path (location_t, loop_p, gphi *, tree, -+ enum tree_code); - /* Drive for loop analysis stage. */ - extern loop_vec_info vect_analyze_loop (struct loop *, loop_vec_info); - extern tree vect_build_loop_niters (loop_vec_info); diff --git a/floop-unroll-and-jam.patch b/floop-unroll-and-jam.patch deleted file mode 100644 index 514aaf859d3aa8f8497624b7e86687997b7529fb..0000000000000000000000000000000000000000 --- a/floop-unroll-and-jam.patch +++ /dev/null @@ -1,905 +0,0 @@ -diff -N -urp a/gcc/Makefile.in b/gcc/Makefile.in ---- a/gcc/Makefile.in 2018-11-07 11:37:24.615223860 +0800 -+++ b/gcc/Makefile.in 2018-11-07 11:38:26.155223860 +0800 -@@ -1292,6 +1292,7 @@ OBJS = \ - gimple-iterator.o \ - gimple-fold.o \ - gimple-laddress.o \ -+ gimple-loop-jam.o \ - gimple-low.o \ - gimple-pretty-print.o \ - gimple-ssa-backprop.o \ -diff -N -urp a/gcc/cfgloop.c b/gcc/cfgloop.c ---- a/gcc/cfgloop.c 2018-11-07 11:37:24.947223860 +0800 -+++ b/gcc/cfgloop.c 2018-11-07 11:38:26.155223860 +0800 -@@ -296,13 +296,25 @@ establish_preds (struct loop *loop, stru - - /* Add LOOP to the loop hierarchy tree where FATHER is father of the - added loop. If LOOP has some children, take care of that their -- pred field will be initialized correctly. */ -+ pred field will be initialized correctly. If AFTER is non-null -+ then it's expected it's a pointer into FATHERs inner sibling -+ list and LOOP is added behind AFTER, otherwise it's added in front -+ of FATHERs siblings. */ - - void --flow_loop_tree_node_add (struct loop *father, struct loop *loop) -+flow_loop_tree_node_add (struct loop *father, struct loop *loop, -+ struct loop *after) - { -- loop->next = father->inner; -- father->inner = loop; -+ if (after) -+ { -+ loop->next = after->next; -+ after->next = loop; -+ } -+ else -+ { -+ loop->next = father->inner; -+ father->inner = loop; -+ } - - establish_preds (loop, father); - } -diff -N -urp a/gcc/cfgloop.h b/gcc/cfgloop.h ---- a/gcc/cfgloop.h 2018-11-07 11:37:24.331223860 +0800 -+++ b/gcc/cfgloop.h 2018-11-07 11:38:26.155223860 +0800 -@@ -324,7 +324,8 @@ void record_loop_exits (void); - void rescan_loop_exit (edge, bool, bool); - - /* Loop data structure manipulation/querying. */ --extern void flow_loop_tree_node_add (struct loop *, struct loop *); -+extern void flow_loop_tree_node_add (struct loop *, struct loop *, -+ struct loop * = NULL); - extern void flow_loop_tree_node_remove (struct loop *); - extern bool flow_loop_nested_p (const struct loop *, const struct loop *); - extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block); -diff -N -urp a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c ---- a/gcc/cfgloopmanip.c 2018-11-07 11:37:24.847223860 +0800 -+++ b/gcc/cfgloopmanip.c 2018-11-07 11:38:26.155223860 +0800 -@@ -1026,9 +1026,11 @@ copy_loop_info (struct loop *loop, struc - } - - /* Copies copy of LOOP as subloop of TARGET loop, placing newly -- created loop into loops structure. */ -+ created loop into loops structure. If AFTER is non-null -+ the new loop is added at AFTER->next, otherwise in front of TARGETs -+ sibling list. */ - struct loop * --duplicate_loop (struct loop *loop, struct loop *target) -+duplicate_loop (struct loop *loop, struct loop *target, struct loop *after) - { - struct loop *cloop; - cloop = alloc_loop (); -@@ -1040,36 +1042,46 @@ duplicate_loop (struct loop *loop, struc - set_loop_copy (loop, cloop); - - /* Add it to target. */ -- flow_loop_tree_node_add (target, cloop); -+ flow_loop_tree_node_add (target, cloop, after); - - return cloop; - } - - /* Copies structure of subloops of LOOP into TARGET loop, placing -- newly created loops into loop tree. */ -+ newly created loops into loop tree at the end of TARGETs sibling -+ list in the original order. */ - void - duplicate_subloops (struct loop *loop, struct loop *target) - { -- struct loop *aloop, *cloop; -+ struct loop *aloop, *cloop, *tail; - -+ for (tail = target->inner; tail && tail->next; tail = tail->next) -+ ; - for (aloop = loop->inner; aloop; aloop = aloop->next) - { -- cloop = duplicate_loop (aloop, target); -+ cloop = duplicate_loop (aloop, target, tail); -+ tail = cloop; -+ gcc_assert (!tail->next); - duplicate_subloops (aloop, cloop); - } - } - - /* Copies structure of subloops of N loops, stored in array COPIED_LOOPS, -- into TARGET loop, placing newly created loops into loop tree. */ -+ into TARGET loop, placing newly created loops into loop tree adding -+ them to TARGETs sibling list at the end in order. */ - static void - copy_loops_to (struct loop **copied_loops, int n, struct loop *target) - { -- struct loop *aloop; -+ struct loop *aloop, *tail; - int i; - -+ for (tail = target->inner; tail && tail->next; tail = tail->next) -+ ; - for (i = 0; i < n; i++) - { -- aloop = duplicate_loop (copied_loops[i], target); -+ aloop = duplicate_loop (copied_loops[i], target, tail); -+ tail = aloop; -+ gcc_assert (!tail->next); - duplicate_subloops (copied_loops[i], aloop); - } - } -@@ -1133,14 +1145,15 @@ set_zero_probability (edge e) - } - - /* Duplicates body of LOOP to given edge E NDUPL times. Takes care of updating -- loop structure and dominators. E's destination must be LOOP header for -- this to work, i.e. it must be entry or latch edge of this loop; these are -- unique, as the loops must have preheaders for this function to work -- correctly (in case E is latch, the function unrolls the loop, if E is entry -- edge, it peels the loop). Store edges created by copying ORIG edge from -- copies corresponding to set bits in WONT_EXIT bitmap (bit 0 corresponds to -- original LOOP body, the other copies are numbered in order given by control -- flow through them) into TO_REMOVE array. Returns false if duplication is -+ loop structure and dominators (order of inner subloops is retained). -+ E's destination must be LOOP header for this to work, i.e. it must be entry -+ or latch edge of this loop; these are unique, as the loops must have -+ preheaders for this function to work correctly (in case E is latch, the -+ function unrolls the loop, if E is entry edge, it peels the loop). Store -+ edges created by copying ORIG edge from copies corresponding to set bits in -+ WONT_EXIT bitmap (bit 0 corresponds to original LOOP body, the other copies -+ are numbered in order given by control flow through them) into TO_REMOVE -+ array. Returns false if duplication is - impossible. */ - - bool -diff -N -urp a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h ---- a/gcc/cfgloopmanip.h 2018-11-07 11:37:24.939223860 +0800 -+++ b/gcc/cfgloopmanip.h 2018-11-07 11:38:26.155223860 +0800 -@@ -47,7 +47,8 @@ extern struct loop *loopify (edge, edge, - unsigned, unsigned); - extern void unloop (struct loop *, bool *, bitmap); - extern void copy_loop_info (struct loop *loop, struct loop *target); --extern struct loop * duplicate_loop (struct loop *, struct loop *); -+extern struct loop * duplicate_loop (struct loop *, struct loop *, -+ struct loop * = NULL); - extern void duplicate_subloops (struct loop *, struct loop *); - extern bool can_duplicate_loop_p (const struct loop *loop); - extern bool duplicate_loop_to_header_edge (struct loop *, edge, -diff -N -urp a/gcc/common.opt b/gcc/common.opt ---- a/gcc/common.opt 2018-11-07 11:37:24.859223860 +0800 -+++ b/gcc/common.opt 2018-11-07 11:38:26.159223860 +0800 -@@ -1496,8 +1496,8 @@ Common Alias(floop-nest-optimize) - Enable loop nest transforms. Same as -floop-nest-optimize. - - floop-unroll-and-jam --Common Alias(floop-nest-optimize) --Enable loop nest transforms. Same as -floop-nest-optimize. -+Common Report Var(flag_unroll_jam) Optimization -+Perform unroll-and-jam on loops. - - fgnu-tm - Common Report Var(flag_tm) -diff -N -urp a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi ---- a/gcc/doc/invoke.texi 2018-11-07 11:37:24.915223860 +0800 -+++ b/gcc/doc/invoke.texi 2018-11-07 11:39:49.031223860 +0800 -@@ -7120,7 +7120,8 @@ Optimize yet more. @option{-O3} turns o - by @option{-O2} and also turns on the @option{-finline-functions}, - @option{-funswitch-loops}, @option{-fpredictive-commoning}, - @option{-fgcse-after-reload}, @option{-ftree-loop-vectorize}, --@option{-ftree-loop-distribute-patterns}, @option{-fsplit-paths} -+@option{-ftree-loop-distribute-patterns}, @option{-fsplit-paths}, -+@option{-floop-unroll-and-jam}, - @option{-ftree-slp-vectorize}, @option{-fvect-cost-model}, - @option{-ftree-partial-pre}, @option{-fpeel-loops} - and @option{-fipa-cp-clone} options. -@@ -8226,12 +8227,10 @@ at @option{-O} and higher. - @itemx -floop-interchange - @itemx -floop-strip-mine - @itemx -floop-block --@itemx -floop-unroll-and-jam - @opindex ftree-loop-linear - @opindex floop-interchange - @opindex floop-strip-mine - @opindex floop-block --@opindex floop-unroll-and-jam - Perform loop nest optimizations. Same as - @option{-floop-nest-optimize}. To use this code transformation, GCC has - to be configured with @option{--with-isl} to enable the Graphite loop -@@ -8323,6 +8322,12 @@ ENDDO - @end smallexample - and the initialization loop is transformed into a call to memset zero. - -+@item -floop-unroll-and-jam -+@opindex floop-unroll-and-jam -+Apply unroll and jam transformations on feasible loops. In a loop -+nest this unrolls the outer loop by some factor and fuses the resulting -+multiple inner loops. This flag is enabled by default at @option{-O3}. -+ - @item -ftree-loop-im - @opindex ftree-loop-im - Perform loop invariant motion on trees. This pass moves only invariants that -@@ -10353,13 +10358,13 @@ loop in the loop nest by a given number - length can be changed using the @option{loop-block-tile-size} - parameter. The default value is 51 iterations. - --@item loop-unroll-jam-size --Specify the unroll factor for the @option{-floop-unroll-and-jam} option. The --default value is 4. -- --@item loop-unroll-jam-depth --Specify the dimension to be unrolled (counting from the most inner loop) --for the @option{-floop-unroll-and-jam}. The default value is 2. -+@item unroll-jam-min-percent -+The minimum percentage of memory references that must be optimized -+away for the unroll-and-jam transformation to be considered profitable. -+ -+@item unroll-jam-max-unroll -+The maximum number of times the outer loop should be unrolled by -+the unroll-and-jam transformation. - - @item ipa-cp-value-list-size - IPA-CP attempts to track all possible values and types passed to a function's -diff -N -urp a/gcc/gimple-loop-jam.c b/gcc/gimple-loop-jam.c ---- a/gcc/gimple-loop-jam.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/gcc/gimple-loop-jam.c 2018-11-07 11:38:26.167223860 +0800 -@@ -0,0 +1,598 @@ -+/* Loop unroll-and-jam. -+ Copyright (C) 2017-2018 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 -+. */ -+ -+#include "config.h" -+#include "system.h" -+#include "coretypes.h" -+#include "params.h" -+#include "tree-pass.h" -+#include "backend.h" -+#include "tree.h" -+#include "gimple.h" -+#include "ssa.h" -+#include "fold-const.h" -+#include "tree-cfg.h" -+#include "tree-ssa.h" -+#include "tree-ssa-loop-niter.h" -+#include "tree-ssa-loop.h" -+#include "tree-ssa-loop-manip.h" -+#include "cfgloop.h" -+#include "tree-scalar-evolution.h" -+#include "gimple-iterator.h" -+#include "cfghooks.h" -+#include "tree-data-ref.h" -+#include "tree-ssa-loop-ivopts.h" -+#include "tree-vectorizer.h" -+ -+/* Unroll and Jam transformation -+ -+ This is a combination of two transformations, where the second -+ is not always valid. It's applicable if a loop nest has redundancies -+ over the iterations of an outer loop while not having that with -+ an inner loop. -+ -+ Given this nest: -+ for (i) { -+ for (j) { -+ B (i,j) -+ } -+ } -+ -+ first unroll: -+ for (i by 2) { -+ for (j) { -+ B (i,j) -+ } -+ for (j) { -+ B (i+1,j) -+ } -+ } -+ -+ then fuse the two adjacent inner loops resulting from that: -+ for (i by 2) { -+ for (j) { -+ B (i,j) -+ B (i+1,j) -+ } -+ } -+ -+ As the order of evaluations of the body B changes this is valid -+ only in certain situations: all distance vectors need to be forward. -+ Additionally if there are multiple induction variables than just -+ a counting control IV (j above) we can also deal with some situations. -+ -+ The validity is checked by unroll_jam_possible_p, and the data-dep -+ testing below. -+ -+ A trivial example where the fusion is wrong would be when -+ B (i,j) == x[j-1] = x[j]; -+ for (i by 2) { -+ for (j) { -+ x[j-1] = x[j]; -+ } -+ for (j) { -+ x[j-1] = x[j]; -+ } -+ } effect: move content to front by two elements -+ --> -+ for (i by 2) { -+ for (j) { -+ x[j-1] = x[j]; -+ x[j-1] = x[j]; -+ } -+ } effect: move content to front by one element -+*/ -+ -+/* Modify the loop tree for the fact that all code once belonging -+ to the OLD loop or the outer loop of OLD now is inside LOOP. */ -+ -+static void -+merge_loop_tree (struct loop *loop, struct loop *old) -+{ -+ basic_block *bbs; -+ int i, n; -+ struct loop *subloop; -+ edge e; -+ edge_iterator ei; -+ -+ /* Find its nodes. */ -+ bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun)); -+ n = get_loop_body_with_size (loop, bbs, n_basic_blocks_for_fn (cfun)); -+ -+ for (i = 0; i < n; i++) -+ { -+ /* If the block was direct child of OLD loop it's now part -+ of LOOP. If it was outside OLD, then it moved into LOOP -+ as well. This avoids changing the loop father for BBs -+ in inner loops of OLD. */ -+ if (bbs[i]->loop_father == old -+ || loop_depth (bbs[i]->loop_father) < loop_depth (old)) -+ { -+ remove_bb_from_loops (bbs[i]); -+ add_bb_to_loop (bbs[i], loop); -+ continue; -+ } -+ -+ /* If we find a direct subloop of OLD, move it to LOOP. */ -+ subloop = bbs[i]->loop_father; -+ if (loop_outer (subloop) == old && subloop->header == bbs[i]) -+ { -+ flow_loop_tree_node_remove (subloop); -+ flow_loop_tree_node_add (loop, subloop); -+ } -+ } -+ -+ /* Update the information about loop exit edges. */ -+ for (i = 0; i < n; i++) -+ { -+ FOR_EACH_EDGE (e, ei, bbs[i]->succs) -+ { -+ rescan_loop_exit (e, false, false); -+ } -+ } -+ -+ loop->num_nodes = n; -+ -+ free (bbs); -+} -+ -+/* BB is part of the outer loop of an unroll-and-jam situation. -+ Check if any statements therein would prevent the transformation. */ -+ -+static bool -+bb_prevents_fusion_p (basic_block bb) -+{ -+ gimple_stmt_iterator gsi; -+ /* BB is duplicated by outer unrolling and then all N-1 first copies -+ move into the body of the fused inner loop. If BB exits the outer loop -+ the last copy still does so, and the first N-1 copies are cancelled -+ by loop unrolling, so also after fusion it's the exit block. -+ But there might be other reasons that prevent fusion: -+ * stores or unknown side-effects prevent fusion -+ * loads don't -+ * computations into SSA names: these aren't problematic. Their -+ result will be unused on the exit edges of the first N-1 copies -+ (those aren't taken after unrolling). If they are used on the -+ other edge (the one leading to the outer latch block) they are -+ loop-carried (on the outer loop) and the Nth copy of BB will -+ compute them again (i.e. the first N-1 copies will be dead). */ -+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) -+ { -+ gimple *g = gsi_stmt (gsi); -+ if (gimple_vdef (g) || gimple_has_side_effects (g)) -+ return true; -+ } -+ return false; -+} -+ -+/* Given an inner loop LOOP (of some OUTER loop) determine if -+ we can safely fuse copies of it (generated by outer unrolling). -+ If so return true, otherwise return false. */ -+ -+static bool -+unroll_jam_possible_p (struct loop *outer, struct loop *loop) -+{ -+ basic_block *bbs; -+ int i, n; -+ struct tree_niter_desc niter; -+ -+ /* When fusing the loops we skip the latch block -+ of the first one, so it mustn't have any effects to -+ preserve. */ -+ if (!empty_block_p (loop->latch)) -+ return false; -+ -+ if (!single_exit (loop)) -+ return false; -+ -+ /* We need a perfect nest. Quick check for adjacent inner loops. */ -+ if (outer->inner != loop || loop->next) -+ return false; -+ -+ /* Prevent head-controlled inner loops, that we usually have. -+ The guard block would need to be accepted -+ (invariant condition either entering or skipping the loop), -+ without also accepting arbitrary control flow. When unswitching -+ ran before us (as with -O3) this won't be a problem because its -+ outer loop unswitching will have moved out the invariant condition. -+ -+ If we do that we need to extend fuse_loops () to cope with this -+ by threading through the (still invariant) copied condition -+ between the two loop copies. */ -+ if (!dominated_by_p (CDI_DOMINATORS, outer->latch, loop->header)) -+ return false; -+ -+ /* The number of iterations of the inner loop must be loop invariant -+ with respect to the outer loop. */ -+ if (!number_of_iterations_exit (loop, single_exit (loop), &niter, -+ false, true) -+ || niter.cmp == ERROR_MARK -+ || !integer_zerop (niter.may_be_zero) -+ || !expr_invariant_in_loop_p (outer, niter.niter)) -+ return false; -+ -+ /* If the inner loop produces any values that are used inside the -+ outer loop (except the virtual op) then it can flow -+ back (perhaps indirectly) into the inner loop. This prevents -+ fusion: without fusion the value at the last iteration is used, -+ with fusion the value after the initial iteration is used. -+ -+ If all uses are outside the outer loop this doesn't prevent fusion; -+ the value of the last iteration is still used (and the values from -+ all intermediate iterations are dead). */ -+ gphi_iterator psi; -+ for (psi = gsi_start_phis (single_exit (loop)->dest); -+ !gsi_end_p (psi); gsi_next (&psi)) -+ { -+ imm_use_iterator imm_iter; -+ use_operand_p use_p; -+ tree op = gimple_phi_result (psi.phi ()); -+ if (virtual_operand_p (op)) -+ continue; -+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op) -+ { -+ gimple *use_stmt = USE_STMT (use_p); -+ if (!is_gimple_debug (use_stmt) -+ && flow_bb_inside_loop_p (outer, gimple_bb (use_stmt))) -+ return false; -+ } -+ } -+ -+ /* And check blocks belonging to just outer loop. */ -+ bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun)); -+ n = get_loop_body_with_size (outer, bbs, n_basic_blocks_for_fn (cfun)); -+ -+ for (i = 0; i < n; i++) -+ if (bbs[i]->loop_father == outer && bb_prevents_fusion_p (bbs[i])) -+ break; -+ free (bbs); -+ if (i != n) -+ return false; -+ -+ /* For now we can safely fuse copies of LOOP only if all -+ loop carried variables are inductions (or the virtual op). -+ -+ We could handle reductions as well (the initial value in the second -+ body would be the after-iter value of the first body) if it's over -+ an associative and commutative operation. We wouldn't -+ be able to handle unknown cycles. */ -+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi)) -+ { -+ affine_iv iv; -+ tree op = gimple_phi_result (psi.phi ()); -+ -+ if (virtual_operand_p (op)) -+ continue; -+ if (!simple_iv (loop, loop, op, &iv, true)) -+ return false; -+ /* The inductions must be regular, loop invariant step and initial -+ value. */ -+ if (!expr_invariant_in_loop_p (outer, iv.step) -+ || !expr_invariant_in_loop_p (outer, iv.base)) -+ return false; -+ /* XXX With more effort we could also be able to deal with inductions -+ where the initial value is loop variant but a simple IV in the -+ outer loop. The initial value for the second body would be -+ the original initial value plus iv.base.step. The next value -+ for the fused loop would be the original next value of the first -+ copy, _not_ the next value of the second body. */ -+ } -+ -+ return true; -+} -+ -+/* Fuse LOOP with all further neighbors. The loops are expected to -+ be in appropriate form. */ -+ -+static void -+fuse_loops (struct loop *loop) -+{ -+ struct loop *next = loop->next; -+ -+ while (next) -+ { -+ edge e; -+ -+ remove_branch (single_pred_edge (loop->latch)); -+ /* Make delete_basic_block not fiddle with the loop structure. */ -+ basic_block oldlatch = loop->latch; -+ loop->latch = NULL; -+ delete_basic_block (oldlatch); -+ e = redirect_edge_and_branch (loop_latch_edge (next), -+ loop->header); -+ loop->latch = e->src; -+ flush_pending_stmts (e); -+ -+ gcc_assert (EDGE_COUNT (next->header->preds) == 1); -+ -+ /* The PHI nodes of the second body (single-argument now) -+ need adjustments to use the right values: either directly -+ the value of the corresponding PHI in the first copy or -+ the one leaving the first body which unrolling did for us. -+ -+ See also unroll_jam_possible_p () for further possibilities. */ -+ gphi_iterator psi_first, psi_second; -+ e = single_pred_edge (next->header); -+ for (psi_first = gsi_start_phis (loop->header), -+ psi_second = gsi_start_phis (next->header); -+ !gsi_end_p (psi_first); -+ gsi_next (&psi_first), gsi_next (&psi_second)) -+ { -+ gphi *phi_first = psi_first.phi (); -+ gphi *phi_second = psi_second.phi (); -+ tree firstop = gimple_phi_result (phi_first); -+ /* The virtual operand is correct already as it's -+ always live at exit, hence has a LCSSA node and outer -+ loop unrolling updated SSA form. */ -+ if (virtual_operand_p (firstop)) -+ continue; -+ -+ /* Due to unroll_jam_possible_p () we know that this is -+ an induction. The second body goes over the same -+ iteration space. */ -+ add_phi_arg (phi_second, firstop, e, -+ gimple_location (phi_first)); -+ } -+ gcc_assert (gsi_end_p (psi_second)); -+ -+ merge_loop_tree (loop, next); -+ gcc_assert (!next->num_nodes); -+ struct loop *ln = next->next; -+ delete_loop (next); -+ next = ln; -+ } -+ rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_USE, loop); -+} -+ -+/* Returns true if the distance in DDR can be determined and adjusts -+ the unroll factor in *UNROLL to make unrolling valid for that distance. -+ Otherwise return false. -+ -+ If this data dep can lead to a removed memory reference, increment -+ *REMOVED and adjust *PROFIT_UNROLL to be the necessary unroll factor -+ for this to happen. */ -+ -+static bool -+adjust_unroll_factor (struct data_dependence_relation *ddr, -+ unsigned *unroll, unsigned *profit_unroll, -+ unsigned *removed) -+{ -+ bool ret = false; -+ if (DDR_ARE_DEPENDENT (ddr) != chrec_known) -+ { -+ if (DDR_NUM_DIST_VECTS (ddr) == 0) -+ return false; -+ unsigned i; -+ lambda_vector dist_v; -+ FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, dist_v) -+ { -+ /* A distance (a,b) is at worst transformed into (a/N,b) by the -+ unrolling (factor N), so the transformation is valid if -+ a >= N, or b > 0, or b is zero and a > 0. Otherwise the unroll -+ factor needs to be limited so that the first condition holds. -+ That may limit the factor down to zero in the worst case. */ -+ int dist = dist_v[0]; -+ if (dist < 0) -+ gcc_unreachable (); -+ else if ((unsigned)dist >= *unroll) -+ ; -+ else if (lambda_vector_lexico_pos (dist_v + 1, DDR_NB_LOOPS (ddr) - 1) -+ || (lambda_vector_zerop (dist_v + 1, DDR_NB_LOOPS (ddr) - 1) -+ && dist > 0)) -+ ; -+ else -+ *unroll = dist; -+ -+ /* With a distance (a,0) it's always profitable to unroll-and-jam -+ (by a+1), because one memory reference will go away. With -+ (a,b) and b != 0 that's less clear. We will increase the -+ number of streams without lowering the number of mem refs. -+ So for now only handle the first situation. */ -+ if (lambda_vector_zerop (dist_v + 1, DDR_NB_LOOPS (ddr) - 1)) -+ { -+ *profit_unroll = MAX (*profit_unroll, (unsigned)dist + 1); -+ (*removed)++; -+ } -+ -+ ret = true; -+ } -+ } -+ return ret; -+} -+ -+/* Main entry point for the unroll-and-jam transformation -+ described above. */ -+ -+static unsigned int -+tree_loop_unroll_and_jam (void) -+{ -+ struct loop *loop; -+ bool changed = false; -+ -+ gcc_assert (scev_initialized_p ()); -+ -+ /* Go through all innermost loops. */ -+ FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST) -+ { -+ struct loop *outer = loop_outer (loop); -+ -+ if (loop_depth (loop) < 2 -+ || optimize_loop_nest_for_size_p (outer)) -+ continue; -+ -+ if (!unroll_jam_possible_p (outer, loop)) -+ continue; -+ -+ vec datarefs; -+ vec dependences; -+ unsigned unroll_factor, profit_unroll, removed; -+ struct tree_niter_desc desc; -+ bool unroll = false; -+ -+ auto_vec loop_nest; -+ dependences.create (10); -+ datarefs.create (10); -+ if (!compute_data_dependences_for_loop (outer, true, &loop_nest, -+ &datarefs, &dependences)) -+ { -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ fprintf (dump_file, "Cannot analyze data dependencies\n"); -+ free_data_refs (datarefs); -+ free_dependence_relations (dependences); -+ return false; -+ } -+ if (!datarefs.length ()) -+ continue; -+ -+ if (dump_file && (dump_flags & TDF_DETAILS)) -+ dump_data_dependence_relations (dump_file, dependences); -+ -+ unroll_factor = (unsigned)-1; -+ profit_unroll = 1; -+ removed = 0; -+ -+ /* Check all dependencies. */ -+ unsigned i; -+ struct data_dependence_relation *ddr; -+ FOR_EACH_VEC_ELT (dependences, i, ddr) -+ { -+ struct data_reference *dra, *drb; -+ -+ /* If the refs are independend there's nothing to do. */ -+ if (DDR_ARE_DEPENDENT (ddr) == chrec_known) -+ continue; -+ dra = DDR_A (ddr); -+ drb = DDR_B (ddr); -+ /* Nothing interesting for the self dependencies. */ -+ if (dra == drb) -+ continue; -+ -+ /* Now check the distance vector, for determining a sensible -+ outer unroll factor, and for validity of merging the inner -+ loop copies. */ -+ if (!adjust_unroll_factor (ddr, &unroll_factor, &profit_unroll, -+ &removed)) -+ { -+ /* Couldn't get the distance vector. For two reads that's -+ harmless (we assume we should unroll). For at least -+ one write this means we can't check the dependence direction -+ and hence can't determine safety. */ -+ -+ if (DR_IS_WRITE (dra) || DR_IS_WRITE (drb)) -+ { -+ unroll_factor = 0; -+ break; -+ } -+ } -+ } -+ -+ /* We regard a user-specified minimum percentage of zero as a request -+ to ignore all profitability concerns and apply the transformation -+ always. */ -+ if (!PARAM_VALUE (PARAM_UNROLL_JAM_MIN_PERCENT)) -+ profit_unroll = 2; -+ else if (removed * 100 / datarefs.length () -+ < (unsigned)PARAM_VALUE (PARAM_UNROLL_JAM_MIN_PERCENT)) -+ profit_unroll = 1; -+ if (unroll_factor > profit_unroll) -+ unroll_factor = profit_unroll; -+ if (unroll_factor > (unsigned)PARAM_VALUE (PARAM_UNROLL_JAM_MAX_UNROLL)) -+ unroll_factor = PARAM_VALUE (PARAM_UNROLL_JAM_MAX_UNROLL); -+ unroll = (unroll_factor > 1 -+ && can_unroll_loop_p (outer, unroll_factor, &desc)); -+ -+ if (unroll) -+ { -+ if (dump_enabled_p ()) -+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, -+ find_loop_location (outer), -+ "applying unroll and jam with factor %d\n", -+ unroll_factor); -+ initialize_original_copy_tables (); -+ tree_unroll_loop (outer, unroll_factor, single_dom_exit (outer), -+ &desc); -+ free_original_copy_tables (); -+ fuse_loops (outer->inner); -+ changed = true; -+ } -+ -+ loop_nest.release (); -+ free_dependence_relations (dependences); -+ free_data_refs (datarefs); -+ } -+ -+ if (changed) -+ { -+ scev_reset (); -+ free_dominance_info (CDI_DOMINATORS); -+ return TODO_cleanup_cfg; -+ } -+ return 0; -+} -+ -+/* Pass boilerplate. */ -+ -+namespace { -+ -+const pass_data pass_data_loop_jam = -+{ -+ GIMPLE_PASS, /* type. */ -+ "unrolljam", /* name. */ -+ OPTGROUP_LOOP, /* optinfo_flags. */ -+ TV_LOOP_JAM, /* tv_id. */ -+ PROP_cfg, /* properties_required. */ -+ 0, /* properties_provided. */ -+ 0, /* properties_destroyed. */ -+ 0, /* todo_flags_start. */ -+ 0, /* todo_flags_finish. */ -+}; -+ -+class pass_loop_jam : public gimple_opt_pass -+{ -+public: -+ pass_loop_jam (gcc::context *ctxt) -+ : gimple_opt_pass (pass_data_loop_jam, ctxt) -+ {} -+ -+ /* opt_pass methods: */ -+ virtual bool gate (function *) -+ { -+ return flag_unroll_jam != 0; -+ } -+ virtual unsigned int execute (function *); -+ -+}; -+ -+unsigned int -+pass_loop_jam::execute (function *fun) -+{ -+ if (number_of_loops (fun) <= 1) -+ return 0; -+ -+ return tree_loop_unroll_and_jam (); -+} -+ -+} -+ -+gimple_opt_pass * -+make_pass_loop_jam (gcc::context *ctxt) -+{ -+ return new pass_loop_jam (ctxt); -+} -+ -diff -N -urp a/gcc/opts.c b/gcc/opts.c ---- a/gcc/opts.c 2018-11-07 11:37:24.891223860 +0800 -+++ b/gcc/opts.c 2018-11-07 11:38:26.171223860 +0800 -@@ -534,6 +534,7 @@ static const struct default_options defa - { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 }, -+ { OPT_LEVELS_3_PLUS, OPT_floop_unroll_and_jam, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 }, -diff -N -urp a/gcc/params.def b/gcc/params.def ---- a/gcc/params.def 2018-11-07 11:37:27.543223860 +0800 -+++ b/gcc/params.def 2018-11-07 11:38:26.171223860 +0800 -@@ -1280,6 +1280,16 @@ DEFPARAM (PARAM_VECT_EPILOGUES_NOMASK, - "Enable loop epilogue vectorization using smaller vector size.", - 0, 0, 1) - -+DEFPARAM (PARAM_UNROLL_JAM_MIN_PERCENT, -+ "unroll-jam-min-percent", -+ "Minimum percentage of memrefs that must go away for unroll-and-jam to be considered profitable.", -+ 1, 0, 100) -+ -+DEFPARAM (PARAM_UNROLL_JAM_MAX_UNROLL, -+ "unroll-jam-max-unroll", -+ "Maximum unroll factor for the unroll-and-jam transformation.", -+ 4, 0, 0) -+ - /* - - Local variables: -diff -N -urp a/gcc/passes.def b/gcc/passes.def ---- a/gcc/passes.def 2018-11-07 11:37:24.859223860 +0800 -+++ b/gcc/passes.def 2018-11-07 11:38:26.171223860 +0800 -@@ -272,6 +272,7 @@ along with GCC; see the file COPYING3. - NEXT_PASS (pass_tree_unswitch); - NEXT_PASS (pass_scev_cprop); - NEXT_PASS (pass_loop_split); -+ NEXT_PASS (pass_loop_jam); - /* All unswitching, final value replacement and splitting can expose - empty loops. Remove them now. */ - NEXT_PASS (pass_cd_dce); -diff -N -urp a/gcc/timevar.def b/gcc/timevar.def ---- a/gcc/timevar.def 2018-11-07 11:37:24.935223860 +0800 -+++ b/gcc/timevar.def 2018-11-07 11:38:26.175223860 +0800 -@@ -186,6 +186,7 @@ DEFTIMEVAR (TV_TREE_LOOP_IVCANON , " - DEFTIMEVAR (TV_SCEV_CONST , "scev constant prop") - DEFTIMEVAR (TV_TREE_LOOP_UNSWITCH , "tree loop unswitching") - DEFTIMEVAR (TV_LOOP_SPLIT , "loop splitting") -+DEFTIMEVAR (TV_LOOP_JAM , "unroll and jam") - DEFTIMEVAR (TV_COMPLETE_UNROLL , "complete unrolling") - DEFTIMEVAR (TV_TREE_PARALLELIZE_LOOPS, "tree parallelize loops") - DEFTIMEVAR (TV_TREE_VECTORIZATION , "tree vectorization") -diff -N -urp a/gcc/tree-pass.h b/gcc/tree-pass.h ---- a/gcc/tree-pass.h 2018-11-07 11:37:24.887223860 +0800 -+++ b/gcc/tree-pass.h 2018-11-07 11:38:26.175223860 +0800 -@@ -369,6 +369,7 @@ extern gimple_opt_pass *make_pass_tree_l - extern gimple_opt_pass *make_pass_lim (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_tree_unswitch (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_loop_split (gcc::context *ctxt); -+extern gimple_opt_pass *make_pass_loop_jam (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_predcom (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_iv_canon (gcc::context *ctxt); - extern gimple_opt_pass *make_pass_scev_cprop (gcc::context *ctxt); diff --git a/fstack-clash-protection.patch b/fstack-clash-protection.patch deleted file mode 100644 index ecbc766ef3c5c550c058177a00aa74342f08acb2..0000000000000000000000000000000000000000 --- a/fstack-clash-protection.patch +++ /dev/null @@ -1,768 +0,0 @@ -diff -N -urp a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c ---- a/gcc/combine-stack-adj.c 2017-01-20 08:05:30.925466000 +0800 -+++ b/gcc/combine-stack-adj.c 2019-01-10 17:10:16.606528459 +0800 -@@ -508,6 +508,8 @@ combine_stack_adjustments_for_block (bas - continue; - - set = single_set_for_csa (insn); -+ if (set && find_reg_note (insn, REG_STACK_CHECK, NULL_RTX)) -+ set = NULL_RTX; - if (set) - { - rtx dest = SET_DEST (set); -diff -N -urp a/gcc/common.opt b/gcc/common.opt ---- a/gcc/common.opt 2019-01-10 13:33:20.926185828 +0800 -+++ b/gcc/common.opt 2019-01-10 16:37:35.238476827 +0800 -@@ -2336,13 +2336,18 @@ Common Report Var(flag_variable_expansio - Apply variable expansion when loops are unrolled. - - fstack-check= --Common Report RejectNegative Joined -+Common Report RejectNegative Joined Optimization - -fstack-check=[no|generic|specific] Insert stack checking code into the program. - - fstack-check - Common Alias(fstack-check=, specific, no) - Insert stack checking code into the program. Same as -fstack-check=specific. - -+fstack-clash-protection -+Common Report Var(flag_stack_clash_protection) Optimization -+Insert code to probe each page of stack space as it is allocated to protect -+from stack-clash style attacks. -+ - fstack-limit - Common Var(common_deferred_options) Defer - -diff -N -urp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c ---- a/gcc/config/aarch64/aarch64.c 2019-01-10 13:33:20.914185828 +0800 -+++ b/gcc/config/aarch64/aarch64.c 2019-01-11 14:12:22.248521895 +0800 -@@ -3881,12 +3881,14 @@ aarch64_expand_prologue (void) - { - if (crtl->is_leaf && !cfun->calls_alloca) - { -- if (frame_size > PROBE_INTERVAL && frame_size > STACK_CHECK_PROTECT) -- aarch64_emit_probe_stack_range (STACK_CHECK_PROTECT, -- frame_size - STACK_CHECK_PROTECT); -+ if (frame_size > PROBE_INTERVAL -+ && frame_size > get_stack_check_protect ()) -+ aarch64_emit_probe_stack_range (get_stack_check_protect (), -+ (frame_size -+ - get_stack_check_protect ())); - } - else if (frame_size > 0) -- aarch64_emit_probe_stack_range (STACK_CHECK_PROTECT, frame_size); -+ aarch64_emit_probe_stack_range (get_stack_check_protect (), frame_size); - } - - aarch64_sub_sp (IP0_REGNUM, initial_adjust, true); -diff -N -urp a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c ---- a/gcc/config/i386/i386.c 2019-01-10 13:33:20.674185822 +0800 -+++ b/gcc/config/i386/i386.c 2019-01-28 10:55:37.006876481 +0800 -@@ -14396,7 +14396,7 @@ ix86_expand_prologue (void) - HOST_WIDE_INT size = allocate; - - if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000)) -- size = 0x80000000 - STACK_CHECK_PROTECT - 1; -+ size = 0x80000000 - get_stack_check_protect () - 1; - - if (TARGET_STACK_PROBE) - { -@@ -14406,18 +14406,21 @@ ix86_expand_prologue (void) - ix86_emit_probe_stack_range (0, size); - } - else -- ix86_emit_probe_stack_range (0, size + STACK_CHECK_PROTECT); -+ ix86_emit_probe_stack_range (0, -+ size + get_stack_check_protect ()); - } - else - { - if (crtl->is_leaf && !cfun->calls_alloca) - { -- if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT) -- ix86_emit_probe_stack_range (STACK_CHECK_PROTECT, -- size - STACK_CHECK_PROTECT); -+ if (size > PROBE_INTERVAL -+ && size > get_stack_check_protect ()) -+ ix86_emit_probe_stack_range (get_stack_check_protect (), -+ (size -+ - get_stack_check_protect ())); - } - else -- ix86_emit_probe_stack_range (STACK_CHECK_PROTECT, size); -+ ix86_emit_probe_stack_range (get_stack_check_protect (), size); - } - } - } -diff -N -urp a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c ---- a/gcc/config/ia64/ia64.c 2017-01-01 20:07:43.905435000 +0800 -+++ b/gcc/config/ia64/ia64.c 2019-01-28 10:58:37.582881234 +0800 -@@ -3481,15 +3481,16 @@ ia64_expand_prologue (void) - - if (crtl->is_leaf && !cfun->calls_alloca) - { -- if (size > PROBE_INTERVAL && size > STACK_CHECK_PROTECT) -- ia64_emit_probe_stack_range (STACK_CHECK_PROTECT, -- size - STACK_CHECK_PROTECT, -+ if (size > PROBE_INTERVAL && size > get_stack_check_protect ()) -+ ia64_emit_probe_stack_range (get_stack_check_protect (), -+ size - get_stack_check_protect (), - bs_size); -- else if (size + bs_size > STACK_CHECK_PROTECT) -- ia64_emit_probe_stack_range (STACK_CHECK_PROTECT, 0, bs_size); -+ else if (size + bs_size > get_stack_check_protect ()) -+ ia64_emit_probe_stack_range (get_stack_check_protect (), -+ 0, bs_size); - } - else if (size + bs_size > 0) -- ia64_emit_probe_stack_range (STACK_CHECK_PROTECT, size, bs_size); -+ ia64_emit_probe_stack_range (get_stack_check_protect (), size, bs_size); - } - - if (dump_file) -diff -N -urp a/gcc/coretypes.h b/gcc/coretypes.h ---- a/gcc/coretypes.h 2017-01-01 20:07:43.905435000 +0800 -+++ b/gcc/coretypes.h 2019-01-11 14:09:58.612518114 +0800 -@@ -371,6 +371,7 @@ typedef unsigned char uchar; - #include "input.h" - #include "is-a.h" - #include "memory-block.h" -+#include "dumpfile.h" - #endif /* GENERATOR_FILE && !USED_FOR_TARGET */ - - #endif /* coretypes.h */ -diff -N -urp a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi ---- a/gcc/doc/invoke.texi 2019-01-10 13:33:20.882185827 +0800 -+++ b/gcc/doc/invoke.texi 2019-01-10 16:40:40.066481692 +0800 -@@ -10050,6 +10050,21 @@ compilation without. The value for comp - needs to be more conservative (higher) in order to make tracer - effective. - -+@item stack-clash-protection-guard-size -+Specify the size of the operating system provided stack guard as -+2 raised to @var{num} bytes. The default value is 12 (4096 bytes). -+Acceptable values are between 12 and 30. Higher values may reduce the -+number of explicit probes, but a value larger than the operating system -+provided guard will leave code vulnerable to stack clash style attacks. -+ -+@item stack-clash-protection-probe-interval -+Stack clash protection involves probing stack space as it is allocated. This -+param controls the maximum distance between probes into the stack as 2 raised -+to @var{num} bytes. Acceptable values are between 10 and 16 and defaults to -+12. Higher values may reduce the number of explicit probes, but a value -+larger than the operating system provided guard will leave code vulnerable to -+stack clash style attacks. -+ - @item max-cse-path-length - - The maximum number of basic blocks on path that CSE considers. -@@ -11248,7 +11263,8 @@ target support in the compiler but comes - @enumerate - @item - Modified allocation strategy for large objects: they are always --allocated dynamically if their size exceeds a fixed threshold. -+allocated dynamically if their size exceeds a fixed threshold. Note this -+may change the semantics of some code. - - @item - Fixed limit on the size of the static frame of functions: when it is -@@ -11263,6 +11279,25 @@ generic implementation, code performance - Note that old-style stack checking is also the fallback method for - @samp{specific} if no target support has been added in the compiler. - -+@samp{-fstack-check=} is designed for Ada's needs to detect infinite recursion -+and stack overflows. @samp{specific} is an excellent choice when compiling -+Ada code. It is not generally sufficient to protect against stack-clash -+attacks. To protect against those you want @samp{-fstack-clash-protection}. -+ -+@item -fstack-clash-protection -+@opindex fstack-clash-protection -+Generate code to prevent stack clash style attacks. When this option is -+enabled, the compiler will only allocate one page of stack space at a time -+and each page is accessed immediately after allocation. Thus, it prevents -+allocations from jumping over any stack guard page provided by the -+operating system. -+ -+Most targets do not fully support stack clash protection. However, on -+those targets @option{-fstack-clash-protection} will protect dynamic stack -+allocations. @option{-fstack-clash-protection} may also provide limited -+protection for static stack allocations if the target supports -+@option{-fstack-check=specific}. -+ - @item -fstack-limit-register=@var{reg} - @itemx -fstack-limit-symbol=@var{sym} - @itemx -fno-stack-limit -diff -N -urp a/gcc/doc/tm.texi b/gcc/doc/tm.texi ---- a/gcc/doc/tm.texi 2017-04-05 01:52:27.193766000 +0800 -+++ b/gcc/doc/tm.texi 2019-01-10 16:50:44.006497591 +0800 -@@ -3419,6 +3419,10 @@ GCC computed the default from the values - normally not need to override that default. - @end defmac - -+@deftypefn {Target Hook} bool TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE (rtx @var{residual}) -+Some targets make optimistic assumptions about the state of stack probing when they emit their prologues. On such targets a probe into the end of any dynamically allocated space is likely required for safety against stack clash style attacks. Define this variable to return nonzero if such a probe is required or zero otherwise. You need not define this macro if it would always have the value zero. -+@end deftypefn -+ - @need 2000 - @node Frame Registers - @subsection Registers That Address the Stack Frame -diff -N -urp a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in ---- a/gcc/doc/tm.texi.in 2017-04-05 01:52:27.193766000 +0800 -+++ b/gcc/doc/tm.texi.in 2019-01-10 16:51:41.530499105 +0800 -@@ -2999,6 +2999,8 @@ GCC computed the default from the values - normally not need to override that default. - @end defmac - -+@hook TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE -+ - @need 2000 - @node Frame Registers - @subsection Registers That Address the Stack Frame -diff -N -urp a/gcc/explow.c b/gcc/explow.c ---- a/gcc/explow.c 2017-02-02 20:39:09.589196000 +0800 -+++ b/gcc/explow.c 2019-01-10 16:56:07.454506105 +0800 -@@ -39,8 +39,10 @@ along with GCC; see the file COPYING3. - #include "expr.h" - #include "common/common-target.h" - #include "output.h" -+#include "params.h" - - static rtx break_out_memory_refs (rtx); -+static void anti_adjust_stack_and_probe_stack_clash (rtx); - - - /* Truncate and perhaps sign-extend C as appropriate for MODE. */ -@@ -1271,6 +1273,29 @@ get_dynamic_stack_size (rtx *psize, unsi - *psize = size; - } - -+/* Return the number of bytes to "protect" on the stack for -fstack-check. -+ -+ "protect" in the context of -fstack-check means how many bytes we -+ should always ensure are available on the stack. More importantly -+ this is how many bytes are skipped when probing the stack. -+ -+ On some targets we want to reuse the -fstack-check prologue support -+ to give a degree of protection against stack clashing style attacks. -+ -+ In that scenario we do not want to skip bytes before probing as that -+ would render the stack clash protections useless. -+ -+ So we never use STACK_CHECK_PROTECT directly. Instead we indirect though -+ this helper which allows us to provide different values for -+ -fstack-check and -fstack-clash-protection. */ -+HOST_WIDE_INT -+get_stack_check_protect (void) -+{ -+ if (flag_stack_clash_protection) -+ return 0; -+ return STACK_CHECK_PROTECT; -+} -+ - /* Return an rtx representing the address of an area of memory dynamically - pushed on the stack. - -@@ -1429,7 +1454,7 @@ allocate_dynamic_stack_space (rtx size, - probe_stack_range (STACK_OLD_CHECK_PROTECT + STACK_CHECK_MAX_FRAME_SIZE, - size); - else if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK) -- probe_stack_range (STACK_CHECK_PROTECT, size); -+ probe_stack_range (get_stack_check_protect (), size); - - /* Don't let anti_adjust_stack emit notes. */ - suppress_reg_args_size = true; -@@ -1482,6 +1507,8 @@ allocate_dynamic_stack_space (rtx size, - - if (flag_stack_check && STACK_CHECK_MOVING_SP) - anti_adjust_stack_and_probe (size, false); -+ else if (flag_stack_clash_protection) -+ anti_adjust_stack_and_probe_stack_clash (size); - else - anti_adjust_stack (size); - -@@ -1757,6 +1784,237 @@ probe_stack_range (HOST_WIDE_INT first, - emit_insn (gen_blockage ()); - } - -+/* Compute parameters for stack clash probing a dynamic stack -+ allocation of SIZE bytes. -+ -+ We compute ROUNDED_SIZE, LAST_ADDR, RESIDUAL and PROBE_INTERVAL. -+ -+ Additionally we conditionally dump the type of probing that will -+ be needed given the values computed. */ -+ -+void -+compute_stack_clash_protection_loop_data (rtx *rounded_size, rtx *last_addr, -+ rtx *residual, -+ HOST_WIDE_INT *probe_interval, -+ rtx size) -+{ -+ /* Round SIZE down to STACK_CLASH_PROTECTION_PROBE_INTERVAL. */ -+ *probe_interval -+ = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL); -+ *rounded_size = simplify_gen_binary (AND, Pmode, size, -+ GEN_INT (-*probe_interval)); -+ -+ /* Compute the value of the stack pointer for the last iteration. -+ It's just SP + ROUNDED_SIZE. */ -+ rtx rounded_size_op = force_operand (*rounded_size, NULL_RTX); -+ *last_addr = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, -+ stack_pointer_rtx, -+ rounded_size_op), -+ NULL_RTX); -+ -+ /* Compute any residuals not allocated by the loop above. Residuals -+ are just the ROUNDED_SIZE - SIZE. */ -+ *residual = simplify_gen_binary (MINUS, Pmode, size, *rounded_size); -+ -+ /* Dump key information to make writing tests easy. */ -+ if (dump_file) -+ { -+ if (*rounded_size == CONST0_RTX (Pmode)) -+ fprintf (dump_file, -+ "Stack clash skipped dynamic allocation and probing loop.\n"); -+ else if (CONST_INT_P (*rounded_size) -+ && INTVAL (*rounded_size) <= 4 * *probe_interval) -+ fprintf (dump_file, -+ "Stack clash dynamic allocation and probing inline.\n"); -+ else if (CONST_INT_P (*rounded_size)) -+ fprintf (dump_file, -+ "Stack clash dynamic allocation and probing in " -+ "rotated loop.\n"); -+ else -+ fprintf (dump_file, -+ "Stack clash dynamic allocation and probing in loop.\n"); -+ -+ if (*residual != CONST0_RTX (Pmode)) -+ fprintf (dump_file, -+ "Stack clash dynamic allocation and probing residuals.\n"); -+ else -+ fprintf (dump_file, -+ "Stack clash skipped dynamic allocation and " -+ "probing residuals.\n"); -+ } -+} -+ -+/* Emit the start of an allocate/probe loop for stack -+ clash protection. -+ -+ LOOP_LAB and END_LAB are returned for use when we emit the -+ end of the loop. -+ -+ LAST addr is the value for SP which stops the loop. */ -+void -+emit_stack_clash_protection_probe_loop_start (rtx *loop_lab, -+ rtx *end_lab, -+ rtx last_addr, -+ bool rotated) -+{ -+ /* Essentially we want to emit any setup code, the top of loop -+ label and the comparison at the top of the loop. */ -+ *loop_lab = gen_label_rtx (); -+ *end_lab = gen_label_rtx (); -+ -+ emit_label (*loop_lab); -+ if (!rotated) -+ emit_cmp_and_jump_insns (stack_pointer_rtx, last_addr, EQ, NULL_RTX, -+ Pmode, 1, *end_lab); -+} -+ -+/* Emit the end of a stack clash probing loop. -+ -+ This consists of just the jump back to LOOP_LAB and -+ emitting END_LOOP after the loop. */ -+ -+void -+emit_stack_clash_protection_probe_loop_end (rtx loop_lab, rtx end_loop, -+ rtx last_addr, bool rotated) -+{ -+ if (rotated) -+ emit_cmp_and_jump_insns (stack_pointer_rtx, last_addr, NE, NULL_RTX, -+ Pmode, 1, loop_lab); -+ else -+ emit_jump (loop_lab); -+ -+ emit_label (end_loop); -+ -+} -+ -+/* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes) -+ while probing it. This pushes when SIZE is positive. SIZE need not -+ be constant. -+ -+ This is subtly different than anti_adjust_stack_and_probe to try and -+ prevent stack-clash attacks -+ -+ 1. It must assume no knowledge of the probing state, any allocation -+ must probe. -+ -+ Consider the case of a 1 byte alloca in a loop. If the sum of the -+ allocations is large, then this could be used to jump the guard if -+ probes were not emitted. -+ -+ 2. It never skips probes, whereas anti_adjust_stack_and_probe will -+ skip probes on the first couple PROBE_INTERVALs on the assumption -+ they're done elsewhere. -+ -+ 3. It only allocates and probes SIZE bytes, it does not need to -+ allocate/probe beyond that because this probing style does not -+ guarantee signal handling capability if the guard is hit. */ -+ -+static void -+anti_adjust_stack_and_probe_stack_clash (rtx size) -+{ -+ /* First ensure SIZE is Pmode. */ -+ if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode) -+ size = convert_to_mode (Pmode, size, 1); -+ -+ /* We can get here with a constant size on some targets. */ -+ rtx rounded_size, last_addr, residual; -+ HOST_WIDE_INT probe_interval; -+ compute_stack_clash_protection_loop_data (&rounded_size, &last_addr, -+ &residual, &probe_interval, size); -+ -+ if (rounded_size != CONST0_RTX (Pmode)) -+ { -+ if (CONST_INT_P (rounded_size) -+ && INTVAL (rounded_size) <= 4 * probe_interval) -+ { -+ for (HOST_WIDE_INT i = 0; -+ i < INTVAL (rounded_size); -+ i += probe_interval) -+ { -+ anti_adjust_stack (GEN_INT (probe_interval)); -+ -+ /* The prologue does not probe residuals. Thus the offset -+ here to probe just beyond what the prologue had already -+ allocated. */ -+ emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, -+ (probe_interval -+ - GET_MODE_SIZE (word_mode)))); -+ emit_insn (gen_blockage ()); -+ } -+ } -+ else -+ { -+ rtx loop_lab, end_loop; -+ bool rotate_loop = CONST_INT_P (rounded_size); -+ emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, -+ last_addr, rotate_loop); -+ -+ anti_adjust_stack (GEN_INT (probe_interval)); -+ -+ /* The prologue does not probe residuals. Thus the offset here -+ to probe just beyond what the prologue had already allocated. */ -+ emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, -+ (probe_interval -+ - GET_MODE_SIZE (word_mode)))); -+ -+ emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, -+ last_addr, rotate_loop); -+ emit_insn (gen_blockage ()); -+ } -+ } -+ -+ if (residual != CONST0_RTX (Pmode)) -+ { -+ rtx label = NULL_RTX; -+ /* RESIDUAL could be zero at runtime and in that case *sp could -+ hold live data. Furthermore, we do not want to probe into the -+ red zone. -+ -+ Go ahead and just guard the probe at *sp on RESIDUAL != 0 at -+ runtime if RESIDUAL is not a compile time constant. */ -+ if (!CONST_INT_P (residual)) -+ { -+ label = gen_label_rtx (); -+ emit_cmp_and_jump_insns (residual, CONST0_RTX (GET_MODE (residual)), -+ EQ, NULL_RTX, Pmode, 1, label); -+ } -+ -+ rtx x = force_reg (Pmode, plus_constant (Pmode, residual, -+ -GET_MODE_SIZE (word_mode))); -+ anti_adjust_stack (residual); -+ emit_stack_probe (gen_rtx_PLUS (Pmode, stack_pointer_rtx, x)); -+ emit_insn (gen_blockage ()); -+ if (!CONST_INT_P (residual)) -+ emit_label (label); -+ } -+ -+ /* Some targets make optimistic assumptions in their prologues about -+ how the caller may have probed the stack. Make sure we honor -+ those assumptions when needed. */ -+ if (size != CONST0_RTX (Pmode) -+ && targetm.stack_clash_protection_final_dynamic_probe (residual)) -+ { -+ /* SIZE could be zero at runtime and in that case *sp could hold -+ live data. Furthermore, we don't want to probe into the red -+ zone. -+ -+ Go ahead and just guard the probe at *sp on SIZE != 0 at runtime -+ if SIZE is not a compile time constant. */ -+ rtx label = NULL_RTX; -+ if (!CONST_INT_P (size)) -+ { -+ label = gen_label_rtx (); -+ emit_cmp_and_jump_insns (size, CONST0_RTX (GET_MODE (size)), -+ EQ, NULL_RTX, Pmode, 1, label); -+ } -+ -+ emit_stack_probe (stack_pointer_rtx); -+ emit_insn (gen_blockage ()); -+ if (!CONST_INT_P (size)) -+ emit_label (label); -+ } -+} -+ - /* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes) - while probing it. This pushes when SIZE is positive. SIZE need not - be constant. If ADJUST_BACK is true, adjust back the stack pointer -diff -N -urp a/gcc/explow.h b/gcc/explow.h ---- a/gcc/explow.h 2017-01-01 20:07:43.905435000 +0800 -+++ b/gcc/explow.h 2019-01-10 16:57:37.934508487 +0800 -@@ -69,6 +69,15 @@ extern void anti_adjust_stack (rtx); - /* Add some bytes to the stack while probing it. An rtx says how many. */ - extern void anti_adjust_stack_and_probe (rtx, bool); - -+/* Support for building allocation/probing loops for stack-clash -+ protection of dyamically allocated stack space. */ -+extern void compute_stack_clash_protection_loop_data (rtx *, rtx *, rtx *, -+ HOST_WIDE_INT *, rtx); -+extern void emit_stack_clash_protection_probe_loop_start (rtx *, rtx *, -+ rtx, bool); -+extern void emit_stack_clash_protection_probe_loop_end (rtx, rtx, -+ rtx, bool); -+ - /* This enum is used for the following two functions. */ - enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL}; - -diff -N -urp a/gcc/flag-types.h b/gcc/flag-types.h ---- a/gcc/flag-types.h 2017-01-01 20:07:43.905435000 +0800 -+++ b/gcc/flag-types.h 2019-01-10 16:42:11.490484099 +0800 -@@ -166,7 +166,14 @@ enum permitted_flt_eval_methods - PERMITTED_FLT_EVAL_METHODS_C11 - }; - --/* Type of stack check. */ -+/* Type of stack check. -+ -+ Stack checking is designed to detect infinite recursion and stack -+ overflows for Ada programs. Furthermore stack checking tries to ensure -+ in that scenario that enough stack space is left to run a signal handler. -+ -+ -fstack-check= does not prevent stack-clash style attacks. For that -+ you want -fstack-clash-protection. */ - enum stack_check_type - { - /* Do not check the stack. */ -diff -N -urp a/gcc/function.c b/gcc/function.c ---- a/gcc/function.c 2017-08-08 21:21:12.755378000 +0800 -+++ b/gcc/function.c 2019-01-10 17:07:17.414523742 +0800 -@@ -5695,6 +5695,58 @@ get_arg_pointer_save_area (void) - return ret; - } - -+ -+/* If debugging dumps are requested, dump information about how the -+ target handled -fstack-check=clash for the prologue. -+ -+ PROBES describes what if any probes were emitted. -+ -+ RESIDUALS indicates if the prologue had any residual allocation -+ (i.e. total allocation was not a multiple of PROBE_INTERVAL). */ -+ -+void -+dump_stack_clash_frame_info (enum stack_clash_probes probes, bool residuals) -+{ -+ if (!dump_file) -+ return; -+ -+ switch (probes) -+ { -+ case NO_PROBE_NO_FRAME: -+ fprintf (dump_file, -+ "Stack clash no probe no stack adjustment in prologue.\n"); -+ break; -+ case NO_PROBE_SMALL_FRAME: -+ fprintf (dump_file, -+ "Stack clash no probe small stack adjustment in prologue.\n"); -+ break; -+ case PROBE_INLINE: -+ fprintf (dump_file, "Stack clash inline probes in prologue.\n"); -+ break; -+ case PROBE_LOOP: -+ fprintf (dump_file, "Stack clash probe loop in prologue.\n"); -+ break; -+ } -+ -+ if (residuals) -+ fprintf (dump_file, "Stack clash residual allocation in prologue.\n"); -+ else -+ fprintf (dump_file, "Stack clash no residual allocation in prologue.\n"); -+ -+ if (frame_pointer_needed) -+ fprintf (dump_file, "Stack clash frame pointer needed.\n"); -+ else -+ fprintf (dump_file, "Stack clash no frame pointer needed.\n"); -+ -+ if (TREE_THIS_VOLATILE (cfun->decl)) -+ fprintf (dump_file, -+ "Stack clash noreturn prologue, assuming no implicit" -+ " probes in caller.\n"); -+ else -+ fprintf (dump_file, -+ "Stack clash not noreturn prologue.\n"); -+} -+ - /* Add a list of INSNS to the hash HASHP, possibly allocating HASHP - for the first time. */ - -diff -N -urp a/gcc/function.h b/gcc/function.h ---- a/gcc/function.h 2017-01-25 01:07:36.015431000 +0800 -+++ b/gcc/function.h 2019-01-10 17:08:12.806525200 +0800 -@@ -553,6 +553,14 @@ do { \ - ((TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn) \ - ? MAX (FUNCTION_BOUNDARY, 2 * BITS_PER_UNIT) : FUNCTION_BOUNDARY) - -+enum stack_clash_probes { -+ NO_PROBE_NO_FRAME, -+ NO_PROBE_SMALL_FRAME, -+ PROBE_INLINE, -+ PROBE_LOOP -+}; -+ -+extern void dump_stack_clash_frame_info (enum stack_clash_probes, bool); - - - extern void push_function_context (void); -diff -N -urp a/gcc/params.def b/gcc/params.def ---- a/gcc/params.def 2019-01-10 13:33:20.894185827 +0800 -+++ b/gcc/params.def 2019-01-10 16:43:15.414485782 +0800 -@@ -213,6 +213,16 @@ DEFPARAM(PARAM_STACK_FRAME_GROWTH, - "Maximal stack frame growth due to inlining (in percent).", - 1000, 0, 0) - -+DEFPARAM(PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE, -+ "stack-clash-protection-guard-size", -+ "Size of the stack guard expressed as a power of two.", -+ 12, 12, 30) -+ -+DEFPARAM(PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL, -+ "stack-clash-protection-probe-interval", -+ "Interval in which to probe the stack expressed as a power of two.", -+ 12, 10, 16) -+ - /* The GCSE optimization will be disabled if it would require - significantly more memory than this value. */ - DEFPARAM(PARAM_MAX_GCSE_MEMORY, -diff -N -urp a/gcc/reg-notes.def b/gcc/reg-notes.def ---- a/gcc/reg-notes.def 2017-03-28 05:00:35.674561000 +0800 -+++ b/gcc/reg-notes.def 2019-01-10 17:12:11.678531488 +0800 -@@ -223,6 +223,10 @@ REG_NOTE (ARGS_SIZE) - pseudo reg. */ - REG_NOTE (RETURNED) - -+/* Indicates the instruction is a stack check probe that should not -+ be combined with other stack adjustments. */ -+REG_NOTE (STACK_CHECK) -+ - /* Used to mark a call with the function decl called by the call. - The decl might not be available in the call due to splitting of the call - insn. This note is a SYMBOL_REF. */ -diff -N -urp a/gcc/rtl.h b/gcc/rtl.h ---- a/gcc/rtl.h 2017-03-14 20:47:42.745690000 +0800 -+++ b/gcc/rtl.h 2019-01-10 16:59:15.574511058 +0800 -@@ -2707,6 +2707,7 @@ get_full_set_src_cost (rtx x, machine_mo - /* In explow.c */ - extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, machine_mode); - extern rtx plus_constant (machine_mode, rtx, HOST_WIDE_INT, bool = false); -+extern HOST_WIDE_INT get_stack_check_protect (void); - - /* In rtl.c */ - extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL); -diff -N -urp a/gcc/sched-deps.c b/gcc/sched-deps.c ---- a/gcc/sched-deps.c 2017-01-01 20:07:43.905435000 +0800 -+++ b/gcc/sched-deps.c 2019-01-10 17:13:37.470533746 +0800 -@@ -4717,6 +4717,11 @@ parse_add_or_inc (struct mem_inc_info *m - if (RTX_FRAME_RELATED_P (insn) || !pat) - return false; - -+ /* Do not allow breaking data dependencies for insns that are marked -+ with REG_STACK_CHECK. */ -+ if (find_reg_note (insn, REG_STACK_CHECK, NULL)) -+ return false; -+ - /* Result must be single reg. */ - if (!REG_P (SET_DEST (pat))) - return false; -diff -N -urp a/gcc/target.def b/gcc/target.def ---- a/gcc/target.def 2019-01-10 13:33:20.762185824 +0800 -+++ b/gcc/target.def 2019-01-10 17:01:49.146515100 +0800 -@@ -5490,6 +5490,12 @@ these registers when the target switches - void, (void), - hook_void_void) - -+DEFHOOK -+(stack_clash_protection_final_dynamic_probe, -+ "Some targets make optimistic assumptions about the state of stack probing when they emit their prologues. On such targets a probe into the end of any dynamically allocated space is likely required for safety against stack clash style attacks. Define this variable to return nonzero if such a probe is required or zero otherwise. You need not define this macro if it would always have the value zero.", -+ bool, (rtx residual), -+ default_stack_clash_protection_final_dynamic_probe) -+ - /* Functions specific to the C family of frontends. */ - #undef HOOK_PREFIX - #define HOOK_PREFIX "TARGET_C_" -diff -N -urp a/gcc/targhooks.c b/gcc/targhooks.c ---- a/gcc/targhooks.c 2017-02-07 19:29:06.644837000 +0800 -+++ b/gcc/targhooks.c 2019-01-10 17:03:23.818517592 +0800 -@@ -2107,4 +2107,10 @@ default_excess_precision (enum excess_pr - return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT; - } - -+bool -+default_stack_clash_protection_final_dynamic_probe (rtx residual ATTRIBUTE_UNUSED) -+{ -+ return 0; -+} -+ - #include "gt-targhooks.h" -diff -N -urp a/gcc/targhooks.h b/gcc/targhooks.h ---- a/gcc/targhooks.h 2017-04-05 01:52:27.193766000 +0800 -+++ b/gcc/targhooks.h 2019-01-10 17:04:11.438518846 +0800 -@@ -263,5 +263,6 @@ extern unsigned int default_min_arithmet - - extern enum flt_eval_method - default_excess_precision (enum excess_precision_type ATTRIBUTE_UNUSED); -+extern bool default_stack_clash_protection_final_dynamic_probe (rtx); - - #endif /* GCC_TARGHOOKS_H */ -diff -N -urp a/gcc/toplev.c b/gcc/toplev.c ---- a/gcc/toplev.c 2017-09-15 16:18:34.015147000 +0800 -+++ b/gcc/toplev.c 2019-01-10 16:45:33.626489420 +0800 -@@ -1573,6 +1573,26 @@ process_options (void) - flag_associative_math = 0; - } - -+ /* -fstack-clash-protection is not currently supported on targets -+ where the stack grows up. */ -+ if (flag_stack_clash_protection && !STACK_GROWS_DOWNWARD) -+ { -+ warning_at (UNKNOWN_LOCATION, 0, -+ "%<-fstack-clash-protection%> is not supported on targets " -+ "where the stack grows from lower to higher addresses"); -+ flag_stack_clash_protection = 0; -+ } -+ -+ /* We can not support -fstack-check= and -fstack-clash-protection at -+ the same time. */ -+ if (flag_stack_check != NO_STACK_CHECK && flag_stack_clash_protection) -+ { -+ warning_at (UNKNOWN_LOCATION, 0, -+ "%<-fstack-check=%> and %<-fstack-clash_protection%> are " -+ "mutually exclusive. Disabling %<-fstack-check=%>"); -+ flag_stack_check = NO_STACK_CHECK; -+ } -+ - /* With -fcx-limited-range, we do cheap and quick complex arithmetic. */ - if (flag_cx_limited_range) - flag_complex_method = 0; diff --git a/gcc-7.3.0.tar.gz b/gcc-9.3.0.tar.xz similarity index 61% rename from gcc-7.3.0.tar.gz rename to gcc-9.3.0.tar.xz index 342d66a28638f7c5178d4dead24be4b8aeefd1e2..36d54ee1c18e3ba1c6d8c18f1c2c93b034010bb9 100644 Binary files a/gcc-7.3.0.tar.gz and b/gcc-9.3.0.tar.xz differ diff --git a/gcc-adapt-to-isl.patch b/gcc-adapt-to-isl.patch deleted file mode 100644 index b82e0680fd777e2f0aba183cb58bafa7274c5b9c..0000000000000000000000000000000000000000 --- a/gcc-adapt-to-isl.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/gcc/graphite.h b/gcc/graphite.h -index 4e0e58c..be0a22b 100644 (file) ---- a/gcc/graphite.h -+++ b/gcc/graphite.h -@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see - #include - #include - #include -+#include -+#include - - typedef struct poly_dr *poly_dr_p; diff --git a/gcc.spec b/gcc.spec index df294bd4041a085b9fd8eaa7c644bb2c672b9a7f..33e91fdb1d5c2d8e84c44a4daa6a22d234dda113 100644 --- a/gcc.spec +++ b/gcc.spec @@ -1,127 +1,194 @@ -%global DATE 20190804 -%define debug_package %{nil} - -%global gcc_version 7.3.0 -%global gcc_release 20190804 -%global isl_version 0.14 -%global cloog_version 0.18.4 - -%define compat_gcc_provides 7777777 +%global DATE 20200428 +%global gcc_version 9.3.0 +%global gcc_major 9.3.0 +%global gcc_release 20200312 %global _unpackaged_files_terminate_build 0 -%undefine _annotated_build +%global _performance_build 1 -%global gcc_target_platform %{_arch}-linux-gnu +%undefine _hardened_build +%undefine _annotated_build %global build_ada 0 -%global build_java 0 +%global build_objc 1 %global build_go 0 -%ifarch aarch64 -%global build_libquadmath 0 -%endif -%ifarch x86_64 +%global build_d 0 +%global build_check 0 +%ifarch %{ix86} x86_64 ia64 ppc64le %global build_libquadmath 1 +%else +%global build_libquadmath 0 %endif +%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 %global build_libasan 1 +%else +%global build_libasan 0 +%endif +%ifarch x86_64 ppc64 ppc64le aarch64 +%global build_libtsan 1 +%else +%global build_libtsan 0 +%endif +%ifarch x86_64 ppc64 ppc64le aarch64 +%global build_liblsan 1 +%else +%global build_liblsan 0 +%endif +%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 +%global build_libubsan 1 +%else +%global build_libubsan 0 +%endif +%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 %{mips} %global build_libatomic 1 +%else +%global build_libatomic 0 +%endif +%ifarch %{ix86} x86_64 %{arm} alpha ppc ppc64 ppc64le ppc64p7 s390 s390x aarch64 %global build_libitm 1 -%global attr_ifunc 1 -%global build_cloog 1 +%else +%global build_libitm 0 +%endif +%global build_isl 0 %global build_libstdcxx_docs 0 -%global build_java_tar 0 -%global build_libtsan 1 -%global build_libilp32 0 -%global build_check 0 +%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64 %{mips} +%global attr_ifunc 1 +%else +%global attr_ifunc 0 +%endif -Summary: Various compilers (C, C++, Objective-C, Java, ...) +Summary: Various compilers (C, C++, Objective-C, ...) Name: gcc -Version: 7.3.0 -Release: %{gcc_release}.h31 +Version: %{gcc_version} +Release: %{gcc_release}.h1 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD -Group: Development/Languages -#Source0: hcc-aarch64-linux-release.tar.bz2 -Source0: gcc-%{version}.tar.gz -Source1: isl-%{isl_version}.tar.xz -Source2: cloog-%{cloog_version}.tar.gz +Source0: gcc-%{version}.tar.xz +%global isl_version 0.16.1 + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: gmp libmpc-devel mpfr gmp-devel glibc-headers gcc-c++ mpfr-devel -#BuildRequires: gmp mpfr gmp-devel glibc-headers gcc-c++ mpfr-devel mpc -%ifarch aarch64 -%if %{build_libilp32} -BuildRequires: glibc-32-headers +BuildRequires: binutils >= 2.31 +BuildRequires: glibc-headers +BuildRequires: libtool, zlib-devel, texinfo, flex, bison +BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1, libmpc-devel >= 0.8.1 +BuildRequires: gcc, gcc-c++ +%if %{build_go} +BuildRequires: hostname, procps %endif +BuildRequires: gdb +BuildRequires: glibc-devel >= 2.16 +%ifarch %{multilib_64_archs} sparcv9 ppc +BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so +%endif +%if %{build_ada} +BuildRequires: gcc-gnat >= 3.1, libgnat >= 3.1 +%endif +%ifarch ia64 +BuildRequires: libunwind >= 0.98 +%endif +%if %{build_isl} +BuildRequires: isl = %{isl_version} +BuildRequires: isl-devel = %{isl_version} +%if 0%{?__isa_bits} == 64 +Requires: libisl.so.15()(64bit) +%else +Requires: libisl.so.15 +%endif +%endif +%if %{build_libstdcxx_docs} +BuildRequires: doxygen >= 1.7.1 +BuildRequires: graphviz, dblatex, texlive-collection-latex, docbook5-style-xsl %endif - Requires: cpp = %{version}-%{release} -Requires: binutils >= 2.20.51.0.2-12 -Requires: glibc-devel >= 2.2.90-12 -Requires: glibc >= 2.16 +Requires: binutils >= 2.31 +Conflicts: gdb < 5.1-2 +Requires: glibc-devel >= 2.16 Requires: libgcc >= %{version}-%{release} Requires: libgomp = %{version}-%{release} -Provides: bundled(libiberty) -Provides: gcc = %{compat_gcc_provides} -Provides: gcc(major) = 7.3.0 -BuildRequires: libtool zlib-devel texinfo - -Patch1: fix-operand-size-mismatch-for-i386-sse.patch -Patch2: gcc-adapt-to-isl.patch -Patch3: sanitizer-pr-85835.patch -Patch4: CVE-2018-12886.patch -Patch5: CVE-2019-15847.patch -Patch6: option-mlong-calls.patch -Patch7: add-tsv110-pipeline-scheduling.patch -Patch8: option-mfentry-and-mlong-calls-bugfix.patch -Patch10: aarch64-ilp32-call-addr-dimode.patch -Patch12: aarch64-fix-tls-negative-offset.patch -Patch14: arm-fix-push-minipool.patch -Patch22: arm-bigendian-disable-interleaved-LS-vectorize.patch -Patch23: floop-unroll-and-jam.patch -Patch24: floop-interchange.patch -Patch25: constructor-priority-bugfix.patch -Patch26: arm-adjust-be-ldrd-strd.patch -Patch28: try-unroll.patch -Patch29: Big-endian-union-bitfield-bugfix.patch -Patch31: fstack-clash-protection.patch -Patch34: mark-pattern-as-clobbering-CC-REGNUM.patch -Patch35: turn-on-funwind-tables-by-default.patch - - -#AutoReqProv: off +%if !%{build_ada} +Obsoletes: gcc-gnat < %{version}-%{release} +%endif +Obsoletes: gcc-java < %{version}-%{release} AutoReq: true +Provides: bundled(libiberty) +Provides: gcc(major) = %{gcc_major} + +Patch0: enable-aarch64-libquadmath.patch +Patch1: generate-csel.patch +Patch2: delete-incorrect-smw.patch +Patch3: remove-array-index-inliner-hint.patch +Patch4: ivopts-1.patch +Patch5: ivopts-2.patch +Patch6: dont-generate-IF_THEN_ELSE.patch +Patch7: fix-cost-of-plus.patch +Patch8: div-opti.patch +Patch9: fix-SYMBOL_TINY_GOT-handling-for-ILP32.patch +Patch10: fix-ICE-during-pass-ccp.patch +Patch11: loop-split.patch +Patch12: loop-finite.patch +Patch13: loop-finite-bugfix.patch +Patch14: fix-regno-out-of-range.patch +Patch15: fix-ICE-in-vectorizable-load.patch +Patch16: address-calculation-optimization-within-loop.patch +Patch17: skip-debug-insns-when-computing-inline-costs.patch +%global gcc_target_platform %{_arch}-linux-gnu -%package -n libgcc -Summary: GCC version 7.3.0 shared support library -Group: System Environment/Libraries -Autoreq: false -Provides: libgcc = %{compat_gcc_provides} +%if %{build_go} +# Avoid stripping these libraries and binaries. +%global __os_install_post \ +chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.14.* \ +chmod 644 %{buildroot}%{_prefix}/bin/go.gcc \ +chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc \ +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \ +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid \ +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json \ +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet \ +%__os_install_post \ +chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgo.so.14.* \ +chmod 755 %{buildroot}%{_prefix}/bin/go.gcc \ +chmod 755 %{buildroot}%{_prefix}/bin/gofmt.gcc \ +chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \ +chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid \ +chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json \ +chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet \ +%{nil} +%endif -%description -n libgcc -This package contains GCC shared support library which is needed -e.g. for exception handling support. +%description +The gcc package contains the GNU Compiler Collection version 9. +You'll need this package in order to compile C code. -%ifarch aarch64 -%if %{build_libilp32} -%package -n libgcc-32 -Summary: GCC version 7.3.0 shared support library -Group: System Environment/Libraries +%package -n libgcc +Summary: GCC version 9 shared support library Autoreq: false -Provides: libgcc = %{compat_gcc_provides} +%if !%{build_ada} +Obsoletes: libgnat < %{version}-%{release} +%endif +Obsoletes: libmudflap +Obsoletes: libmudflap-devel +Obsoletes: libmudflap-static +Obsoletes: libgcj < %{version}-%{release} +Obsoletes: libgcj-devel < %{version}-%{release} +Obsoletes: libgcj-src < %{version}-%{release} +%ifarch %{ix86} x86_64 +Obsoletes: libcilkrts +Obsoletes: libcilkrts-static +Obsoletes: libmpx +Obsoletes: libmpx-static +%endif -%description -n libgcc-32 +%description -n libgcc This package contains GCC shared support library which is needed e.g. for exception handling support. -%endif -%endif %package c++ Summary: C++ support for GCC -Group: Development/Languages Requires: gcc = %{version}-%{release} Requires: libstdc++ = %{version}-%{release} Requires: libstdc++-devel = %{version}-%{release} +Provides: gcc-g++ = %{version}-%{release} +Provides: g++ = %{version}-%{release} Autoreq: true -Provides: gcc-c++ = %{compat_gcc_provides} %description c++ This package adds C++ support to the GNU Compiler Collection. @@ -130,10 +197,8 @@ including templates and exception handling. %package -n libstdc++ Summary: GNU Standard C++ Library -Group: System Environment/Libraries Autoreq: true Requires: glibc >= 2.10.90-7 -Provides: libstdc++ = %{compat_gcc_provides} %description -n libstdc++ The libstdc++ package contains a rewritten standard compliant GCC Standard @@ -141,10 +206,8 @@ C++ Library. %package -n libstdc++-devel Summary: Header files and libraries for C++ development -Group: Development/Libraries Requires: libstdc++%{?_isa} = %{version}-%{release} Autoreq: true -Provides: libstdc++-devel = %{compat_gcc_provides} %description -n libstdc++-devel This is the GNU implementation of the standard C++ libraries. This @@ -153,36 +216,25 @@ development. This includes rewritten implementation of STL. %package -n libstdc++-static Summary: Static libraries for the GNU standard C++ library -Group: Development/Libraries Requires: libstdc++-devel = %{version}-%{release} Autoreq: true -Provides: libstdc++-static = %{compat_gcc_provides} %description -n libstdc++-static Static libraries for the GNU standard C++ library. -%ifarch aarch64 -%if %{build_libilp32} -%package -n libstdc++-32 -Summary: GNU Standard C++ Library -Group: System Environment/Libraries +%package -n libstdc++-docs +Summary: Documentation for the GNU standard C++ library Autoreq: true -Requires: glibc >= 2.10.90-7 -Provides: libstdc++ = %{compat_gcc_provides} -%description -n libstdc++-32 -The libstdc++ package contains a rewritten standard compliant GCC Standard -C++ Library. -%endif -%endif +%description -n libstdc++-docs +Manual, doxygen generated API information and Frequently Asked Questions +for the GNU standard C++ library. %package objc Summary: Objective-C support for GCC -Group: Development/Languages Requires: gcc = %{version}-%{release} Requires: libobjc = %{version}-%{release} Autoreq: true -Provides: gcc-objc = %{compat_gcc_provides} %description objc gcc-objc provides Objective-C support for the GCC. @@ -191,43 +243,126 @@ object-oriented derivative of the C language. %package objc++ Summary: Objective-C++ support for GCC -Group: Development/Languages Requires: gcc-c++ = %{version}-%{release}, gcc-objc = %{version}-%{release} Autoreq: true -Provides: gcc-objc++ = %{compat_gcc_provides} %description objc++ gcc-objc++ package provides Objective-C++ support for the GCC. %package -n libobjc Summary: Objective-C runtime -Group: System Environment/Libraries Autoreq: true -Provides: libobjc = %{compat_gcc_provides} %description -n libobjc This package contains Objective-C shared library which is needed to run Objective-C dynamically linked programs. -%ifarch aarch64 -%if %{build_libilp32} -%package -n libobjc-32 -Summary: Objective-C runtime -Group: System Environment/Libraries +%package gfortran +Summary: Fortran support +Requires: gcc = %{version}-%{release} +Requires: libgfortran = %{version}-%{release} +%if %{build_libquadmath} +Requires: libquadmath = %{version}-%{release} +Requires: libquadmath-devel = %{version}-%{release} +%endif +Provides: gcc-fortran = %{version}-%{release} +Provides: gfortran = %{version}-%{release} Autoreq: true -Provides: libobjc = %{compat_gcc_provides} -%description -n libobjc-32 -This package contains Objective-C shared library which is needed to run -Objective-C dynamically linked programs. +%description gfortran +The gcc-gfortran package provides support for compiling Fortran +programs with the GNU Compiler Collection. + +%package -n libgfortran +Summary: Fortran runtime +Autoreq: true +%if %{build_libquadmath} +Requires: libquadmath = %{version}-%{release} %endif + +%description -n libgfortran +This package contains Fortran shared library which is needed to run +Fortran dynamically linked programs. + +%package -n libgfortran-static +Summary: Static Fortran libraries +Requires: libgfortran = %{version}-%{release} +Requires: gcc = %{version}-%{release} +%if %{build_libquadmath} +Requires: libquadmath-static = %{version}-%{release} %endif +%description -n libgfortran-static +This package contains static Fortran libraries. + +%package gdc +Summary: D support +Requires: gcc = %{version}-%{release} +Requires: libgphobos = %{version}-%{release} +Provides: gcc-d = %{version}-%{release} +Provides: gdc = %{version}-%{release} +Autoreq: true + +%description gdc +The gcc-gdc package provides support for compiling D +programs with the GNU Compiler Collection. + +%package -n libgphobos +Summary: D runtime +Autoreq: true + +%description -n libgphobos +This package contains D shared library which is needed to run +D dynamically linked programs. + +%package -n libgphobos-static +Summary: Static D libraries +Requires: libgphobos = %{version}-%{release} +Requires: gcc-gdc = %{version}-%{release} + +%description -n libgphobos-static +This package contains static D libraries. + +%package -n libgomp +Summary: GCC OpenMP v4.5 shared support library + +%description -n libgomp +This package contains GCC shared support library which is needed +for OpenMP v4.5 support. + +%package gdb-plugin +Summary: GCC plugin for GDB +Requires: gcc = %{version}-%{release} + +%description gdb-plugin +This package contains GCC plugin for GDB C expression evaluation. + +%package -n libquadmath +Summary: GCC __float128 shared support library + +%description -n libquadmath +This package contains GCC shared support library which is needed +for __float128 math support and for Fortran REAL*16 support. + +%package -n libquadmath-devel +Summary: GCC __float128 support +Requires: libquadmath = %{version}-%{release} +Requires: gcc = %{version}-%{release} + +%description -n libquadmath-devel +This package contains headers for building Fortran programs using +REAL*16 and programs using __float128 math. + +%package -n libquadmath-static +Summary: Static libraries for __float128 support +Requires: libquadmath-devel = %{version}-%{release} + +%description -n libquadmath-static +This package contains static libraries for building Fortran programs +using REAL*16 and programs using __float128 math. + %package -n libitm Summary: The GNU Transactional Memory library -Group: System Environment/Libraries -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info %description -n libitm This package contains the GNU Transactional Memory library @@ -235,7 +370,6 @@ which is a GCC transactional memory support runtime library. %package -n libitm-devel Summary: The GNU Transactional Memory support -Group: Development/Libraries Requires: libitm = %{version}-%{release} Requires: gcc = %{version}-%{release} @@ -245,7 +379,6 @@ GNU Transactional Memory library. %package -n libitm-static Summary: The GNU Transactional Memory static library -Group: Development/Libraries Requires: libitm-devel = %{version}-%{release} %description -n libitm-static @@ -253,9 +386,6 @@ This package contains GNU Transactional Memory static libraries. %package -n libatomic Summary: The GNU Atomic library -Group: System Environment/Libraries -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info %description -n libatomic This package contains the GNU Atomic library @@ -264,7 +394,6 @@ by hardware. %package -n libatomic-static Summary: The GNU Atomic static library -Group: Development/Libraries Requires: libatomic = %{version}-%{release} %description -n libatomic-static @@ -272,9 +401,6 @@ This package contains GNU Atomic static libraries. %package -n libasan Summary: The Address Sanitizer runtime library -Group: System Environment/Libraries -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info %description -n libasan This package contains the Address Sanitizer library @@ -282,7 +408,6 @@ which is used for -fsanitize=address instrumented programs. %package -n libasan-static Summary: The Address Sanitizer static library -Group: Development/Libraries Requires: libasan = %{version}-%{release} %description -n libasan-static @@ -290,9 +415,6 @@ This package contains Address Sanitizer static runtime library. %package -n libtsan Summary: The Thread Sanitizer runtime library -Group: System Environment/Libraries -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info %description -n libtsan This package contains the Thread Sanitizer library @@ -300,100 +422,44 @@ which is used for -fsanitize=thread instrumented programs. %package -n libtsan-static Summary: The Thread Sanitizer static library -Group: Development/Libraries Requires: libtsan = %{version}-%{release} %description -n libtsan-static This package contains Thread Sanitizer static runtime library. -%package plugin-devel -Summary: Support for compiling GCC plugins -Group: Development/Languages -Requires: gcc = %{version}-%{release} -Requires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1, libmpc-devel >= 0.8.1 +%package -n libubsan +Summary: The Undefined Behavior Sanitizer runtime library -%description plugin-devel -This package contains header files and other support files -for compiling GCC plugins. The GCC plugin ABI is currently -not stable, so plugins must be rebuilt any time GCC is updated. +%description -n libubsan +This package contains the Undefined Behavior Sanitizer library +which is used for -fsanitize=undefined instrumented programs. -%package gfortran -Summary: Fortran support -Group: Development/Languages -Requires: gcc = %{version}-%{release} -Requires: libgfortran = %{version}-%{release} -BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1, libmpc-devel >= 0.8.1 -%if %{build_libquadmath} -Requires: libquadmath = %{version}-%{release} -Requires: libquadmath-devel = %{version}-%{release} -%endif -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info -Autoreq: true -Provides: gcc-gfortran = %{compat_gcc_provides} - -%description gfortran -The gcc-gfortran package provides support for compiling Fortran -programs with the GNU Compiler Collection. - -%package -n libgfortran -Summary: Fortran runtime -Group: System Environment/Libraries -Autoreq: true -Provides: libgfortran = %{compat_gcc_provides} -%if %{build_libquadmath} -Requires: libquadmath = %{version}-%{release} -%endif - -%description -n libgfortran -This package contains Fortran shared library which is needed to run -Fortran dynamically linked programs. +%package -n libubsan-static +Summary: The Undefined Behavior Sanitizer static library +Requires: libubsan = %{version}-%{release} -%package -n libgomp -Summary: GCC OpenMP v3.0 shared support library -Group: System Environment/Libraries -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info -Provides: libgomp = %{compat_gcc_provides} - -%description -n libgomp -This package contains GCC shared support library which is needed -for OpenMP v3.0 support. +%description -n libubsan-static +This package contains Undefined Behavior Sanitizer static runtime library. -%ifarch aarch64 -%if %{build_libilp32} -%package -n libgfortran-32 -Summary: Fortran runtime -Group: System Environment/Libraries -Autoreq: true -Provides: libgfortran = %{compat_gcc_provides} +%package -n liblsan +Summary: The Leak Sanitizer runtime library -%description -n libgfortran-32 -This package contains Fortran shared library which is needed to run -Fortran dynamically linked programs. +%description -n liblsan +This package contains the Leak Sanitizer library +which is used for -fsanitize=leak instrumented programs. -%package -n libgomp-32 -Summary: GCC OpenMP v3.0 shared support library -Group: System Environment/Libraries -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info -Provides: libgomp = %{compat_gcc_provides} +%package -n liblsan-static +Summary: The Leak Sanitizer static library +Requires: liblsan = %{version}-%{release} -%description -n libgomp-32 -This package contains GCC shared support library which is needed -for OpenMP v3.0 support. -%endif -%endif +%description -n liblsan-static +This package contains Leak Sanitizer static runtime library. %package -n cpp Summary: The C Preprocessor -Group: Development/Languages Requires: filesystem >= 3 Provides: /lib/cpp -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info Autoreq: true -Provides: cpp = %{compat_gcc_provides} %description -n cpp Cpp is the GNU C-Compatible Compiler Preprocessor. @@ -403,7 +469,6 @@ compilation. It is called a macro processor because it allows you to define macros, abbreviations for longer constructs. - The C preprocessor provides four separate functionalities: the inclusion of header files (files of declarations that can be substituted into your program); macro expansion (you can define macros, @@ -418,75 +483,95 @@ compiler about where each source line originated). You should install this package if you are a C programmer and you use macros. -%description -This is compiler for arm64. -%ifarch x86_64 -%package -n libquadmath -Summary: GCC __float128 shared support library -Group: System Environment/Libraries -Requires(post): /sbin/install-info -Requires(preun): /sbin/install-info +%package gnat +Summary: Ada 83, 95, 2005 and 2012 support for GCC +Requires: gcc = %{version}-%{release} +Requires: libgnat = %{version}-%{release}, libgnat-devel = %{version}-%{release} +Autoreq: true -%description -n libquadmath -This package contains GCC shared support library which is needed -for __float128 math support and for Fortran REAL*16 support. +%description gnat +GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes +development tools, the documents and Ada compiler. -%package -n libquadmath-devel -Summary: GCC __float128 support -Group: Development/Libraries -Requires: libquadmath = %{version}-%{release} +%package -n libgnat +Summary: GNU Ada 83, 95, 2005 and 2012 runtime shared libraries +Autoreq: true + +%description -n libgnat +GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes +shared libraries, which are required to run programs compiled with the GNAT. + +%package -n libgnat-devel +Summary: GNU Ada 83, 95, 2005 and 2012 libraries +Autoreq: true + +%description -n libgnat-devel +GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes +libraries, which are required to compile with the GNAT. + +%package -n libgnat-static +Summary: GNU Ada 83, 95, 2005 and 2012 static libraries +Requires: libgnat-devel = %{version}-%{release} +Autoreq: true + +%description -n libgnat-static +GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes +static libraries. + +%package go +Summary: Go support Requires: gcc = %{version}-%{release} +Requires: libgo = %{version}-%{release} +Requires: libgo-devel = %{version}-%{release} +Requires(post): %{_sbindir}/update-alternatives +Requires(postun): %{_sbindir}/update-alternatives +Provides: gccgo = %{version}-%{release} +Autoreq: true -%description -n libquadmath-devel -This package contains headers for building Fortran programs using -REAL*16 and programs using __float128 math. +%description go +The gcc-go package provides support for compiling Go programs +with the GNU Compiler Collection. -%package -n libquadmath-static -Summary: Static libraries for __float128 support -Group: Development/Libraries -Requires: libquadmath-devel = %{version}-%{release} +%package -n libgo +Summary: Go runtime +Autoreq: true -%description -n libquadmath-static -This package contains static libraries for building Fortran programs -using REAL*16 and programs using __float128 math. +%description -n libgo +This package contains Go shared library which is needed to run +Go dynamically linked programs. -%endif +%package -n libgo-devel +Summary: Go development libraries +Requires: libgo = %{version}-%{release} +Autoreq: true + +%description -n libgo-devel +This package includes libraries and support files for compiling +Go programs. + +%package -n libgo-static +Summary: Static Go libraries +Requires: libgo = %{version}-%{release} +Requires: gcc = %{version}-%{release} + +%description -n libgo-static +This package contains static Go libraries. + +%package plugin-devel +Summary: Support for compiling GCC plugins +Requires: gcc = %{version}-%{release} +Requires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1, libmpc-devel >= 0.8.1 + +%description plugin-devel +This package contains header files and other support files +for compiling GCC plugins. The GCC plugin ABI is currently +not stable, so plugins must be rebuilt any time GCC is updated. -%if 0%{?_enable_debug_packages} -%define debug_package %{nil} -%global __debug_package 1 -%global __debug_install_post \ - %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_find_debuginfo_opts} "%{_builddir}/gcc-%{version}"\ - %{_builddir}/gcc-%{version}/split-debuginfo.sh\ -%{nil} -%package debuginfo -Summary: Debug information for package %{name} -Group: Development/Debug -AutoReqProv: 0 -Requires: gcc-base-debuginfo = %{version}-%{release} -%description debuginfo -This package provides debug information for package %{name}. -Debug information is useful when developing applications that use this -package or when debugging this package. -%files debuginfo -f debugfiles.list -%defattr(-,root,root) -%package base-debuginfo -Summary: Debug information for libraries from package %{name} -Group: Development/Debug -AutoReqProv: 0 -%description base-debuginfo -This package provides debug information for libgcc_s, libgomp and -libstdc++ libraries from package %{name}. -Debug information is useful when developing applications that use this -package or when debugging this package. -%files base-debuginfo -f debugfiles-base.list -%defattr(-,root,root) -%endif %prep -%setup -q -n gcc-%{version} -a 1 -a 2 +%setup -q -n gcc-%{version} /bin/pwd - +%patch0 -p1 %patch1 -p1 %patch2 -p1 %patch3 -p1 @@ -495,258 +580,98 @@ package or when debugging this package. %patch6 -p1 %patch7 -p1 %patch8 -p1 +%patch9 -p1 %patch10 -p1 +%patch11 -p1 %patch12 -p1 +%patch13 -p1 %patch14 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch28 -p1 -%patch29 -p1 -%patch31 -p1 -%patch34 -p1 -%patch35 -p1 - -%if 0%{?_enable_debug_packages} -cat > split-debuginfo.sh <<\EOF -#!/bin/sh -BUILDDIR="%{_builddir}/gcc-%{version}" -if [ -f "${BUILDDIR}"/debugfiles.list \ - -a -f "${BUILDDIR}"/debuglinks.list ]; then - > "${BUILDDIR}"/debugsources-base.list - > "${BUILDDIR}"/debugfiles-base.list - cd "${RPM_BUILD_ROOT}" - for f in `find usr/lib/debug -name \*.debug \ - | egrep 'lib[0-9]*/lib(gcc|gomp|stdc|quadmath|itm)'`; do - echo "/$f" >> "${BUILDDIR}"/debugfiles-base.list - if [ -f "$f" -a ! -L "$f" ]; then - cp -a "$f" "${BUILDDIR}"/test.debug - /usr/lib/rpm/debugedit -b "${RPM_BUILD_DIR}" -d /usr/src/debug \ - -l "${BUILDDIR}"/debugsources-base.list \ - "${BUILDDIR}"/test.debug - rm -f "${BUILDDIR}"/test.debug - fi - done - for f in `find usr/lib/debug/.build-id -type l`; do - ls -l "$f" | egrep -q -- '->.*lib[0-9]*/lib(gcc|gomp|stdc|quadmath|itm)' \ - && echo "/$f" >> "${BUILDDIR}"/debugfiles-base.list - done - grep -v -f "${BUILDDIR}"/debugfiles-base.list \ - "${BUILDDIR}"/debugfiles.list > "${BUILDDIR}"/debugfiles.list.new - mv -f "${BUILDDIR}"/debugfiles.list.new "${BUILDDIR}"/debugfiles.list - for f in `LC_ALL=C sort -z -u "${BUILDDIR}"/debugsources-base.list \ - | grep -E -v -z '(|)$' \ - | xargs --no-run-if-empty -n 1 -0 echo \ - | sed 's,^,usr/src/debug/,'`; do - if [ -f "$f" ]; then - echo "/$f" >> "${BUILDDIR}"/debugfiles-base.list - echo "%%exclude /$f" >> "${BUILDDIR}"/debugfiles.list - fi - done - mv -f "${BUILDDIR}"/debugfiles-base.list{,.old} - echo "%%dir /usr/lib/debug" > "${BUILDDIR}"/debugfiles-base.list - awk 'BEGIN{FS="/"}(NF>4&&$NF){d="%%dir /"$2"/"$3"/"$4;for(i=5;i> "${BUILDDIR}"/debugfiles-base.list - cat "${BUILDDIR}"/debugfiles-base.list.old >> "${BUILDDIR}"/debugfiles-base.list - rm -f "${BUILDDIR}"/debugfiles-base.list.old -fi -EOF -chmod 755 split-debuginfo.sh -%endif - +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 %build -%ifarch aarch64_ilp32 -optflags=`echo ${optflags}|sed -e 's/-mabi=ilp32//g'` -optflags=`echo ${optflags}|sed -e 's/-Werror=format-security/ /g'` -CFLAGS='-O2 -g' -%endif -%ifarch x86_64 -%global optflags `echo %{optflags}|sed -e 's/-fcf-protection//g'` -%endif export CONFIG_SITE=NONE -%if %{build_java} -export GCJ_PROPERTIES=jdt.compiler.useSingleThread=true -# gjar isn't usable, so even when GCC source tree no longer includes -# fastjar, build it anyway. -mkdir fastjar-%{fastjar_ver}/obj-%{gcc_target_platform} -cd fastjar-%{fastjar_ver}/obj-%{gcc_target_platform} -../configure CFLAGS="%{optflags}" --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} -make -j100 -export PATH=`pwd`${PATH:+:$PATH} -cd ../../ -%endif - -rm -fr obj-%{gcc_target_platform} -mkdir obj-%{gcc_target_platform} -cd obj-%{gcc_target_platform} - -%if %{build_java} -%if !%{bootstrap_java} -# If we don't have gjavah in $PATH, try to build it with the old gij -mkdir java_hacks -cd java_hacks -cp -a ../../libjava/classpath/tools/external external -mkdir -p gnu/classpath/tools -cp -a ../../libjava/classpath/tools/gnu/classpath/tools/{common,javah,getopt} gnu/classpath/tools/ -cp -a ../../libjava/classpath/tools/resource/gnu/classpath/tools/common/messages.properties gnu/classpath/tools/common -cp -a ../../libjava/classpath/tools/resource/gnu/classpath/tools/getopt/messages.properties gnu/classpath/tools/getopt -cd external/asm; for i in `find . -name \*.java`; do gcj --encoding ISO-8859-1 -C $i -I.; done; cd ../.. -for i in `find gnu -name \*.java`; do gcj -C $i -I. -Iexternal/asm/; done -gcj -findirect-dispatch -O2 -fmain=gnu.classpath.tools.javah.Main -I. -Iexternal/asm/ `find . -name \*.class` -o gjavah.real -cat > gjavah < ecj1 <> ../../cloog-%{cloog_version}/source/isl/constraints.c << \EOF -#include -static void __attribute__((used)) *s1 = (void *) isl_union_map_compute_flow; -static void __attribute__((used)) *s2 = (void *) isl_map_dump; -EOF -cd ../../cloog-%{cloog_version} -./autogen.sh -cd - - -../../cloog-%{cloog_version}/configure --with-isl=system \ - --with-isl-prefix=`cd ../isl-install; pwd` \ - CC=/usr/bin/gcc CXX=/usr/bin/g++ \ - CFLAGS="${CFLAGS:-%optflags}" CXXFLAGS="${CXXFLAGS:-%optflags}" \ - --prefix=`cd ..; pwd`/cloog-install -sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool -sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool -make -j100 -make -j100 install -cd ../cloog-install/lib -ln -sf libcloog-isl.so.4 libcloog-isl.so -ln -sf libcloog-isl.so.4 libcloog.so -cd ../.. - -#test don't build -%if 1 CC=gcc +CXX=g++ OPT_FLAGS=`echo %{optflags}|sed -e 's/\(-Wp,\)\?-D_FORTIFY_SOURCE=[12]//g'` OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'` OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mfpmath=sse/-mfpmath=sse -msse2/g'` -OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-Werror=format-security/ /g'` OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/ -pipe / /g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-Werror=format-security/ /g'` +%ifarch x86_64 +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-fcf-protection/ /g'` +%endif %ifarch sparc OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mcpu=ultrasparc/-mtune=ultrasparc/g;s/-mcpu=v[78]//g'` %endif %ifarch %{ix86} OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-march=i.86//g'` %endif -%ifarch sparc64 -cat > gcc64 <<"EOF" -#!/bin/sh -exec /usr/bin/gcc -m64 "$@" -EOF -chmod +x gcc64 -CC=`pwd`/gcc64 -%endif -%ifarch ppc64 ppc64le ppc64p7 -if gcc -m64 -xc -S /dev/null -o - > /dev/null 2>&1; then - cat > gcc64 <<"EOF" -#!/bin/sh -exec /usr/bin/gcc -m64 "$@" -EOF - chmod +x gcc64 - CC=`pwd`/gcc64 -fi -%endif -%ifarch aarch64_ilp32 -OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mabi=ilp32//g'` -%endif OPT_FLAGS=`echo "$OPT_FLAGS" | sed -e 's/[[:blank:]]\+/ /g'` case "$OPT_FLAGS" in *-fasynchronous-unwind-tables*) - sed -i -e 's/-fno-exceptions /-fno-exceptions -fno-asynchronous-unwind-tables/' \ - ../gcc/Makefile.in + sed -i -e 's/-fno-exceptions /-fno-exceptions -fno-asynchronous-unwind-tables /' \ + gcc/Makefile.in ;; esac + +rm -rf obj-%{gcc_target_platform} +mkdir obj-%{gcc_target_platform} +cd obj-%{gcc_target_platform} + enablelgo= enablelada= +enablelobjc= +enableld= +%if %{build_objc} +enablelobjc=,objc,obj-c++ +%endif %if %{build_ada} enablelada=,ada %endif %if %{build_go} enablelgo=,go %endif +%if %{build_d} +enableld=,d +%endif OPT_FLAGS="$OPT_FLAGS -fPIE -Wl,-z,relro,-z,now" OPT_LDFLAGS="$OPT_LDFLAGS -Wl,-z,relro,-z,now" export extra_ldflags_libobjc="-Wl,-z,relro,-z,now" export FCFLAGS="$OPT_FLAGS" CC="$CC" CFLAGS="$OPT_FLAGS" \ - CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \ - | sed 's/ -Werror=format-security //'`" \ - LDFLAGS="$OPT_LDFLAGS" \ - CFLAGS_FOR_TARGET="$OPT_FLAGS" \ - CXXFLAGS_FOR_TARGET="$OPT_FLAGS" \ - XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" GCJFLAGS="$OPT_FLAGS" \ - ../configure --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \ - --enable-shared --enable-threads=posix --enable-checking=release \ - --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions \ - --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu \ - --enable-languages=c,c++,objc,obj-c++,fortran,lto --enable-plugin \ - --enable-initfini-array --disable-libgcj --without-isl --without-cloog \ - --enable-gnu-indirect-function --build=%{gcc_target_platform} \ - --with-stage1-ldflags="$OPT_LDFLAGS" \ - --with-boot-ldflags="$OPT_LDFLAGS" \ + CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \ + | sed 's/ -Werror=format-security //'`" \ + LDFLAGS="$OPT_LDFLAGS" \ + CFLAGS_FOR_TARGET="$OPT_FLAGS" \ + CXXFLAGS_FOR_TARGET="$OPT_FLAGS" \ + XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" GCJFLAGS="$OPT_FLAGS" \ + ../configure --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \ + --enable-shared --enable-threads=posix --enable-checking=release \ + --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions \ + --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu \ + --enable-languages=c,c++,objc,obj-c++,fortran,lto --enable-plugin \ + --enable-initfini-array --disable-libgcj --without-isl --without-cloog \ + --enable-gnu-indirect-function --build=%{gcc_target_platform} \ + --with-stage1-ldflags="$OPT_LDFLAGS" \ + --with-boot-ldflags="$OPT_LDFLAGS" \ %ifarch x86_64 - --with-tune=generic \ - --with-arch_32=x86-64 \ - --disable-multilib + --with-tune=generic \ + --with-arch_32=x86-64 \ + --disable-multilib %endif %ifarch aarch64 -%if %{build_libilp32} - --with-multilib-list=lp64,ilp32 -%else - --with-multilib-list=lp64 -%endif + --with-multilib-list=lp64 %endif -%ifarch %{arm} sparc sparcv9 sparc64 -GCJFLAGS="$OPT_FLAGS" make -j BOOT_CFLAGS="$OPT_FLAGS" bootstrap +%ifarch sparc sparcv9 sparc64 +make -j %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" bootstrap %else -#GCJFLAGS="$OPT_FLAGS" make -j BOOT_CFLAGS="$OPT_FLAGS" profiledbootstrap -GCJFLAGS="$OPT_FLAGS" make -j BOOT_CFLAGS="$OPT_FLAGS" BOOT_LDFLAGS="-pie -Wl,-z,relro,-z,now" -%endif -#test don't build -%endif -%if %{build_cloog} -cp -a cloog-install/lib/libcloog-isl.so.4 gcc/ +make -j %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" BOOT_LDFLAGS="-pie -Wl,-z,relro,-z,now" %endif # Make generated man pages even if Pod::Man is not new enough @@ -754,28 +679,24 @@ perl -pi -e 's/head3/head2/' ../contrib/texi2pod.pl for i in ../gcc/doc/*.texi; do cp -a $i $i.orig; sed 's/ftable/table/' $i.orig > $i done -make -j100 -C gcc generated-manpages +make -j -C gcc generated-manpages for i in ../gcc/doc/*.texi; do mv -f $i.orig $i; done # Make generated doxygen pages. %if %{build_libstdcxx_docs} cd %{gcc_target_platform}/libstdc++-v3 -make doc-html-doxygen -make doc-man-doxygen +make -j doc-html-doxygen +make -j doc-man-doxygen cd ../.. %endif # Copy various doc files here and there cd .. -mkdir -p rpm.doc/gfortran -mkdir -p rpm.doc/objc -mkdir -p rpm.doc/boehm-gc rpm.doc/fastjar rpm.doc/libffi rpm.doc/libjava +mkdir -p rpm.doc/gfortran rpm.doc/objc rpm.doc/gdc rpm.doc/libphobos mkdir -p rpm.doc/go rpm.doc/libgo rpm.doc/libquadmath rpm.doc/libitm -#mkdir -p rpm.doc/changelogs/{gcc/cp,gcc/java,gcc/ada,libstdc++-v3,libobjc,libmudflap,libgomp,libatomic,libsanitizer} -mkdir -p rpm.doc/changelogs/{gcc/cp,gcc/java,gcc/ada,libstdc++-v3,libobjc,libgomp,libatomic,libsanitizer} -%if 0 -#for i in {gcc,gcc/cp,gcc/java,gcc/ada,libstdc++-v3,libobjc,libmudflap,libgomp,libatomic,libsanitizer}/ChangeLog*; do -for i in {gcc,gcc/cp,gcc/java,gcc/ada,libstdc++-v3,libobjc,libgomp,libatomic,libsanitizer}/ChangeLog*; do +mkdir -p rpm.doc/changelogs/{gcc/cp,gcc/ada,libstdc++-v3,libobjc,libgomp,libcc1,libatomic,libsanitizer} + +for i in {gcc,gcc/cp,gcc/ada,libstdc++-v3,libobjc,libgomp,libcc1,libatomic,libsanitizer}/ChangeLog*; do cp -p $i rpm.doc/changelogs/$i done @@ -785,23 +706,20 @@ done) (cd libgfortran; for i in ChangeLog*; do cp -p $i ../rpm.doc/gfortran/$i.libgfortran done) +%if %{build_objc} (cd libobjc; for i in README*; do cp -p $i ../rpm.doc/objc/$i.libobjc done) -(cd boehm-gc; for i in ChangeLog*; do - cp -p $i ../rpm.doc/boehm-gc/$i.gc -done) - -(cd fastjar-%{fastjar_ver}; for i in ChangeLog* README*; do - cp -p $i ../rpm.doc/fastjar/$i.fastjar -done) -(cd libffi; for i in ChangeLog* README* LICENSE; do - cp -p $i ../rpm.doc/libffi/$i.libffi -done) -(cd libjava; for i in ChangeLog* README*; do - cp -p $i ../rpm.doc/libjava/$i.libjava +%endif +%if %{build_d} +(cd gcc/d; for i in ChangeLog*; do + cp -p $i ../../rpm.doc/gdc/$i.gdc done) -cp -p libjava/LIBGCJ_LICENSE rpm.doc/libjava/ +(cd libphobos; for i in ChangeLog*; do + cp -p $i ../rpm.doc/libphobos/$i.libphobos +done +cp -a src/LICENSE*.txt libdruntime/LICENSE ../rpm.doc/libphobos/) +%endif %if %{build_libquadmath} (cd libquadmath; for i in ChangeLog* COPYING.LIB; do cp -p $i ../rpm.doc/libquadmath/$i.libquadmath @@ -823,54 +741,25 @@ done) rm -f rpm.doc/changelogs/gcc/ChangeLog.[1-9] find rpm.doc -name \*ChangeLog\* | xargs bzip2 -9 -%endif - -%if %{build_java_tar} -find libjava -name \*.h -type f | xargs grep -l '// DO NOT EDIT THIS FILE - it is machine generated' > libjava-classes.list -find libjava -name \*.class -type f >> libjava-classes.list -find libjava/testsuite -name \*.jar -type f >> libjava-classes.list -tar cf - -T libjava-classes.list | bzip2 -9 > $RPM_SOURCE_DIR/libjava-classes-%{version}-%{release}.tar.bz2 -%endif %install -rm -fr %{buildroot} +rm -rf %{buildroot} cd obj-%{gcc_target_platform} -%if %{build_java} -export GCJ_PROPERTIES=jdt.compiler.useSingleThread=true -export PATH=`pwd`/../fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}${PATH:+:$PATH} -%if !%{bootstrap_java} -export PATH=`pwd`/java_hacks${PATH:+:$PATH} -%endif -%endif - TARGET_PLATFORM=%{gcc_target_platform} # There are some MP bugs in libstdc++ Makefiles -make -j100 -C %{gcc_target_platform}/libstdc++-v3 +make -j -C %{gcc_target_platform}/libstdc++-v3 -make -j100 prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \ +make prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \ infodir=%{buildroot}%{_infodir} install -%if %{build_java} -make -j100 DESTDIR=%{buildroot} -C %{gcc_target_platform}/libjava install-src.zip -%endif %if %{build_ada} chmod 644 %{buildroot}%{_infodir}/gnat* %endif -%ifarch aarch64_ilp32 -FULLPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version}/ilp32 -FULLEPATH=%{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version}/ilp32 -%else -FULLPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -FULLEPATH=%{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -FULLHPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} - -%if %{build_cloog} -cp -a cloog-install/lib/libcloog-isl.so.4 $FULLPATH/ -%endif +FULLPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +FULLEPATH=%{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} # fix some things ln -sf gcc %{buildroot}%{_prefix}/bin/cc @@ -880,11 +769,19 @@ ln -sf gfortran %{buildroot}%{_prefix}/bin/f95 rm -f %{buildroot}%{_infodir}/dir gzip -9 %{buildroot}%{_infodir}/*.info* ln -sf gcc %{buildroot}%{_prefix}/bin/gnatgcc +mkdir -p %{buildroot}%{_fmoddir} + +%if %{build_go} +mv %{buildroot}%{_prefix}/bin/go{,.gcc} +mv %{buildroot}%{_prefix}/bin/gofmt{,.gcc} +ln -sf /etc/alternatives/go %{buildroot}%{_prefix}/bin/go +ln -sf /etc/alternatives/gofmt %{buildroot}%{_prefix}/bin/gofmt +%endif cxxconfig="`find %{gcc_target_platform}/libstdc++-v3/include -name c++config.h`" for i in `find %{gcc_target_platform}/[36]*/libstdc++-v3/include -name c++config.h 2>/dev/null`; do if ! diff -up $cxxconfig $i; then - cat > %{buildroot}%{_prefix}/include/c++/%{version}/%{gcc_target_platform}/bits/c++config.h < %{buildroot}%{_prefix}/include/c++/%{gcc_major}/%{gcc_target_platform}/bits/c++config.h < @@ -907,7 +804,7 @@ EOF fi done -for f in `find %{buildroot}%{_prefix}/include/c++/%{version}/%{gcc_target_platform}/ -name c++config.h`; do +for f in `find %{buildroot}%{_prefix}/include/c++/%{gcc_major}/%{gcc_target_platform}/ -name c++config.h`; do for i in 1 2 4 8; do sed -i -e 's/#define _GLIBCXX_ATOMIC_BUILTINS_'$i' 1/#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_'$i'\ &\ @@ -924,7 +821,7 @@ done # 4) it is huge # People can always precompile on their own whatever they want, but # shipping this for everybody is unnecessary. -rm -rf %{buildroot}%{_prefix}/include/c++/%{version}/%{gcc_target_platform}/bits/*.h.gch +rm -rf %{buildroot}%{_prefix}/include/c++/%{gcc_major}/%{gcc_target_platform}/bits/*.h.gch %if %{build_libstdcxx_docs} libstdcxx_doc_builddir=%{gcc_target_platform}/libstdc++-v3/doc/doxygen @@ -945,86 +842,70 @@ ln -f %{buildroot}%{_prefix}/bin/%{gcc_target_platform}-gcc \ %{buildroot}%{_prefix}/bin/ppc-%{_vendor}-%{_target_os}-gcc %endif +FULLLSUBDIR= %ifarch sparcv9 ppc -FULLLPATH=$FULLPATH/lib32 +FULLLSUBDIR=lib32 %endif %ifarch sparc64 ppc64 ppc64p7 -FULLLPATH=$FULLPATH/lib64 +FULLLSUBDIR=lib64 %endif -if [ -n "$FULLLPATH" ]; then +if [ -n "$FULLLSUBDIR" ]; then + FULLLPATH=$FULLPATH/$FULLLSUBDIR mkdir -p $FULLLPATH else FULLLPATH=$FULLPATH fi find %{buildroot} -name \*.la | xargs rm -f -%if %{build_java} -# gcj -static doesn't work properly anyway, unless using --whole-archive -# and saving 35MB is not bad. -find %{buildroot} -name libgcj.a -o -name libgtkpeer.a \ - -o -name libgjsmalsa.a -o -name libgcj-tools.a -o -name libjvm.a \ - -o -name libgij.a -o -name libgcj_bc.a -o -name libjavamath.a \ - | xargs rm -f - -mv %{buildroot}%{_prefix}/lib/libgcj.spec $FULLPATH/ -sed -i -e 's/lib: /&%%{static:%%eJava programs cannot be linked statically}/' \ - $FULLPATH/libgcj.spec -%endif mv %{buildroot}%{_prefix}/%{_lib}/libgfortran.spec $FULLPATH/ +%if %{build_d} +mv %{buildroot}%{_prefix}/%{_lib}/libgphobos.spec $FULLPATH/ +%endif %if %{build_libitm} mv %{buildroot}%{_prefix}/%{_lib}/libitm.spec $FULLPATH/ %endif - %if %{build_libasan} mv %{buildroot}%{_prefix}/%{_lib}/libsanitizer.spec $FULLPATH/ %endif mkdir -p %{buildroot}/%{_lib} -mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{version}-%{DATE}.so.1 -chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{version}-%{DATE}.so.1 -ln -sf libgcc_s-%{version}-%{DATE}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1 +mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1 +chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1 +ln -sf libgcc_s-%{gcc_major}-%{DATE}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1 +%ifarch %{ix86} x86_64 ppc ppc64 ppc64p7 ppc64le %{arm} +rm -f $FULLPATH/libgcc_s.so +echo '/* GNU ld script + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ +OUTPUT_FORMAT('`gcc -Wl,--print-output-format -nostdlib -r -o /dev/null`') +GROUP ( /%{_lib}/libgcc_s.so.1 libgcc.a )' > $FULLPATH/libgcc_s.so +%else ln -sf /%{_lib}/libgcc_s.so.1 $FULLPATH/libgcc_s.so - -%ifarch aarch64 -%if %{build_libilp32} -mkdir -p %{buildroot}/libilp32 -mv -f %{buildroot}%{_prefix}/libilp32/libgcc_s.so.1 %{buildroot}/libilp32/libgcc_s-%{version}-%{DATE}.so.1 -chmod 755 %{buildroot}/libilp32/libgcc_s-%{version}-%{DATE}.so.1 -ln -sf libgcc_s-%{version}-%{DATE}.so.1 %{buildroot}/libilp32/libgcc_s.so.1 -ln -sf /libilp32/libgcc_s.so.1 $FULLPATH/ilp32/libgcc_s.so %endif -%endif - %ifarch sparcv9 ppc -ln -sf /lib64/libgcc_s.so.1 $FULLPATH/64/libgcc_s.so -%endif -%ifarch %{multilib_64_archs} -ln -sf /lib/libgcc_s.so.1 $FULLPATH/32/libgcc_s.so -%endif %ifarch ppc -rm -f $FULLPATH/libgcc_s.so +rm -f $FULLPATH/64/libgcc_s.so echo '/* GNU ld script Use the shared library, but some functions are only in the static library, so try that secondarily. */ -OUTPUT_FORMAT(elf32-powerpc) -GROUP ( /lib/libgcc_s.so.1 libgcc.a )' > $FULLPATH/libgcc_s.so +OUTPUT_FORMAT('`gcc -m64 -Wl,--print-output-format -nostdlib -r -o /dev/null`') +GROUP ( /lib64/libgcc_s.so.1 libgcc.a )' > $FULLPATH/64/libgcc_s.so +%else +ln -sf /lib64/libgcc_s.so.1 $FULLPATH/64/libgcc_s.so %endif -%ifarch ppc64 ppc64p7 -rm -f $FULLPATH/32/libgcc_s.so +%endif +%ifarch %{multilib_64_archs} +%ifarch x86_64 ppc64 ppc64p7 +rm -f $FULLPATH/64/libgcc_s.so echo '/* GNU ld script Use the shared library, but some functions are only in the static library, so try that secondarily. */ -OUTPUT_FORMAT(elf32-powerpc) +OUTPUT_FORMAT('`gcc -m32 -Wl,--print-output-format -nostdlib -r -o /dev/null`') GROUP ( /lib/libgcc_s.so.1 libgcc.a )' > $FULLPATH/32/libgcc_s.so +%else +ln -sf /lib/libgcc_s.so.1 $FULLPATH/32/libgcc_s.so %endif -%ifarch %{arm} -rm -f $FULLPATH/libgcc_s.so -echo '/* GNU ld script - Use the shared library, but some functions are only in - the static library, so try that secondarily. */ -OUTPUT_FORMAT(elf32-littlearm) -GROUP ( /lib/libgcc_s.so.1 libgcc.a )' > $FULLPATH/libgcc_s.so %endif mv -f %{buildroot}%{_prefix}/%{_lib}/libgomp.spec $FULLPATH/ @@ -1036,63 +917,40 @@ rm -f $FULLPATH/adalib/libgnarl.so* $FULLPATH/adalib/libgnat.so* %endif mkdir -p %{buildroot}%{_prefix}/libexec/getconf -if gcc/xgcc -B gcc/ -E -dD -xc /dev/null | grep __LONG_MAX__.*2147483647; then +if gcc/xgcc -B gcc/ -E -P -dD -xc /dev/null | grep '__LONG_MAX__.*\(2147483647\|0x7fffffff\($\|[LU]\)\)'; then ln -sf POSIX_V6_ILP32_OFF32 %{buildroot}%{_prefix}/libexec/getconf/default else ln -sf POSIX_V6_LP64_OFF64 %{buildroot}%{_prefix}/libexec/getconf/default fi -%if %{build_java} -pushd ../fastjar-%{fastjar_ver}/obj-%{gcc_target_platform} -make -j100 install DESTDIR=%{buildroot} -popd - -if [ "%{_lib}" != "lib" ]; then - mkdir -p %{buildroot}%{_prefix}/%{_lib}/pkgconfig - sed '/^libdir/s/lib$/%{_lib}/' %{buildroot}%{_prefix}/lib/pkgconfig/libgcj-*.pc \ - > %{buildroot}%{_prefix}/%{_lib}/pkgconfig/`basename %{buildroot}%{_prefix}/lib/pkgconfig/libgcj-*.pc` -fi - -%endif - mkdir -p %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib} mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++*gdb.py* \ %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/ - -%ifarch aarch64 -%if %{build_libilp32} -mkdir -p %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/libilp32 -mv -f %{buildroot}%{_prefix}/libilp32/libstdc++*gdb.py* \ - %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/libilp32 -%endif -%endif - pushd ../libstdc++-v3/python for i in `find . -name \*.py`; do - touch -r $i %{buildroot}%{_prefix}/share/gcc-%{version}/python/$i + touch -r $i %{buildroot}%{_prefix}/share/gcc-%{gcc_major}/python/$i done touch -r hook.in %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc++*gdb.py -%ifarch aarch64 -%if %{build_libilp32} -touch -r hook.in %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/libilp32/libstdc++*gdb.py -%endif -%endif popd pushd $FULLPATH if [ "%{_lib}" = "lib" ]; then +%if %{build_objc} ln -sf ../../../libobjc.so.4 libobjc.so +%endif ln -sf ../../../libstdc++.so.6.*[0-9] libstdc++.so -ln -sf ../../../libgfortran.so.4.* libgfortran.so +ln -sf ../../../libgfortran.so.5.* libgfortran.so ln -sf ../../../libgomp.so.1.* libgomp.so -#ln -sf ../../../libmudflap.so.0.* libmudflap.so -#ln -sf ../../../libmudflapth.so.0.* libmudflapth.so %if %{build_go} -ln -sf ../../../libgo.so.4.* libgo.so +ln -sf ../../../libgo.so.14.* libgo.so %endif %if %{build_libquadmath} ln -sf ../../../libquadmath.so.0.* libquadmath.so %endif +%if %{build_d} +ln -sf ../../../libgdruntime.so.76.* libgdruntime.so +ln -sf ../../../libgphobos.so.76.* libgphobos.so +%endif %if %{build_libitm} ln -sf ../../../libitm.so.1.* libitm.so %endif @@ -1100,161 +958,90 @@ ln -sf ../../../libitm.so.1.* libitm.so ln -sf ../../../libatomic.so.1.* libatomic.so %endif %if %{build_libasan} -ln -sf ../../../libasan.so.4.* libasan.so +ln -sf ../../../libasan.so.5.* libasan.so mv ../../../libasan_preinit.o libasan_preinit.o %endif -%if %{build_java} -ln -sf ../../../libgcj.so.14.* libgcj.so -ln -sf ../../../libgcj-tools.so.14.* libgcj-tools.so -ln -sf ../../../libgij.so.14.* libgij.so +%if %{build_libubsan} +ln -sf ../../../libubsan.so.1.* libubsan.so %endif else +%if %{build_objc} ln -sf ../../../../%{_lib}/libobjc.so.4 libobjc.so +%endif ln -sf ../../../../%{_lib}/libstdc++.so.6.*[0-9] libstdc++.so -ln -sf ../../../../%{_lib}/libgfortran.so.4.* libgfortran.so +ln -sf ../../../../%{_lib}/libgfortran.so.5.* libgfortran.so ln -sf ../../../../%{_lib}/libgomp.so.1.* libgomp.so -%ifarch aarch64 -%if %{build_libilp32} -ln -sf ../../../../libilp32/libobjc.so.4 ilp32/libobjc.so -ln -sf ../../../../libilp32/libstdc++.so.6.*[0-9] ilp32/libstdc++.so -ln -sf ../../../../libilp32/libgfortran.so.4.* ilp32/libgfortran.so -ln -sf ../../../../libilp32/libgomp.so.1.* ilp32/libgomp.so -%endif -%endif -#ln -sf ../../../../%{_lib}/libmudflap.so.0.* libmudflap.so -#ln -sf ../../../../%{_lib}/libmudflapth.so.0.* libmudflapth.so %if %{build_go} -ln -sf ../../../../%{_lib}/libgo.so.4.* libgo.so -%ifarch aarch64 -%if %{build_libilp32} -ln -sf ../../../../libilp32/libgo.so.4.* ilp32/libgo.so -%endif -%endif +ln -sf ../../../../%{_lib}/libgo.so.14.* libgo.so %endif %if %{build_libquadmath} ln -sf ../../../../%{_lib}/libquadmath.so.0.* libquadmath.so -%ifarch aarch64 -%if %{build_libilp32} -ln -sf ../../../../libilp32/libquadmath.so.0.* ilp32/libquadmath.so -%endif %endif +%if %{build_d} +ln -sf ../../../../%{_lib}/libgdruntime.so.76.* libgdruntime.so +ln -sf ../../../../%{_lib}/libgphobos.so.76.* libgphobos.so %endif %if %{build_libitm} ln -sf ../../../../%{_lib}/libitm.so.1.* libitm.so -%ifarch aarch64 -%if %{build_libilp32} -ln -sf ../../../../libilp32/libitm.so.1.* ilp32/libitm.so -%endif -%endif %endif %if %{build_libatomic} ln -sf ../../../../%{_lib}/libatomic.so.1.* libatomic.so -%ifarch aarch64 -%if %{build_libilp32} -ln -sf ../../../../libilp32/libatomic.so.1.* ilp32/libatomic.so -%endif -%endif %endif %if %{build_libasan} -ln -sf ../../../../%{_lib}/libasan.so.4.* libasan.so +ln -sf ../../../../%{_lib}/libasan.so.5.* libasan.so mv ../../../../%{_lib}/libasan_preinit.o libasan_preinit.o -%ifarch aarch64 -%if %{build_libilp32} -ln -sf ../../../../libilp32/libasan.so.4.* ilp32/libasan.so -mv ../../../../libilp32/libasan_preinit.o ilp32/libasan_preinit.o -%endif %endif +%if %{build_libubsan} +ln -sf ../../../../%{_lib}/libubsan.so.1.* libubsan.so %endif %if %{build_libtsan} rm -f libtsan.so echo 'INPUT ( %{_prefix}/%{_lib}/'`echo ../../../../%{_lib}/libtsan.so.0.* | sed 's,^.*libt,libt,'`' )' > libtsan.so -%ifarch aarch64 -%if %{build_libilp32} -echo 'INPUT ( %{_prefix}/libilp32/'`echo ../../../../libilp32/libtsan.so.0.* | sed 's,^.*libt,libt,'`' )' > ilp32/libtsan.so -%endif -%endif -%endif -%if %{build_java} -ln -sf ../../../../%{_lib}/libgcj.so.14.* libgcj.so -ln -sf ../../../../%{_lib}/libgcj-tools.so.14.* libgcj-tools.so -ln -sf ../../../../%{_lib}/libgij.so.14.* libgij.so -%ifarch aarch64 -%if %{build_libilp32} -ln -sf ../../../../libilp32/libgcj.so.14.* ilp32/libgcj.so -ln -sf ../../../../libilp32/libgcj-tools.so.14.* ilp32/libgcj-tools.so -ln -sf ../../../../libilp32/libgij.so.14.* ilp32/libgij.so -%endif +mv ../../../../%{_lib}/libtsan_preinit.o libtsan_preinit.o %endif +%if %{build_liblsan} +rm -f liblsan.so +echo 'INPUT ( %{_prefix}/%{_lib}/'`echo ../../../../%{_lib}/liblsan.so.0.* | sed 's,^.*libl,libl,'`' )' > liblsan.so +mv ../../../../%{_lib}/liblsan_preinit.o liblsan_preinit.o %endif fi -%if %{build_java} -mv -f %{buildroot}%{_prefix}/%{_lib}/libgcj_bc.so $FULLLPATH/ -%endif mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++.*a $FULLLPATH/ +mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++fs.*a $FULLLPATH/ mv -f %{buildroot}%{_prefix}/%{_lib}/libsupc++.*a $FULLLPATH/ mv -f %{buildroot}%{_prefix}/%{_lib}/libgfortran.*a $FULLLPATH/ +%if %{build_objc} mv -f %{buildroot}%{_prefix}/%{_lib}/libobjc.*a . -mv -f %{buildroot}%{_prefix}/%{_lib}/libgomp.*a . -%ifarch aarch64 -%if %{build_libilp32} -mv -f %{buildroot}%{_prefix}/libilp32/libstdc++.*a $FULLLPATH/ilp32/ -mv -f %{buildroot}%{_prefix}/libilp32/libsupc++.*a $FULLLPATH/ilp32/ -mv -f %{buildroot}%{_prefix}/libilp32/libgfortran.*a $FULLLPATH/ilp32/ -mv -f %{buildroot}%{_prefix}/libilp32/libobjc.*a ./ilp32/ -mv -f %{buildroot}%{_prefix}/libilp32/libgomp.*a ./ilp32/ %endif -%endif - -#mv -f %{buildroot}%{_prefix}/%{_lib}/libmudflap{,th}.*a $FULLLPATH/ +mv -f %{buildroot}%{_prefix}/%{_lib}/libgomp.*a . %if %{build_libquadmath} mv -f %{buildroot}%{_prefix}/%{_lib}/libquadmath.*a $FULLLPATH/ -%ifarch aarch64 -%if %{build_libilp32} -mv -f %{buildroot}%{_prefix}/libilp32/libquadmath.*a $FULLLPATH/ilp32/ -%endif %endif +%if %{build_d} +mv -f %{buildroot}%{_prefix}/%{_lib}/libgdruntime.*a $FULLLPATH/ +mv -f %{buildroot}%{_prefix}/%{_lib}/libgphobos.*a $FULLLPATH/ %endif %if %{build_libitm} mv -f %{buildroot}%{_prefix}/%{_lib}/libitm.*a $FULLLPATH/ -%ifarch aarch64 -%if %{build_libilp32} -mv -f %{buildroot}%{_prefix}/libilp32/libitm.*a $FULLLPATH/ilp32/ -%endif -%endif %endif %if %{build_libatomic} mv -f %{buildroot}%{_prefix}/%{_lib}/libatomic.*a $FULLLPATH/ -%ifarch aarch64 -%if %{build_libilp32} -mv -f %{buildroot}%{_prefix}/libilp32/libatomic.*a $FULLLPATH/ilp32/ -%endif -%endif %endif %if %{build_libasan} mv -f %{buildroot}%{_prefix}/%{_lib}/libasan.*a $FULLLPATH/ -%ifarch aarch64 -%if %{build_libilp32} -mv -f %{buildroot}%{_prefix}/libilp32/libasan.*a $FULLLPATH/ilp32/ -%endif %endif +%if %{build_libubsan} +mv -f %{buildroot}%{_prefix}/%{_lib}/libubsan.*a $FULLLPATH/ %endif %if %{build_libtsan} -mv -f %{buildroot}%{_prefix}/%{_lib}/libtsan.*a $FULLLPATH/ -%ifarch aarch64 -%if %{build_libilp32} -mv -f %{buildroot}%{_prefix}/libilp32/libtsan.*a $FULLLPATH/ilp32/ -%endif +mv -f %{buildroot}%{_prefix}/%{_lib}/libtsan.*a $FULLPATH/ %endif +%if %{build_liblsan} +mv -f %{buildroot}%{_prefix}/%{_lib}/liblsan.*a $FULLPATH/ %endif %if %{build_go} mv -f %{buildroot}%{_prefix}/%{_lib}/libgo.*a $FULLLPATH/ mv -f %{buildroot}%{_prefix}/%{_lib}/libgobegin.*a $FULLLPATH/ -%ifarch aarch64 -%if %{build_libilp32} -mv -f %{buildroot}%{_prefix}/libilp32/libgo.*a $FULLLPATH/ilp32/ -mv -f %{buildroot}%{_prefix}/libilp32/libgobegin.*a $FULLLPATH/ilp32/ -%endif -%endif +mv -f %{buildroot}%{_prefix}/%{_lib}/libgolibbegin.*a $FULLLPATH/ %endif %if %{build_ada} @@ -1269,53 +1056,57 @@ mv -f $FULLPATH/ada{include,lib} $FULLLPATH/ pushd $FULLLPATH/adalib if [ "%{_lib}" = "lib" ]; then ln -sf ../../../../../libgnarl-*.so libgnarl.so -ln -sf ../../../../../libgnarl-*.so libgnarl-4.8.so +ln -sf ../../../../../libgnarl-*.so libgnarl-9.so ln -sf ../../../../../libgnat-*.so libgnat.so -ln -sf ../../../../../libgnat-*.so libgnat-4.8.so +ln -sf ../../../../../libgnat-*.so libgnat-9.so else ln -sf ../../../../../../%{_lib}/libgnarl-*.so libgnarl.so -ln -sf ../../../../../../%{_lib}/libgnarl-*.so libgnarl-4.8.so +ln -sf ../../../../../../%{_lib}/libgnarl-*.so libgnarl-9.so ln -sf ../../../../../../%{_lib}/libgnat-*.so libgnat.so -ln -sf ../../../../../../%{_lib}/libgnat-*.so libgnat-4.8.so +ln -sf ../../../../../../%{_lib}/libgnat-*.so libgnat-9.so fi popd else pushd $FULLPATH/adalib if [ "%{_lib}" = "lib" ]; then ln -sf ../../../../libgnarl-*.so libgnarl.so -ln -sf ../../../../libgnarl-*.so libgnarl-4.8.so +ln -sf ../../../../libgnarl-*.so libgnarl-9.so ln -sf ../../../../libgnat-*.so libgnat.so -ln -sf ../../../../libgnat-*.so libgnat-4.8.so +ln -sf ../../../../libgnat-*.so libgnat-9.so else ln -sf ../../../../../%{_lib}/libgnarl-*.so libgnarl.so -ln -sf ../../../../../%{_lib}/libgnarl-*.so libgnarl-4.8.so +ln -sf ../../../../../%{_lib}/libgnarl-*.so libgnarl-9.so ln -sf ../../../../../%{_lib}/libgnat-*.so libgnat.so -ln -sf ../../../../../%{_lib}/libgnat-*.so libgnat-4.8.so +ln -sf ../../../../../%{_lib}/libgnat-*.so libgnat-9.so fi popd fi %endif %ifarch sparcv9 ppc +%if %{build_objc} ln -sf ../../../../../lib64/libobjc.so.4 64/libobjc.so +%endif ln -sf ../`echo ../../../../lib/libstdc++.so.6.*[0-9] | sed s~/lib/~/lib64/~` 64/libstdc++.so -ln -sf ../`echo ../../../../lib/libgfortran.so.4.* | sed s~/lib/~/lib64/~` 64/libgfortran.so +ln -sf ../`echo ../../../../lib/libgfortran.so.5.* | sed s~/lib/~/lib64/~` 64/libgfortran.so ln -sf ../`echo ../../../../lib/libgomp.so.1.* | sed s~/lib/~/lib64/~` 64/libgomp.so -#rm -f libmudflap.so libmudflapth.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libmudflap.so.0.* | sed 's,^.*libm,libm,'`' )' > libmudflap.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libmudflapth.so.0.* | sed 's,^.*libm,libm,'`' )' > libmudflapth.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libmudflap.so.0.* | sed 's,^.*libm,libm,'`' )' > 64/libmudflap.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libmudflapth.so.0.* | sed 's,^.*libm,libm,'`' )' > 64/libmudflapth.so %if %{build_go} rm -f libgo.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgo.so.4.* | sed 's,^.*libg,libg,'`' )' > libgo.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgo.so.4.* | sed 's,^.*libg,libg,'`' )' > 64/libgo.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > libgo.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > 64/libgo.so %endif %if %{build_libquadmath} rm -f libquadmath.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libquadmath.so.0.* | sed 's,^.*libq,libq,'`' )' > libquadmath.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libquadmath.so.0.* | sed 's,^.*libq,libq,'`' )' > 64/libquadmath.so %endif +%if %{build_d} +rm -f libgdruntime.so libgphobos.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > libgdruntime.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > 64/libgdruntime.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > libgphobos.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > 64/libgphobos.so +%endif %if %{build_libitm} rm -f libitm.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libitm.so.1.* | sed 's,^.*libi,libi,'`' )' > libitm.so @@ -1328,33 +1119,37 @@ echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libatomic.so.1.* | sed 's, %endif %if %{build_libasan} rm -f libasan.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libasan.so.4.* | sed 's,^.*liba,liba,'`' )' > libasan.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libasan.so.4.* | sed 's,^.*liba,liba,'`' )' > 64/libasan.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > libasan.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > 64/libasan.so mv ../../../../lib64/libasan_preinit.o 64/libasan_preinit.o %endif -%if %{build_java} -ln -sf ../`echo ../../../../lib/libgcj.so.14.* | sed s~/lib/~/lib64/~` 64/libgcj.so -ln -sf ../`echo ../../../../lib/libgcj-tools.so.14.* | sed s~/lib/~/lib64/~` 64/libgcj-tools.so -ln -sf ../`echo ../../../../lib/libgij.so.14.* | sed s~/lib/~/lib64/~` 64/libgij.so -ln -sf lib32/libgcj_bc.so libgcj_bc.so -ln -sf ../lib64/libgcj_bc.so 64/libgcj_bc.so +%if %{build_libubsan} +rm -f libubsan.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib/libubsan.so.1.* | sed 's,^.*libu,libu,'`' )' > libubsan.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib/libubsan.so.1.* | sed 's,^.*libu,libu,'`' )' > 64/libubsan.so %endif ln -sf lib32/libgfortran.a libgfortran.a ln -sf ../lib64/libgfortran.a 64/libgfortran.a +%if %{build_objc} mv -f %{buildroot}%{_prefix}/lib64/libobjc.*a 64/ +%endif mv -f %{buildroot}%{_prefix}/lib64/libgomp.*a 64/ ln -sf lib32/libstdc++.a libstdc++.a ln -sf ../lib64/libstdc++.a 64/libstdc++.a +ln -sf lib32/libstdc++fs.a libstdc++fs.a +ln -sf ../lib64/libstdc++fs.a 64/libstdc++fs.a ln -sf lib32/libsupc++.a libsupc++.a ln -sf ../lib64/libsupc++.a 64/libsupc++.a -#ln -sf lib32/libmudflap.a libmudflap.a -#ln -sf ../lib64/libmudflap.a 64/libmudflap.a -#ln -sf lib32/libmudflapth.a libmudflapth.a -#ln -sf ../lib64/libmudflapth.a 64/libmudflapth.a %if %{build_libquadmath} ln -sf lib32/libquadmath.a libquadmath.a ln -sf ../lib64/libquadmath.a 64/libquadmath.a %endif +%if %{build_d} +ln -sf lib32/libgdruntime.a libgdruntime.a +ln -sf ../lib64/libgdruntime.a 64/libgdruntime.a +ln -sf lib32/libgphobos.a libgphobos.a +ln -sf ../lib64/libgphobos.a 64/libgphobos.a +%endif %if %{build_libitm} ln -sf lib32/libitm.a libitm.a ln -sf ../lib64/libitm.a 64/libitm.a @@ -1367,11 +1162,17 @@ ln -sf ../lib64/libatomic.a 64/libatomic.a ln -sf lib32/libasan.a libasan.a ln -sf ../lib64/libasan.a 64/libasan.a %endif +%if %{build_libubsan} +ln -sf lib32/libubsan.a libubsan.a +ln -sf ../lib64/libubsan.a 64/libubsan.a +%endif %if %{build_go} ln -sf lib32/libgo.a libgo.a ln -sf ../lib64/libgo.a 64/libgo.a ln -sf lib32/libgobegin.a libgobegin.a ln -sf ../lib64/libgobegin.a 64/libgobegin.a +ln -sf lib32/libgolibbegin.a libgolibbegin.a +ln -sf ../lib64/libgolibbegin.a 64/libgolibbegin.a %endif %if %{build_ada} ln -sf lib32/adainclude adainclude @@ -1382,27 +1183,29 @@ ln -sf ../lib64/adalib 64/adalib %endif %ifarch %{multilib_64_archs} mkdir -p 32 +%if %{build_objc} ln -sf ../../../../libobjc.so.4 32/libobjc.so +%endif ln -sf ../`echo ../../../../lib64/libstdc++.so.6.*[0-9] | sed s~/../lib64/~/~` 32/libstdc++.so -ln -sf ../`echo ../../../../lib64/libgfortran.so.4.* | sed s~/../lib64/~/~` 32/libgfortran.so +ln -sf ../`echo ../../../../lib64/libgfortran.so.5.* | sed s~/../lib64/~/~` 32/libgfortran.so ln -sf ../`echo ../../../../lib64/libgomp.so.1.* | sed s~/../lib64/~/~` 32/libgomp.so -%if 0 -rm -f libmudflap.so libmudflapth.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libmudflap.so.0.* | sed 's,^.*libm,libm,'`' )' > libmudflap.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libmudflapth.so.0.* | sed 's,^.*libm,libm,'`' )' > libmudflapth.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libmudflap.so.0.* | sed 's,^.*libm,libm,'`' )' > 32/libmudflap.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libmudflapth.so.0.* | sed 's,^.*libm,libm,'`' )' > 32/libmudflapth.so -%endif %if %{build_go} rm -f libgo.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgo.so.4.* | sed 's,^.*libg,libg,'`' )' > libgo.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgo.so.4.* | sed 's,^.*libg,libg,'`' )' > 32/libgo.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > libgo.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgo.so.14.* | sed 's,^.*libg,libg,'`' )' > 32/libgo.so %endif %if %{build_libquadmath} rm -f libquadmath.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libquadmath.so.0.* | sed 's,^.*libq,libq,'`' )' > libquadmath.so echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libquadmath.so.0.* | sed 's,^.*libq,libq,'`' )' > 32/libquadmath.so %endif +%if %{build_d} +rm -f libgdruntime.so libgphobos.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > libgdruntime.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgdruntime.so.76.* | sed 's,^.*libg,libg,'`' )' > 32/libgdruntime.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > libgphobos.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgphobos.so.76.* | sed 's,^.*libg,libg,'`' )' > 32/libgphobos.so +%endif %if %{build_libitm} rm -f libitm.so echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libitm.so.1.* | sed 's,^.*libi,libi,'`' )' > libitm.so @@ -1415,16 +1218,18 @@ echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libatomic.so.1.* | sed 's, %endif %if %{build_libasan} rm -f libasan.so -echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libasan.so.4.* | sed 's,^.*liba,liba,'`' )' > libasan.so -echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libasan.so.4.* | sed 's,^.*liba,liba,'`' )' > 32/libasan.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > libasan.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libasan.so.5.* | sed 's,^.*liba,liba,'`' )' > 32/libasan.so mv ../../../../lib/libasan_preinit.o 32/libasan_preinit.o %endif -%if %{build_java} -ln -sf ../`echo ../../../../lib64/libgcj.so.14.* | sed s~/../lib64/~/~` 32/libgcj.so -ln -sf ../`echo ../../../../lib64/libgcj-tools.so.14.* | sed s~/../lib64/~/~` 32/libgcj-tools.so -ln -sf ../`echo ../../../../lib64/libgij.so.14.* | sed s~/../lib64/~/~` 32/libgij.so +%if %{build_libubsan} +rm -f libubsan.so +echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libubsan.so.1.* | sed 's,^.*libu,libu,'`' )' > libubsan.so +echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libubsan.so.1.* | sed 's,^.*libu,libu,'`' )' > 32/libubsan.so %endif +%if %{build_objc} mv -f %{buildroot}%{_prefix}/lib/libobjc.*a 32/ +%endif mv -f %{buildroot}%{_prefix}/lib/libgomp.*a 32/ %endif %ifarch sparc64 ppc64 ppc64p7 @@ -1432,16 +1237,20 @@ ln -sf ../lib32/libgfortran.a 32/libgfortran.a ln -sf lib64/libgfortran.a libgfortran.a ln -sf ../lib32/libstdc++.a 32/libstdc++.a ln -sf lib64/libstdc++.a libstdc++.a +ln -sf ../lib32/libstdc++fs.a 32/libstdc++fs.a +ln -sf lib64/libstdc++fs.a libstdc++fs.a ln -sf ../lib32/libsupc++.a 32/libsupc++.a ln -sf lib64/libsupc++.a libsupc++.a -#ln -sf ../lib32/libmudflap.a 32/libmudflap.a -#ln -sf lib64/libmudflap.a libmudflap.a -#ln -sf ../lib32/libmudflapth.a 32/libmudflapth.a -#ln -sf lib64/libmudflapth.a libmudflapth.a %if %{build_libquadmath} ln -sf ../lib32/libquadmath.a 32/libquadmath.a ln -sf lib64/libquadmath.a libquadmath.a %endif +%if %{build_d} +ln -sf ../lib32/libgdruntime.a 32/libgdruntime.a +ln -sf lib64/libgdruntime.a libgdruntime.a +ln -sf ../lib32/libgphobos.a 32/libgphobos.a +ln -sf lib64/libgphobos.a libgphobos.a +%endif %if %{build_libitm} ln -sf ../lib32/libitm.a 32/libitm.a ln -sf lib64/libitm.a libitm.a @@ -1454,15 +1263,17 @@ ln -sf lib64/libatomic.a libatomic.a ln -sf ../lib32/libasan.a 32/libasan.a ln -sf lib64/libasan.a libasan.a %endif +%if %{build_libubsan} +ln -sf ../lib32/libubsan.a 32/libubsan.a +ln -sf lib64/libubsan.a libubsan.a +%endif %if %{build_go} ln -sf ../lib32/libgo.a 32/libgo.a ln -sf lib64/libgo.a libgo.a ln -sf ../lib32/libgobegin.a 32/libgobegin.a ln -sf lib64/libgobegin.a libgobegin.a -%endif -%if %{build_java} -ln -sf ../lib32/libgcj_bc.so 32/libgcj_bc.so -ln -sf lib64/libgcj_bc.so libgcj_bc.so +ln -sf ../lib32/libgolibbegin.a 32/libgolibbegin.a +ln -sf lib64/libgolibbegin.a libgolibbegin.a %endif %if %{build_ada} ln -sf ../lib32/adainclude 32/adainclude @@ -1472,62 +1283,82 @@ ln -sf lib64/adalib adalib %endif %else %ifarch %{multilib_64_archs} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libgfortran.a 32/libgfortran.a -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libstdc++.a 32/libstdc++.a -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libsupc++.a 32/libsupc++.a -#ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libmudflap.a 32/libmudflap.a -#ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libmudflapth.a 32/libmudflapth.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgfortran.a 32/libgfortran.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libstdc++.a 32/libstdc++.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libstdc++fs.a 32/libstdc++fs.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libsupc++.a 32/libsupc++.a %if %{build_libquadmath} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libquadmath.a 32/libquadmath.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libquadmath.a 32/libquadmath.a +%endif +%if %{build_d} +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgdruntime.a 32/libgdruntime.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgphobos.a 32/libgphobos.a %endif %if %{build_libitm} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libitm.a 32/libitm.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libitm.a 32/libitm.a %endif %if %{build_libatomic} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libatomic.a 32/libatomic.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libatomic.a 32/libatomic.a %endif %if %{build_libasan} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libasan.a 32/libasan.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libasan.a 32/libasan.a %endif -%if %{build_go} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libgo.a 32/libgo.a -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libgobegin.a 32/libgobegin.a +%if %{build_libubsan} +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libubsan.a 32/libubsan.a %endif -%if %{build_java} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/libgcj_bc.so 32/libgcj_bc.so +%if %{build_go} +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgo.a 32/libgo.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgobegin.a 32/libgobegin.a +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgolibbegin.a 32/libgolibbegin.a %endif %if %{build_ada} -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/adainclude 32/adainclude -ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{version}/adalib 32/adalib +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/adainclude 32/adainclude +ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/adalib 32/adalib +%endif %endif %endif + +# If we are building a debug package then copy all of the static archives +# into the debug directory to keep them as unstripped copies. +%if 0%{?_enable_debug_packages} +for d in . $FULLLSUBDIR; do + mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/debug%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/$d + for f in `find $d -maxdepth 1 -a \ + \( -name libasan.a -o -name libatomic.a \ + -o -name libcaf_single.a \ + -o -name libgcc.a -o -name libgcc_eh.a \ + -o -name libgcov.a -o -name libgfortran.a \ + -o -name libgo.a -o -name libgobegin.a \ + -o -name libgolibbegin.a -o -name libgomp.a \ + -o -name libitm.a -o -name liblsan.a \ + -o -name libobjc.a -o -name libgdruntime.a -o -name libgphobos.a \ + -o -name libquadmath.a -o -name libstdc++.a \ + -o -name libstdc++fs.a -o -name libsupc++.a \ + -o -name libtsan.a -o -name libubsan.a \) -a -type f`; do + cp -a $f $RPM_BUILD_ROOT%{_prefix}/lib/debug%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/$d/ + done +done %endif # Strip debug info from Fortran/ObjC/Java static libraries -%if 0 strip -g `find . \( -name libgfortran.a -o -name libobjc.a -o -name libgomp.a \ - -o -name libmudflap.a -o -name libmudflapth.a \ -o -name libgcc.a -o -name libgcov.a -o -name libquadmath.a \ + -o -name libgdruntime.a -o -name libgphobos.a \ -o -name libitm.a -o -name libgo.a -o -name libcaf\*.a \ - -o -name libatomic.a -o -name libasan.a -o -name libtsan.a \) \ + -o -name libatomic.a -o -name libasan.a -o -name libtsan.a \ + -o -name libubsan.a -o -name liblsan.a -o -name libcc1.a \) \ -a -type f` -%endif - -strip -g `find . \( -name libgfortran.a -o -name libobjc.a -o -name libgomp.a \ - -o -name libgcc.a -o -name libgcov.a -o -name libquadmath.a \ - -o -name libitm.a -o -name libgo.a -o -name libcaf\*.a \ - -o -name libatomic.a -o -name libasan.a -o -name libtsan.a \) \ - -a -type f` - - popd -chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgfortran.so.4.* +chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgfortran.so.5.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgomp.so.1.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libcc1.so.0.* -#chmod 755 %{buildroot}%{_prefix}/%{_lib}/libmudflap{,th}.so.0.* %if %{build_libquadmath} chmod 755 %{buildroot}%{_prefix}/%{_lib}/libquadmath.so.0.* %endif +%if %{build_d} +chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgdruntime.so.76.* +chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgphobos.so.76.* +%endif %if %{build_libitm} chmod 755 %{buildroot}%{_prefix}/%{_lib}/libitm.so.1.* %endif @@ -1535,24 +1366,39 @@ chmod 755 %{buildroot}%{_prefix}/%{_lib}/libitm.so.1.* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libatomic.so.1.* %endif %if %{build_libasan} -chmod 755 %{buildroot}%{_prefix}/%{_lib}/libasan.so.4.* +chmod 755 %{buildroot}%{_prefix}/%{_lib}/libasan.so.5.* +%endif +%if %{build_libubsan} +chmod 755 %{buildroot}%{_prefix}/%{_lib}/libubsan.so.1.* %endif %if %{build_libtsan} chmod 755 %{buildroot}%{_prefix}/%{_lib}/libtsan.so.0.* %endif -%if %{build_go} -chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgo.so.4.* +%if %{build_liblsan} +chmod 755 %{buildroot}%{_prefix}/%{_lib}/liblsan.so.0.* %endif +%if %{build_go} +# Avoid stripping these libraries and binaries. +chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.14.* +chmod 644 %{buildroot}%{_prefix}/bin/go.gcc +chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json +chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet +%endif +%if %{build_objc} chmod 755 %{buildroot}%{_prefix}/%{_lib}/libobjc.so.4.* +%endif %if %{build_ada} chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgnarl*so* chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgnat*so* %endif -mv $FULLHPATH/include-fixed/syslimits.h $FULLHPATH/include/syslimits.h -mv $FULLHPATH/include-fixed/limits.h $FULLHPATH/include/limits.h -for h in `find $FULLHPATH/include -name \*.h`; do +mv $FULLPATH/include-fixed/syslimits.h $FULLPATH/include/syslimits.h +mv $FULLPATH/include-fixed/limits.h $FULLPATH/include/limits.h +for h in `find $FULLPATH/include -name \*.h`; do if grep -q 'It has been auto-edited by fixincludes from' $h; then rh=`grep -A2 'It has been auto-edited by fixincludes from' $h | tail -1 | sed 's|^.*"\(.*\)".*$|\1|'` diff -up $rh $h || : @@ -1586,49 +1432,24 @@ exec gcc $fl ${1+"$@"} EOF chmod 755 %{buildroot}%{_prefix}/bin/c?9 -%if "%{version}" != "%{gcc_version}" -mv -f $RPM_BUILD_ROOT%{_prefix}/libexec/gcc/%{gcc_target_platform}/{%{version},%{gcc_version}} -ln -sf %{gcc_version} $RPM_BUILD_ROOT%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -mv -f $RPM_BUILD_ROOT%{_prefix}/lib/gcc/%{gcc_target_platform}/{%{version},%{gcc_version}} -ln -sf %{gcc_version} $RPM_BUILD_ROOT%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -mv -f $RPM_BUILD_ROOT%{_prefix}/include/c++/{%{version},%{gcc_version}} -ln -sf %{gcc_version} $RPM_BUILD_ROOT%{_prefix}/include/c++/%{version} -mv -f $RPM_BUILD_ROOT%{_prefix}/share/gcc-{%{version},%{gcc_version}} -ln -sf gcc-%{gcc_version} $RPM_BUILD_ROOT%{_prefix}/share/gcc-%{version} -%if %{build_java} -mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/gcj-{%{version},%{gcc_version}} -ln -sf gcj-%{gcc_version} $RPM_BUILD_ROOT%{_prefix}/%{_lib}/gcj-%{version} -mv -f $RPM_BUILD_ROOT%{_prefix}/share/java/libgcj-{%{version},%{gcc_version}}.jar -ln -sf libgcj-%{gcc_version}.jar $RPM_BUILD_ROOT%{_prefix}/share/java/libgcj-%{version}.jar -mv -f $RPM_BUILD_ROOT%{_prefix}/share/java/libgcj-tools-{%{version},%{gcc_version}}.jar -ln -sf libgcj-tools-%{gcc_version}.jar $RPM_BUILD_ROOT%{_prefix}/share/java/libgcj-tools-%{version}.jar -mv -f $RPM_BUILD_ROOT%{_prefix}/share/java/src-{%{version},%{gcc_version}}.zip -ln -sf src-%{gcc_version}.zip $RPM_BUILD_ROOT%{_prefix}/share/java/src-%{version}.zip -%endif -%if %{build_go} -mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/go/{%{version},%{gcc_version}} -ln -sf %{gcc_version} $RPM_BUILD_ROOT%{_prefix}/%{_lib}/go/%{version} -%endif -%endif - cd .. %find_lang %{name} %find_lang cpplib # Remove binaries we will not be including, so that they don't end up in # gcc-debuginfo -rm -f %{buildroot}%{_prefix}/%{_lib}/{libffi*,libiberty.a} +rm -f %{buildroot}%{_prefix}/%{_lib}/{libffi*,libiberty.a} || : rm -f $FULLEPATH/install-tools/{mkheaders,fixincl} rm -f %{buildroot}%{_prefix}/lib/{32,64}/libiberty.a rm -f %{buildroot}%{_prefix}/%{_lib}/libssp* -rm -f %{buildroot}%{_prefix}/bin/gappletviewer || : -rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcc-%{version} || : +rm -f %{buildroot}%{_prefix}/%{_lib}/libvtv* || : rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gfortran || : rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gccgo || : rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcj || : rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcc-ar || : rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcc-nm || : rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcc-ranlib || : +rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gdc || : %ifarch %{multilib_64_archs} # Remove libraries for the other arch on multilib arches @@ -1636,13 +1457,9 @@ rm -f %{buildroot}%{_prefix}/lib/lib*.so* rm -f %{buildroot}%{_prefix}/lib/lib*.a rm -f %{buildroot}/lib/libgcc_s*.so* %if %{build_go} -%if "%{version}" != "%{gcc_version}" -mv -f $RPM_BUILD_ROOT%{_prefix}/lib/go/{%{version},%{gcc_version}} -ln -sf %{gcc_version} $RPM_BUILD_ROOT%{_prefix}/lib/go/%{version} -%endif -rm -rf %{buildroot}%{_prefix}/lib/go/%{gcc_version}/%{gcc_target_platform} +rm -rf %{buildroot}%{_prefix}/lib/go/%{gcc_major}/%{gcc_target_platform} %ifnarch sparc64 ppc64 ppc64p7 -ln -sf %{multilib_32_arch}-%{_vendor}-%{_target_os} %{buildroot}%{_prefix}/lib/go/%{gcc_version}/%{gcc_target_platform} +ln -sf %{multilib_32_arch}-%{_vendor}-%{_target_os} %{buildroot}%{_prefix}/lib/go/%{gcc_major}/%{gcc_target_platform} %endif %endif %else @@ -1651,45 +1468,23 @@ rm -f %{buildroot}%{_prefix}/lib64/lib*.so* rm -f %{buildroot}%{_prefix}/lib64/lib*.a rm -f %{buildroot}/lib64/libgcc_s*.so* %if %{build_go} -%if "%{version}" != "%{gcc_version}" -mv -f $RPM_BUILD_ROOT%{_prefix}/lib64/go/{%{version},%{gcc_version}} -ln -sf %{gcc_version} $RPM_BUILD_ROOT%{_prefix}/lib64/go/%{version} -%endif -rm -rf %{buildroot}%{_prefix}/lib64/go/%{gcc_version}/%{gcc_target_platform} -%endif +rm -rf %{buildroot}%{_prefix}/lib64/go/%{gcc_major}/%{gcc_target_platform} %endif %endif - -%if %{build_java} -mkdir -p %{buildroot}%{_prefix}/share/java/gcj-endorsed \ - %{buildroot}%{_prefix}/%{_lib}/gcj-%{gcc_version}/classmap.db.d -chmod 755 %{buildroot}%{_prefix}/share/java/gcj-endorsed \ - %{buildroot}%{_prefix}/%{_lib}/gcj-%{gcc_version} \ - %{buildroot}%{_prefix}/%{_lib}/gcj-%{gcc_version}/classmap.db.d -touch %{buildroot}%{_prefix}/%{_lib}/gcj-%{gcc_version}/classmap.db %endif rm -f %{buildroot}%{mandir}/man3/ffi* # Help plugins find out nvra. -echo gcc-%{version}-%{release}.%{_arch} > $FULLHPATH/rpmver +echo gcc-%{version}-%{release}.%{_arch} > $FULLPATH/rpmver %check - -%if %{build_check} - cd obj-%{gcc_target_platform} -%if %{build_java} -export PATH=`pwd`/../fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}${PATH:+:$PATH} -%if !%{bootstrap_java} -export PATH=`pwd`/java_hacks${PATH:+:$PATH} -%endif -%endif -%if 0 +%if %{build_check} # run the tests. -make %{?_smp_mflags} -k check ALT_CC_UNDER_TEST=gcc ALT_CXX_UNDER_TEST=g++ \ -RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector-strong}'" || : +LC_ALL=C make -j %{?_smp_mflags} -k check ALT_CC_UNDER_TEST=gcc ALT_CXX_UNDER_TEST=g++ \ + RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector-strong}'" || : echo ====================TESTING========================= ( LC_ALL=C ../contrib/test_summary || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}' echo ====================TESTING END===================== @@ -1697,214 +1492,82 @@ mkdir testlogs-%{_target_platform}-%{version}-%{release} for i in `find . -name \*.log | grep -F testsuite/ | grep -v 'config.log\|acats.*/tests/'`; do ln $i testlogs-%{_target_platform}-%{version}-%{release}/ || : done -tar cf - testlogs-%{_target_platform}-%{version}-%{release} | bzip2 -9c \ - | uuencode testlogs-%{_target_platform}.tar.bz2 || : +tar cf - testlogs-%{_target_platform}-%{version}-%{release} | xz -9e \ + | uuencode testlogs-%{_target_platform}.tar.xz || : rm -rf testlogs-%{_target_platform}-%{version}-%{release} %endif -%endif #build_check - -%clean -rm -rf %{buildroot} - -%post -if [ -f %{_infodir}/gcc.info.gz ]; then - /sbin/install-info \ - --info-dir=%{_infodir} %{_infodir}/gcc.info.gz || : -fi - -%preun -if [ $1 = 0 -a -f %{_infodir}/gcc.info.gz ]; then - /sbin/install-info --delete \ - --info-dir=%{_infodir} %{_infodir}/gcc.info.gz || : -fi - -%post -n cpp -if [ -f %{_infodir}/cpp.info.gz ]; then - /sbin/install-info \ - --info-dir=%{_infodir} %{_infodir}/cpp.info.gz || : -fi +%post go +%{_sbindir}/update-alternatives --install \ + %{_prefix}/bin/go go %{_prefix}/bin/go.gcc 92 \ + --slave %{_prefix}/bin/gofmt gofmt %{_prefix}/bin/gofmt.gcc -%preun -n cpp -if [ $1 = 0 -a -f %{_infodir}/cpp.info.gz ]; then - /sbin/install-info --delete \ - --info-dir=%{_infodir} %{_infodir}/cpp.info.gz || : +%preun go +if [ $1 = 0 ]; then + %{_sbindir}/update-alternatives --remove go %{_prefix}/bin/go.gcc fi -#%post gfortran -#if [ -f %{_infodir}/gfortran.info.gz ]; then -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/gfortran.info.gz || : -#fi - -#%preun gfortran -#if [ $1 = 0 -a -f %{_infodir}/gfortran.info.gz ]; then -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/gfortran.info.gz || : -#fi - -#%post java -#if [ -f %{_infodir}/gcj.info.gz ]; then -#/sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/gcj.info.gz || : -#fi - -#%preun java -#if [ $1 = 0 -a -f %{_infodir}/gcj.info.gz ]; then -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/gcj.info.gz || : -#fi - -#%post gnat -#if [ -f %{_infodir}/gnat_rm.info.gz ]; then -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/gnat_rm.info.gz || : -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/gnat_ugn.info.gz || : -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/gnat-style.info.gz || : -#fi - -#%preun gnat -#if [ $1 = 0 -a -f %{_infodir}/gnat_rm.info.gz ]; then -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/gnat_rm.info.gz || : -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/gnat_ugn.info.gz || : -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/gnat-style.info.gz || : -#fi - # Because glibc Prereq's libgcc and /sbin/ldconfig # comes from glibc, it might not exist yet when # libgcc is installed -#%post -n libgcc -p -#if posix.access ("/sbin/ldconfig", "x") then -# local pid = posix.fork () -# if pid == 0 then -# posix.exec ("/sbin/ldconfig") -# elseif pid ~= -1 then -# posix.wait (pid) -# end -#end - -#%postun -n libgcc -p -#if posix.access ("/sbin/ldconfig", "x") then -# local pid = posix.fork () -# if pid == 0 then -# posix.exec ("/sbin/ldconfig") -# elseif pid ~= -1 then -# posix.wait (pid) -# end -#end - -%post -n libstdc++ -p /sbin/ldconfig - -%postun -n libstdc++ -p /sbin/ldconfig - -#%post -n libobjc -p /sbin/ldconfig - -#%postun -n libobjc -p /sbin/ldconfig - -#%post -n libgcj -#/sbin/ldconfig -#if [ -f %{_infodir}/cp-tools.info.gz ]; then -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/cp-tools.info.gz || : -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/fastjar.info.gz || : -#fi - -#%preun -n libgcj -#if [ $1 = 0 -a -f %{_infodir}/cp-tools.info.gz ]; then -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/cp-tools.info.gz || : -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/fastjar.info.gz || : -#fi - -#%postun -n libgcj -p /sbin/ldconfig - -#%post -n libgfortran -p /sbin/ldconfig - -#%postun -n libgfortran -p /sbin/ldconfig - -#%post -n libgnat -p /sbin/ldconfig - -#%postun -n libgnat -p /sbin/ldconfig - -%post -n libgomp -/sbin/ldconfig -if [ -f %{_infodir}/libgomp.info.gz ]; then - /sbin/install-info \ - --info-dir=%{_infodir} %{_infodir}/libgomp.info.gz || : -fi - -%preun -n libgomp -if [ $1 = 0 -a -f %{_infodir}/libgomp.info.gz ]; then - /sbin/install-info --delete \ - --info-dir=%{_infodir} %{_infodir}/libgomp.info.gz || : -fi - -%postun -n libgomp -p /sbin/ldconfig +%post -n libgcc -p +if posix.access ("/sbin/ldconfig", "x") then + local pid = posix.fork () + if pid == 0 then + posix.exec ("/sbin/ldconfig") + elseif pid ~= -1 then + posix.wait (pid) + end +end -#%post -n libmudflap -p /sbin/ldconfig +%postun -n libgcc -p +if posix.access ("/sbin/ldconfig", "x") then + local pid = posix.fork () + if pid == 0 then + posix.exec ("/sbin/ldconfig") + elseif pid ~= -1 then + posix.wait (pid) + end +end -#%postun -n libmudflap -p /sbin/ldconfig +%ldconfig_scriptlets -n libstdc++ -#%post -n libquadmath -#/sbin/ldconfig -#if [ -f %{_infodir}/libquadmath.info.gz ]; then -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/libquadmath.info.gz || : -#fi +%ldconfig_scriptlets -n libobjc -#%preun -n libquadmath -#if [ $1 = 0 -a -f %{_infodir}/libquadmath.info.gz ]; then -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/libquadmath.info.gz || : -#fi +%ldconfig_scriptlets -n libgfortran -#%postun -n libquadmath -p /sbin/ldconfig +%ldconfig_scriptlets -n libgphobos -#%post -n libitm -#/sbin/ldconfig -#if [ -f %{_infodir}/libitm.info.gz ]; then -# /sbin/install-info \ -# --info-dir=%{_infodir} %{_infodir}/libitm.info.gz || : -#fi +%ldconfig_scriptlets -n libgnat -#%preun -n libitm -#if [ $1 = 0 -a -f %{_infodir}/libitm.info.gz ]; then -# /sbin/install-info --delete \ -# --info-dir=%{_infodir} %{_infodir}/libitm.info.gz || : -#fi +%ldconfig_scriptlets -n libgomp -#%postun -n libitm -p /sbin/ldconfig +%ldconfig_scriptlets gdb-plugin -#%post -n libatomic -p /sbin/ldconfig +%ldconfig_scriptlets -n libgquadmath -#%postun -n libatomic -p /sbin/ldconfig +%ldconfig_scriptlets -n libitm -#%post -n libasan -p /sbin/ldconfig +%ldconfig_scriptlets -n libatomic -#%postun -n libasan -p /sbin/ldconfig +%ldconfig_scriptlets -n libasan -#%post -n libtsan -p /sbin/ldconfig +%ldconfig_scriptlets -n libubsan -#%postun -n libtsan -p /sbin/ldconfig +%ldconfig_scriptlets -n libtsan -#%post -n libgo -p /sbin/ldconfig +%ldconfig_scriptlets -n liblsan -#%postun -n libgo -p /sbin/ldconfig +%ldconfig_scriptlets -n libgo %files -f %{name}.lang -%defattr(-,root,root,-) %{_prefix}/bin/cc %{_prefix}/bin/c89 %{_prefix}/bin/c99 %{_prefix}/bin/gcc %{_prefix}/bin/gcov +%{_prefix}/bin/gcov-tool +%{_prefix}/bin/gcov-dump %{_prefix}/bin/gcc-ar %{_prefix}/bin/gcc-nm %{_prefix}/bin/gcc-ranlib @@ -1918,1436 +1581,946 @@ fi %{_prefix}/bin/ppc-%{_vendor}-%{_target_os}-gcc %endif %{_prefix}/bin/%{gcc_target_platform}-gcc +%{_prefix}/bin/%{gcc_target_platform}-gcc-%{gcc_major} %{_mandir}/man1/gcc.1* %{_mandir}/man1/gcov.1* +%{_mandir}/man1/gcov-tool.1* +%{_mandir}/man1/gcov-dump.1* %{_infodir}/gcc* %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/lto1 -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/lto-wrapper -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/liblto_plugin.so* -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/rpmver -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stddef.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdarg.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdfix.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/varargs.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/float.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/limits.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdbool.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/iso646.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/syslimits.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/unwind.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/omp.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/openacc.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdint.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdint-gcc.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdalign.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdnoreturn.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/stdatomic.h +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/lto1 +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/lto-wrapper +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/liblto_plugin.so* +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/rpmver +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stddef.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdarg.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdfix.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/varargs.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/float.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/limits.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdbool.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/iso646.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/syslimits.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/unwind.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/omp.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/openacc.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint-gcc.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdalign.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdnoreturn.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdatomic.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/gcov.h %ifarch %{ix86} x86_64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/mmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/xmmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/emmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/pmmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/tmmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/ammintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/smmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/nmmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/bmmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/wmmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/immintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avxintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/x86intrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/fma4intrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/xopintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/lwpintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/popcntintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/bmiintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/tbmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/ia32intrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx2intrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/bmi2intrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/f16cintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/fmaintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/lzcntintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/rtmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/xtestintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/adxintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/prfchwintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/rdseedintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/fxsrintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/xsaveintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/xsaveoptintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/mm_malloc.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/mm3dnow.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cpuid.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cross-stdarg.h - -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx5124fmapsintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx5124vnniwintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512bwintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512cdintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512dqintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512erintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512fintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512ifmaintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512ifmavlintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512pfintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512vbmiintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512vbmivlintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512vlbwintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512vldqintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512vlintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/avx512vpopcntdqintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/cilk.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/cilk_api.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/cilk_api_linux.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/cilk_stub.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/cilk_undocumented.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/common.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/holder.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/hyperobject_base.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/metaprogramming.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_file.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_list.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_max.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_min.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_min_max.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_opadd.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_opand.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_opmul.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_opor.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_opxor.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_ostream.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/cilk/reducer_string.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/clflushoptintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/clwbintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/clzerointrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/gcov.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/mwaitxintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/pkuintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/quadmath.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/quadmath_weak.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/sgxintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/shaintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/xsavecintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/xsavesintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/emmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/pmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/tmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ammintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/smmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/nmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/wmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/immintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avxintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/x86intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/fma4intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xopintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/lwpintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/popcntintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmiintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/tbmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ia32intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx2intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmi2intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/f16cintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/fmaintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/lzcntintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/rtmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xtestintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/adxintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/prfchwintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/rdseedintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/fxsrintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsaveintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsaveoptintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512cdintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512erintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512fintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512pfintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/shaintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mm_malloc.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mm3dnow.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cpuid.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cross-stdarg.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bwintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512dqintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512ifmaintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512ifmavlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmiintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmivlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vlbwintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vldqintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/clflushoptintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/clwbintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mwaitxintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsavecintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsavesintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/clzerointrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/pkuintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx5124fmapsintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx5124vnniwintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vpopcntdqintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/sgxintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/gfniintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cetintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cet.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmi2intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmi2vlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vnniintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vnnivlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/vaesintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/vpclmulqdqintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vpopcntdqvlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bitalgintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/pconfigintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/wbnoinvdintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/movdirintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/waitpkgintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cldemoteintrin.h %endif %ifarch ia64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/ia64intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ia64intrin.h %endif %ifarch ppc ppc64 ppc64le ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/ppc-asm.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/altivec.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/spe.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/paired.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/ppu_intrinsics.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/si2vmx.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/spu2vmx.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/vec_types.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/htmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/htmxlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ppc-asm.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/altivec.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ppu_intrinsics.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/si2vmx.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/spu2vmx.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/vec_types.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/htmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/htmxlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmi2intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmiintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mm_malloc.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/emmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/x86intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/pmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/tmmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/smmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amo.h %endif %ifarch %{arm} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/unwind-arm-common.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/mmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/arm_neon.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/unwind-arm-common.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_neon.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_acle.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_cmse.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_fp16.h %endif %ifarch aarch64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/arm_neon.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/arm_fp16.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/arm_acle.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_neon.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_acle.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_fp16.h %endif %ifarch sparc sparcv9 sparc64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/visintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/visintrin.h %endif %ifarch s390 s390x -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/s390intrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/htmintrin.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/htmxlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/s390intrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/htmintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/htmxlintrin.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/vecintrin.h %endif %if %{build_libasan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/sanitizer -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/collect2 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/crt*.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcov.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcc_eh.a -%ifnarch aarch64_ilp32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcc_s.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgomp.spec -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgomp.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgomp.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/sanitizer +%endif +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/collect2 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/crt*.o +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcc.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcov.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcc_eh.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcc_s.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.spec +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.so %if %{build_libitm} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libitm.spec -%endif -%if %{build_cloog} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libcloog-isl.so.* +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.spec %endif %if %{build_libasan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libsanitizer.spec -%endif +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libsanitizer.spec %endif %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/crt*.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcov.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcc_eh.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcc_s.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgomp.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgomp.so -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libmudflap.a -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libmudflapth.a -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libmudflap.so -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libmudflapth.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/crt*.o +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgcc.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgcov.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgcc_eh.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgcc_s.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgomp.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgomp.so %if %{build_libquadmath} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libquadmath.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libquadmath.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libquadmath.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libquadmath.so %endif %if %{build_libitm} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libitm.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libitm.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libitm.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libitm.so %endif %if %{build_libatomic} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libatomic.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libatomic.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libatomic.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libatomic.so %endif %if %{build_libasan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libasan.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libasan.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libasan_preinit.o -%endif +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libasan.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libasan.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libasan_preinit.o %endif -%ifarch aarch64 aarch64_ilp32 -%if %{build_libilp32} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgomp.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgomp.so +%if %{build_libubsan} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libubsan.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libubsan.so %endif %endif %ifarch %{multilib_64_archs} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/crt*.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgcc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgcov.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgcc_eh.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgcc_s.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgomp.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgomp.so -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libmudflap.a -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libmudflapth.a -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libmudflap.so -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libmudflapth.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/crt*.o +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcc.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcov.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcc_eh.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcc_s.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgomp.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgomp.so %if %{build_libquadmath} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libquadmath.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libquadmath.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libquadmath.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libquadmath.so %endif %if %{build_libitm} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libitm.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libitm.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libitm.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libitm.so %endif %if %{build_libatomic} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libatomic.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libatomic.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libatomic.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libatomic.so %endif %if %{build_libasan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libasan.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libasan.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libasan_preinit.o +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libasan.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libasan.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libasan_preinit.o +%endif +%if %{build_libubsan} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libubsan.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libubsan.so %endif %endif %ifarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflapth.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflapth.so %if %{build_libquadmath} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libquadmath.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libquadmath.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libquadmath.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libquadmath.so %endif %if %{build_libitm} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libitm.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libitm.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.so %endif %if %{build_libatomic} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libatomic.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libatomic.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libatomic.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libatomic.so %endif %if %{build_libasan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libasan.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libasan.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libasan_preinit.o +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan_preinit.o %endif -%if %{build_libtsan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libtsan.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libtsan.so +%if %{build_libubsan} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libubsan.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libubsan.so %endif %else %if %{build_libatomic} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libatomic.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libatomic.so %endif %if %{build_libasan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libasan.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libasan_preinit.o +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan_preinit.o %endif -%if %{build_libtsan} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libtsan.so +%if %{build_libubsan} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libubsan.so %endif %endif -%ifarch aarch64 arch64_ilp32 -%if %{build_libilp32} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgcc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgcc_eh.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/crtfastmath.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/crtend.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/crtendS.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/crtbeginT.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/crtbegin.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgcov.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/crtbeginS.o -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgcc_s.so +%if %{build_libtsan} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libtsan.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libtsan_preinit.o %endif +%if %{build_liblsan} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan_preinit.o %endif -%dir %{_prefix}/libexec/getconf %{_prefix}/libexec/getconf/default -#%doc gcc/README* rpm.doc/changelogs/gcc/ChangeLog* gcc/COPYING* COPYING.RUNTIME +%doc gcc/README* rpm.doc/changelogs/gcc/ChangeLog* +%{!?_licensedir:%global license %%doc} +%license gcc/COPYING* COPYING.RUNTIME %files -n cpp -f cpplib.lang -%defattr(-,root,root,-) %{_prefix}/lib/cpp %{_prefix}/bin/cpp %{_mandir}/man1/cpp.1* %{_infodir}/cpp* %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1 +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1 %files -n libgcc -%defattr(-,root,root,-) -/%{_lib}/libgcc_s-%{version}-%{DATE}.so.1 +/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1 /%{_lib}/libgcc_s.so.1 -%doc gcc/COPYING* COPYING.RUNTIME - -%ifarch aarch64 -%if %{build_libilp32} -%files -n libgcc-32 -%defattr(-,root,root,-) -/libilp32/libgcc_s-%{version}-%{DATE}.so.1 -/libilp32/libgcc_s.so.1 -%endif -%endif +%{!?_licensedir:%global license %%doc} +%license gcc/COPYING* COPYING.RUNTIME %files c++ -%defattr(-,root,root,-) %{_prefix}/bin/%{gcc_target_platform}-*++ %{_prefix}/bin/g++ %{_prefix}/bin/c++ %{_mandir}/man1/g++.1* %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1plus +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1plus %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libstdc++.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libstdc++.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libsupc++.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libstdc++.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libstdc++.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libstdc++fs.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libsupc++.a %endif %ifarch %{multilib_64_archs} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libstdc++.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libstdc++.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libsupc++.a -%endif -%ifarch aarch64 aarch64_ilp32 -%if %{build_libilp32} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libstdc++.so -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libstdc++.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libstdc++.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libstdc++fs.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libsupc++.a %endif %ifarch sparcv9 ppc %{multilib_64_archs} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++.so %endif %ifarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libsupc++.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++fs.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libsupc++.a %endif -#%doc rpm.doc/changelogs/gcc/cp/ChangeLog* +%doc rpm.doc/changelogs/gcc/cp/ChangeLog* %files -n libstdc++ -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libstdc++.so.6* %dir %{_datadir}/gdb %dir %{_datadir}/gdb/auto-load %dir %{_datadir}/gdb/auto-load/%{_prefix} %dir %{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/ %{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc*gdb.py* -%dir %{_prefix}/share/gcc-%{gcc_version} -%dir %{_prefix}/share/gcc-%{gcc_version}/python -%if "%{version}" != "%{gcc_version}" -%{_prefix}/share/gcc-%{version} -%endif -%{_prefix}/share/gcc-%{gcc_version}/python/libstdcxx - -%ifarch aarch64 -%if %{build_libilp32} -%files -n libstdc++-32 -%defattr(-,root,root,-) -%{_prefix}/libilp32/libstdc++.so.6* -%dir %{_datadir}/gdb/auto-load/%{_prefix}/libilp32/ -%{_datadir}/gdb/auto-load/%{_prefix}/libilp32/libstdc*gdb.py* -%endif -%endif +%dir %{_prefix}/share/gcc-%{gcc_major} +%dir %{_prefix}/share/gcc-%{gcc_major}/python +%{_prefix}/share/gcc-%{gcc_major}/python/libstdcxx %files -n libstdc++-devel -%defattr(-,root,root,-) %dir %{_prefix}/include/c++ -%dir %{_prefix}/include/c++/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/include/c++/%{version} -%endif -%{_prefix}/include/c++/%{gcc_version}/[^gjos]* -%{_prefix}/include/c++/%{gcc_version}/os* -%{_prefix}/include/c++/%{gcc_version}/op* -%{_prefix}/include/c++/%{gcc_version}/s[^u]* +%{_prefix}/include/c++/%{gcc_major} %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%ifnarch sparcv9 ppc %{multilib_64_archs} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++.so +%endif +%ifarch sparcv9 ppc +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libstdc++fs.a %endif -%ifnarch sparcv9 ppc %{multilib_64_archs} aarch64_ilp32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.so +%ifarch sparc64 ppc64 ppc64p7 +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libstdc++fs.a +%endif +%ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++fs.a %endif -#%doc rpm.doc/changelogs/libstdc++-v3/ChangeLog* libstdc++-v3/README* +%doc rpm.doc/changelogs/libstdc++-v3/ChangeLog* libstdc++-v3/README* %files -n libstdc++-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libstdc++.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libsupc++.a -%endif -%ifarch aarch64 aarch64_ilp32 -%if %{build_libilp32} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libstdc++.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libsupc++.a -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libstdc++.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libsupc++.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libstdc++.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libsupc++.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libstdc++.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libsupc++.a %endif -%ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 aarch64_ilp32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libsupc++.a +%ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libsupc++.a %endif %if %{build_libstdcxx_docs} %files -n libstdc++-docs -%defattr(-,root,root) %{_mandir}/man3/* %doc rpm.doc/libstdc++-v3/html %endif - +%if %{build_objc} %files objc -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/objc -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1obj -%ifnarch aarch64_ilp32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libobjc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libobjc.so -%endif +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/objc +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1obj +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libobjc.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libobjc.so %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libobjc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libobjc.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libobjc.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libobjc.so %endif %ifarch %{multilib_64_archs} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libobjc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libobjc.so -%endif -%ifarch aarch64 aarch64_ilp32 -%if %{build_libilp32} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libobjc.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libobjc.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libobjc.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libobjc.so %endif -%endif -#%doc rpm.doc/objc/* -#%doc libobjc/THREADS* rpm.doc/changelogs/libobjc/ChangeLog* +%doc rpm.doc/objc/* +%doc libobjc/THREADS* rpm.doc/changelogs/libobjc/ChangeLog* %files objc++ -%defattr(-,root,root,-) %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1objplus +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1objplus %files -n libobjc -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libobjc.so.4* - -%ifarch aarch64 -%if %{build_libilp32} -%files -n libobjc-32 -%defattr(-,root,root,-) -%{_prefix}/libilp32/libobjc.so.4* -%endif %endif %files gfortran -%defattr(-,root,root,-) %{_prefix}/bin/gfortran %{_prefix}/bin/f95 %{_mandir}/man1/gfortran.1* %{_infodir}/gfortran* %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/omp_lib.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/omp_lib.f90 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/omp_lib.mod -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/omp_lib_kinds.mod -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/openacc.f90 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/openacc.mod -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/openacc_kinds.mod -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/openacc_lib.h -%ifarch x86_64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/ieee_arithmetic.mod -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/ieee_exceptions.mod -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/finclude/ieee_features.mod -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/f951 -%ifnarch aarch64_ilp32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortran.spec -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortranbegin.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libcaf_single.a +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ISO_Fortran_binding.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib.f90 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib.mod +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib_kinds.mod +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc.f90 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc.mod +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc_kinds.mod +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc_lib.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_arithmetic.mod +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_exceptions.mod +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_features.mod +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/f951 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.spec +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libcaf_single.a %ifarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortran.a -%endif -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortran.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.a %endif +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.so %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgfortranbegin.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libcaf_single.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgfortran.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgfortran.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libcaf_single.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgfortran.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgfortran.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/finclude %endif %ifarch %{multilib_64_archs} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32 -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgfortranbegin.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libcaf_single.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgfortran.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgfortran.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libcaf_single.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgfortran.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgfortran.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/finclude %endif -%ifarch aarch64 aarch64_ilp32 -%if %{build_libilp32} -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgfortranbegin.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libcaf_single.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgfortran.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/ilp32/libgfortran.so -%endif -%endif -#%doc rpm.doc/gfortran/* +%dir %{_fmoddir} +%doc rpm.doc/gfortran/* %files -n libgfortran -%defattr(-,root,root,-) -%{_prefix}/%{_lib}/libgfortran.so.4* - -%ifarch aarch64 -%if %{build_libilp32} -%files -n libgfortran-32 -%defattr(-,root,root,-) -%{_prefix}/libilp32/libgfortran.so.4* -%endif -%endif +%{_prefix}/%{_lib}/libgfortran.so.5* -%if 0 %files -n libgfortran-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libgfortran.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libgfortran.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libgfortran.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libgfortran.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortran.a -%endif -%endif - -%if %{build_java} -%files java -%defattr(-,root,root,-) -%{_prefix}/bin/gcj -%{_prefix}/bin/gjavah -%{_prefix}/bin/gcjh -%{_prefix}/bin/jcf-dump -%{_mandir}/man1/gcj.1* -%{_mandir}/man1/jcf-dump.1* -%{_mandir}/man1/gjavah.1* -%{_mandir}/man1/gcjh.1* -%{_infodir}/gcj* -%dir %{_prefix}/libexec/gcc -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.a %endif + +%if %{build_d} +%files gdc +%{_prefix}/bin/gdc +%{_mandir}/man1/gdc.1* +%{_infodir}/gdc* %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/jc1 -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/ecj1 -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/jvgenmain -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj-tools.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/libexec/gcc +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform} +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/d +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/d21 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgphobos.spec %ifarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj_bc.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgdruntime.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgphobos.a %endif -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgij.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgdruntime.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgphobos.so %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcj.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcj-tools.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcj_bc.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgij.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgdruntime.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgphobos.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgdruntime.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgphobos.so %endif %ifarch %{multilib_64_archs} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgcj.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgcj-tools.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgcj_bc.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgij.so -%endif -#%doc rpm.doc/changelogs/gcc/java/ChangeLog* - -%files -n libgcj -%defattr(-,root,root,-) -%{_prefix}/bin/jv-convert -%{_prefix}/bin/gij -%{_prefix}/bin/gjar -%{_prefix}/bin/fastjar -%{_prefix}/bin/gnative2ascii -%{_prefix}/bin/grepjar -%{_prefix}/bin/grmic -%{_prefix}/bin/grmid -%{_prefix}/bin/grmiregistry -%{_prefix}/bin/gtnameserv -%{_prefix}/bin/gkeytool -%{_prefix}/bin/gorbd -%{_prefix}/bin/gserialver -%{_prefix}/bin/gcj-dbtool -%{_prefix}/bin/gjarsigner -%{_mandir}/man1/fastjar.1* -%{_mandir}/man1/grepjar.1* -%{_mandir}/man1/gjar.1* -%{_mandir}/man1/gjarsigner.1* -%{_mandir}/man1/jv-convert.1* -%{_mandir}/man1/gij.1* -%{_mandir}/man1/gnative2ascii.1* -%{_mandir}/man1/grmic.1* -%{_mandir}/man1/grmiregistry.1* -%{_mandir}/man1/gcj-dbtool.1* -%{_mandir}/man1/gkeytool.1* -%{_mandir}/man1/gorbd.1* -%{_mandir}/man1/grmid.1* -%{_mandir}/man1/gserialver.1* -%{_mandir}/man1/gtnameserv.1* -%{_infodir}/fastjar.info* -%{_infodir}/cp-tools.info* -%{_prefix}/%{_lib}/libgcj.so.* -%{_prefix}/%{_lib}/libgcj-tools.so.* -%{_prefix}/%{_lib}/libgcj_bc.so.* -%{_prefix}/%{_lib}/libgij.so.* -%dir %{_prefix}/%{_lib}/gcj-%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/%{_lib}/gcj-%{version} -%endif -%{_prefix}/%{_lib}/gcj-%{gcc_version}/libgtkpeer.so -%{_prefix}/%{_lib}/gcj-%{gcc_version}/libgjsmalsa.so -%{_prefix}/%{_lib}/gcj-%{gcc_version}/libjawt.so -%{_prefix}/%{_lib}/gcj-%{gcc_version}/libjvm.so -%{_prefix}/%{_lib}/gcj-%{gcc_version}/libjavamath.so -%dir %{_prefix}/share/java -%{_prefix}/share/java/[^sl]* -%{_prefix}/share/java/libgcj-%{gcc_version}.jar -%if "%{version}" != "%{gcc_version}" -%{_prefix}/share/java/libgcj-%{version}.jar -%endif -%dir %{_prefix}/%{_lib}/security -%config(noreplace) %{_prefix}/%{_lib}/security/classpath.security -%{_prefix}/%{_lib}/logging.properties -%dir %{_prefix}/%{_lib}/gcj-%{gcc_version}/classmap.db.d -%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) %{_prefix}/%{_lib}/gcj-%{gcc_version}/classmap.db - -%files -n libgcj-devel -%defattr(-,root,root,-) +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgdruntime.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgphobos.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgdruntime.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgphobos.so +%endif +%doc rpm.doc/gdc/* + +%files -n libgphobos +%{_prefix}/%{_lib}/libgdruntime.so.76* +%{_prefix}/%{_lib}/libgphobos.so.76* +%doc rpm.doc/libphobos/* + +%files -n libgphobos-static %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/gcj -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/jawt.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/jawt_md.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/jni.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/jni_md.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/jvmpi.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj.spec +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libgcj_bc.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libgdruntime.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libgphobos.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libgcj_bc.so +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libgdruntime.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libgphobos.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj_bc.so -%endif -%dir %{_prefix}/include/c++ -%dir %{_prefix}/include/c++/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/include/c++/%{version} -%endif -%{_prefix}/include/c++/%{gcc_version}/[gj]* -%{_prefix}/include/c++/%{gcc_version}/org -%{_prefix}/include/c++/%{gcc_version}/sun -%{_prefix}/%{_lib}/pkgconfig/libgcj-*.pc -%doc rpm.doc/boehm-gc/* rpm.doc/fastjar/* rpm.doc/libffi/* -%doc rpm.doc/libjava/* - -%files -n libgcj-src -%defattr(-,root,root,-) -%dir %{_prefix}/share/java -%{_prefix}/share/java/src*.zip -%{_prefix}/share/java/libgcj-tools-%{gcc_version}.jar -%if "%{version}" != "%{gcc_version}" -%{_prefix}/share/java/libgcj-tools-%{version}.jar +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgdruntime.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgphobos.a %endif %endif %if %{build_ada} %files gnat -%defattr(-,root,root,-) %{_prefix}/bin/gnat %{_prefix}/bin/gnat[^i]* %{_infodir}/gnat* %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/adainclude -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/adalib +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/adainclude +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/adalib %endif %ifarch %{multilib_64_archs} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/adainclude -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/adalib +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adainclude +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adalib %endif %ifarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adainclude -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adalib +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adainclude +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib %endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/gnat1 -#%doc rpm.doc/changelogs/gcc/ada/ChangeLog* +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/gnat1 +%doc rpm.doc/changelogs/gcc/ada/ChangeLog* %files -n libgnat -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libgnat-*.so %{_prefix}/%{_lib}/libgnarl-*.so %files -n libgnat-devel -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/adainclude -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/adalib -%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/adalib/libgnat.a -%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/adalib/libgnarl.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/adainclude +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/adalib +%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/adalib/libgnat.a +%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/adalib/libgnarl.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/adainclude -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/adalib -%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/adalib/libgnat.a -%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/adalib/libgnarl.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/adainclude +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/adalib +%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/adalib/libgnat.a +%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/adalib/libgnarl.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adainclude -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adalib -%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adalib/libgnat.a -%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adalib/libgnarl.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adainclude +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib +%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnat.a +%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnarl.a %endif %files -n libgnat-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/adalib -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/adalib/libgnat.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/adalib/libgnarl.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/adalib +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/adalib/libgnat.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/adalib/libgnarl.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/adalib -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/adalib/libgnat.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/adalib/libgnarl.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/adalib +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/adalib/libgnat.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/adalib/libgnarl.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adalib -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adalib/libgnat.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/adalib/libgnarl.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnat.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnarl.a %endif %endif %files -n libgomp -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libgomp.so.1* %{_infodir}/libgomp.info* -#%doc rpm.doc/changelogs/libgomp/ChangeLog* - -%ifarch aarch64 -%if %{build_libilp32} -%files -n libgomp-32 -%defattr(-,root,root,-) -%{_prefix}/libilp32/libgomp.so.1* -%endif -%endif - -%if 0 -%files -n libmudflap -%defattr(-,root,root,-) -%{_prefix}/%{_lib}/libmudflap.so.0* -%{_prefix}/%{_lib}/libmudflapth.so.0* - -%files -n libmudflap-devel -%defattr(-,root,root,-) -%dir %{_prefix}/lib/gcc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/mf-runtime.h -%ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflapth.so -%endif -#%doc rpm.doc/changelogs/libmudflap/ChangeLog* - -%files -n libmudflap-static -%defattr(-,root,root,-) -%dir %{_prefix}/lib/gcc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif -%ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libmudflap.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libmudflapth.a -%endif -%ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libmudflap.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libmudflapth.a -%endif -%ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflapth.a -%endif -%endif +%doc rpm.doc/changelogs/libgomp/ChangeLog* %if %{build_libquadmath} %files -n libquadmath -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libquadmath.so.0* %{_infodir}/libquadmath.info* -#%%doc rpm.doc/libquadmath/COPYING* +%{!?_licensedir:%global license %%doc} +%license rpm.doc/libquadmath/COPYING* %files -n libquadmath-devel -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/quadmath.h -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/quadmath_weak.h +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/quadmath.h +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/quadmath_weak.h %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libquadmath.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libquadmath.so %endif -#%doc rpm.doc/libquadmath/ChangeLog* +%doc rpm.doc/libquadmath/ChangeLog* %files -n libquadmath-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libquadmath.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libquadmath.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libquadmath.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libquadmath.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libquadmath.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libquadmath.a %endif %endif %if %{build_libitm} %files -n libitm -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libitm.so.1* %{_infodir}/libitm.info* %files -n libitm-devel -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/itm.h -#%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/itm_weak.h +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include +#%%{_prefix}/lib/gcc/%%{gcc_target_platform}/%%{gcc_major}/include/itm.h +#%%{_prefix}/lib/gcc/%%{gcc_target_platform}/%%{gcc_major}/include/itm_weak.h %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libitm.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.so %endif -#%doc rpm.doc/libitm/ChangeLog* +%doc rpm.doc/libitm/ChangeLog* %files -n libitm-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libitm.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libitm.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libitm.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libitm.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libitm.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.a %endif %endif %if %{build_libatomic} %files -n libatomic -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libatomic.so.1* %files -n libatomic-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libatomic.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libatomic.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libatomic.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libatomic.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libatomic.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libatomic.a %endif -#%doc rpm.doc/changelogs/libatomic/ChangeLog* +%doc rpm.doc/changelogs/libatomic/ChangeLog* %endif %if %{build_libasan} %files -n libasan -%defattr(-,root,root,-) -%{_prefix}/%{_lib}/libasan.so.4* +%{_prefix}/%{_lib}/libasan.so.5* %files -n libasan-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%ifarch sparcv9 ppc +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libasan.a +%endif +%ifarch sparc64 ppc64 ppc64p7 +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libasan.a +%endif +%ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan.a +%endif +%doc rpm.doc/changelogs/libsanitizer/ChangeLog* +%{!?_licensedir:%global license %%doc} +%license libsanitizer/LICENSE.TXT %endif + +%if %{build_libubsan} +%files -n libubsan +%{_prefix}/%{_lib}/libubsan.so.1* + +%files -n libubsan-static +%dir %{_prefix}/lib/gcc +%dir %{_prefix}/lib/gcc/%{gcc_target_platform} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libasan.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libubsan.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libasan.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libubsan.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libasan.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libubsan.a %endif -#%doc rpm.doc/changelogs/libsanitizer/ChangeLog* libsanitizer/LICENSE.TXT +%doc rpm.doc/changelogs/libsanitizer/ChangeLog* +%{!?_licensedir:%global license %%doc} +%license libsanitizer/LICENSE.TXT %endif %if %{build_libtsan} %files -n libtsan -%defattr(-,root,root,-) %{_prefix}/%{_lib}/libtsan.so.0* %files -n libtsan-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libtsan.a +%doc rpm.doc/changelogs/libsanitizer/ChangeLog* +%{!?_licensedir:%global license %%doc} +%license libsanitizer/LICENSE.TXT %endif -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libtsan.a -#%doc rpm.doc/changelogs/libsanitizer/ChangeLog* libsanitizer/LICENSE.TXT + +%if %{build_liblsan} +%files -n liblsan +%{_prefix}/%{_lib}/liblsan.so.0* + +%files -n liblsan-static +%dir %{_prefix}/lib/gcc +%dir %{_prefix}/lib/gcc/%{gcc_target_platform} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan.a +%doc rpm.doc/changelogs/libsanitizer/ChangeLog* +%{!?_licensedir:%global license %%doc} +%license libsanitizer/LICENSE.TXT %endif %if %{build_go} %files go -%defattr(-,root,root,-) +%ghost %{_prefix}/bin/go +%attr(755,root,root) %{_prefix}/bin/go.gcc %{_prefix}/bin/gccgo +%ghost %{_prefix}/bin/gofmt +%attr(755,root,root) %{_prefix}/bin/gofmt.gcc %{_mandir}/man1/gccgo.1* +%{_mandir}/man1/go.1* +%{_mandir}/man1/gofmt.1* %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/go1 +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/go1 +%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo +%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid +%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json +%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgo.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgo.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgobegin.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgo.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgo.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgobegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/64/libgolibbegin.a %endif %ifarch %{multilib_64_archs} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgo.so -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgo.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libgobegin.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgo.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgo.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgobegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgolibbegin.a %endif %ifarch sparcv9 ppc %{multilib_64_archs} -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgo.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgo.so %endif %ifarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgo.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgobegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgo.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgobegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgolibbegin.a %endif %doc rpm.doc/go/* %files -n libgo -%defattr(-,root,root,-) -%{_prefix}/%{_lib}/libgo.so.4* +%attr(755,root,root) %{_prefix}/%{_lib}/libgo.so.14* %doc rpm.doc/libgo/* %files -n libgo-devel -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %dir %{_prefix}/%{_lib}/go -%dir %{_prefix}/%{_lib}/go/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/%{_lib}/go/%{version} -%endif -%{_prefix}/%{_lib}/go/%{gcc_version}/%{gcc_target_platform} +%dir %{_prefix}/%{_lib}/go/%{gcc_major} +%{_prefix}/%{_lib}/go/%{gcc_major}/%{gcc_target_platform} %ifarch %{multilib_64_archs} %ifnarch sparc64 ppc64 ppc64p7 %dir %{_prefix}/lib/go -%dir %{_prefix}/lib/go/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/go/%{version} -%endif -%{_prefix}/lib/go/%{gcc_version}/%{gcc_target_platform} +%dir %{_prefix}/lib/go/%{gcc_major} +%{_prefix}/lib/go/%{gcc_major}/%{gcc_target_platform} %endif %endif %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libgobegin.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libgobegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libgolibbegin.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libgobegin.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libgobegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libgolibbegin.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgobegin.a -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgo.so +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgobegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgolibbegin.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgo.so %endif %files -n libgo-static -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} %ifarch sparcv9 ppc -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libgo.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib32/libgo.a %endif %ifarch sparc64 ppc64 ppc64p7 -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libgo.a +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64 +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/lib64/libgo.a %endif %ifnarch sparcv9 sparc64 ppc ppc64 ppc64p7 -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgo.a +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgo.a %endif %endif -%if 1 %files plugin-devel -%defattr(-,root,root,-) %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} -%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/plugin +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/gtype.state +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/include %dir %{_prefix}/libexec/gcc %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} -%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} -%if "%{version}" != "%{gcc_version}" -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{version} -%endif -%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/plugin -%endif - +%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} +%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/plugin +%files gdb-plugin +%{_prefix}/%{_lib}/libcc1.so* +%dir %{_prefix}/lib/gcc +%dir %{_prefix}/lib/gcc/%{gcc_target_platform} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} +%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/libcc1plugin.so* +%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/libcp1plugin.so* +%doc rpm.doc/changelogs/libcc1/ChangeLog* %changelog -* Fri Apr 3 2020 chenli - 7.3.0-20190804.h31 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:delete unneeded if condition - -* Tue Dec 31 2019 openEuler Buildteam - 7.3.0-20190804.h30 -- Type:NA -- ID:NA -- SUG:NA -- DESC:delete unneeded requires - -* Mon Dec 30 2019 openEuler Buildteam - 7.3.0-20190804.h29 -- Type:NA -- ID:NA -- SUG:NA -- DESC:delete unneeded requires - -* Mon Dec 23 2019 openEuler Buildteam - 7.3.0-20190804.h28 -- Type:NA -- ID:NA -- SUG:NA -- DESC:delete unneeded info in changelog - -* Tue Dec 4 2019 guoge - 7.3.0-20190804.h27 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: delete some patches - -* Tue Dec 4 2019 guoge - 7.3.0-20190804.h26 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: update patches - -* Fri Nov 29 2019 jiangchuangang - 7.3.0-20190804.h25 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:revise gcc_target_platform - -* Thu Nov 14 2019 jiangchuangang - 7.3.0-20190804.h24 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:rename patch - -* Mon Nov 5 2019 jiangchuangang - 7.3.0-20190804.h23 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: revise gcc_target_platform - -* Mon Nov 5 2019 jiangchuangang - 7.3.0-20190804.h22 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:support for x86 architecture - -* Thu Oct 24 2019 shenyangyang 7.3.0-20190804.h21 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:add build requires of zlib-devel - -* Wed Oct 23 2019 shenyangyang 7.3.0-20190804.h20 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:delete %{?dist} - -* Wed Sep 11 2019 gaoyi - 7.3.0-20190804.h19 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: export extra_ldflags_libobjc for libobjc - -* Tue Sep 10 2019 gaoyi - 7.3.0-20190804.h18 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: export FCFLAGS for fortran to add SP - -* Mon Sep 09 2019 gaoyi - 7.3.0-20190804.h17 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC: add CVE-2019-15847 - -* Sun Aug 04 2019 liufeng 7.3.0-20190804.h16 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: update gcc version - -* Tue Jun 5 2019 zoujing 7.3.0-20190601.h15 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: update gcc version - -* Fri May 31 2019 zoujing 7.3.0-20190515.h14 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: sync patch from compile - -* Tue May 21 2019 zoujing 7.3.0-20190515.h13 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: add libtsan - -* Fri May 17 2019 zoujing 7.3.0-20190515.h12 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: update gcc version - -* Mon May 13 2019 shenyining 7.3.0-20190316.h11 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:add sec compile option - -* Mon May 13 2019 yutianqi 7.3.0-20190316.h10 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:change gcc src to src and patch - -* Wed May 8 2019 luochunsheng 7.3.0-20190316.h9 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:remove sensitive information - -*Fri Apr 12 2019 liuxueping 7.3.0-20190316.h8 -- Type:NA -- ID:NA -- SUG:NA -- DESC: delete BuildRequires: -bep-env - -*Tue Mar 26 2019 zoujing 7.3.0-20190316.h7 -- Type:NA -- ID:NA -- SUG:NA -- DESC: update gcc-7.3.0 - -*Wed Mar 20 2019 zoujing 7.3.0-20190214.h6 -- Type:NA -- ID:NA -- SUG:NA -- DESC: revert add --disable-libstdcxx-dual-abi - -*Sat Mar 16 2019 zoujing 7.3.0-20190214.h5 -- Type:NA -- ID:NA -- SUG:NA -- DESC: revert add --disable-libstdcxx-dual-abi - -*Thu Mar 14 2019 zoujing 7.3.0-20190214.h4 -- Type:NA -- ID:NA -- SUG:NA -- DESC: add --disable-libstdcxx-dual-abi and some include files - -*Tue Mar 5 2019 zoujing 7.3.0-20190214.h3 -- Type:NA -- ID:NA -- SUG:NA -- DESC: add plugin-devel and optionial for compile - -* Mon Mar 1 2019 hexiaowen 7.3.0-20190214.h2 -- Type:NA -- ID:NA -- SUG:NA -- DESC: add plugin-devel and option - -* Tue Feb 26 2019 zoujing -1.h1 -- Type:NA -- ID:NA -- SUG:NA -- DESC: add libasan - -* Sun Feb 24 2019 zoujing -- Type:NA -- ID:NA -- SUG:NA -- DESC: remove -Werror=format-security - -* Thu Feb 21 2019 zoujing -- Type:NA -- ID:NA -- SUG:NA -- DESC:add libatomic and libitm packages on gcc 7.3.0 - -* Fri Feb 15 2019 zoujing -- Type:NA -- ID:NA -- SUG:NA -- DESC:update gcc-7.3.0 sourcecode - -* Fri Nov 11 2016 liupeifeng3@huawei.com -- gcc update 199192 -* Mon Aug 15 2016 wuhui3@huawei.com -- gcc update svn revision 197280 -* Fri Oct 23 2015 wuhui3@huawei.com -- add some -* Sat May 23 2015 john.wanghui@huawei.com -- create spec -* Sat May 23 2015 jiangjiji@huawei.com -- compile programs +* Tue Apr 28 2020 eastb233 - 9.3.0-20200312.h1 +- Type:modify +- Desc:modify patch name and gcc.spec + +* Sun Apr 26 2020 jdkboy - 9.3.0-20200312.h1 +- Type:init +- Desc:Init gcc 9.3.0 diff --git a/generate-csel.patch b/generate-csel.patch new file mode 100644 index 0000000000000000000000000000000000000000..35a00cee9436145654d6356c7f5c9fc8cf9f5432 --- /dev/null +++ b/generate-csel.patch @@ -0,0 +1,171 @@ +diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cselim-details" } */ ++ ++unsigned test(unsigned k, unsigned b) { ++ unsigned a[2]; ++ if (b < a[k]) { ++ a[k] = b; ++ } ++ return a[0]+a[1]; ++} ++ ++/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */ +diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cselim-details" } */ ++ ++int c; ++unsigned test(unsigned k, unsigned b) { ++ unsigned a[2]; ++ a[k] = c; ++ if (b < a[k]) { ++ a[k] = b; ++ } ++ return a[0]+a[1]; ++} ++ ++/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */ +diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cselim-details" } */ ++ ++unsigned a[2]; ++unsigned test(unsigned k, unsigned b) { ++ if (b < a[k]) { ++ a[k] = b; ++ } ++ return a[0]+a[1]; ++} ++ ++/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */ +diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cselim-details" } */ ++ ++int *p; ++unsigned test(unsigned k, unsigned b) { ++ unsigned a[2]; ++ p = a; ++ if (b < a[k]) { ++ a[k] = b; ++ } ++ return a[0]+a[1]; ++} ++ ++/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */ +diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c +@@ -0,0 +1,16 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cselim-details" } */ ++ ++int test(int b, int k) { ++ struct { ++ int data[2]; ++ } a; ++ ++ if (b < a.data[k]) { ++ a.data[k] = b; ++ } ++ ++ return a.data[0] + a.data[1]; ++} ++ ++/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */ +diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cselim-details" } */ ++ ++int test(int b, int k) { ++ typedef struct { ++ int x; ++ } SS; ++ struct { ++ SS data[2]; ++ } a; ++ ++ if (b < a.data[k].x) { ++ a.data[k].x = b; ++ } ++ ++ return a.data[0].x + a.data[1].x; ++} ++ ++/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */ +diff -uprN a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c +--- a/gcc/tree-ssa-phiopt.c ++++ b/gcc/tree-ssa-phiopt.c +@@ -2196,7 +2196,8 @@ get_non_trapping (void) + + We check that MIDDLE_BB contains only one store, that that store + doesn't trap (not via NOTRAP, but via checking if an access to the same +- memory location dominates us) and that the store has a "simple" RHS. */ ++ memory location dominates us, or the store is to a local addressable ++ object) and that the store has a "simple" RHS. */ + + static bool + cond_store_replacement (basic_block middle_bb, basic_block join_bb, +@@ -2218,8 +2219,9 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, + locus = gimple_location (assign); + lhs = gimple_assign_lhs (assign); + rhs = gimple_assign_rhs1 (assign); +- if (TREE_CODE (lhs) != MEM_REF +- || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME ++ if ((TREE_CODE (lhs) != MEM_REF ++ && TREE_CODE (lhs) != ARRAY_REF ++ && TREE_CODE (lhs) != COMPONENT_REF) + || !is_gimple_reg_type (TREE_TYPE (lhs))) + return false; + +@@ -2227,7 +2229,13 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, + TREE_THIS_NOTRAP here, but in that case we also could move stores, + whose value is not available readily, which we want to avoid. */ + if (!nontrap->contains (lhs)) +- return false; ++ { ++ /* If LHS is a local variable without address-taken, we could ++ always safely move down the store. */ ++ tree base = get_base_address (lhs); ++ if (!auto_var_p (base) || TREE_ADDRESSABLE (base)) ++ return false; ++ } + + /* Now we've checked the constraints, so do the transformation: + 1) Remove the single store. */ +@@ -2280,6 +2288,14 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, + else + gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT); + ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ { ++ fprintf (dump_file, "\nConditional store replacement happened!"); ++ fprintf (dump_file, "\nReplaced the store with a load."); ++ fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n"); ++ print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS); ++ } ++ + return true; + } diff --git a/isl-0.14.tar.xz b/isl-0.14.tar.xz deleted file mode 100644 index 823478eeabef35afb19b9ebea047dd34c09694cb..0000000000000000000000000000000000000000 Binary files a/isl-0.14.tar.xz and /dev/null differ diff --git a/ivopts-1.patch b/ivopts-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c5e62c543c872387bef81330d06fa0920edadbe --- /dev/null +++ b/ivopts-1.patch @@ -0,0 +1,178 @@ +diff -urpN a/gcc/testsuite/gfortran.dg/graphite/pr90240.f b/gcc/testsuite/gfortran.dg/graphite/pr90240.f +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/gfortran.dg/graphite/pr90240.f +@@ -0,0 +1,18 @@ ++! { dg-do compile } ++! { dg-options "-O1 -floop-nest-optimize" } ++ ++ PARAMETER (n=1335, N2=1335) ++ COMMON a(n,N2), b(n,N2), c(n,N2), ++ * d(n,N2), ++ 2 e(n,N2), f(n,N2), ++ * g(n,N2), h(n,N2) ++ DO 200 j=1,i ++ DO 300 k=1,l ++ a(k,j) = c(k,j)*g(k,j)*f(k+1,m)+f(k,m)+f(k,j) ++ 2 +f(k+1,j)*h(k+1,j) ++ b(k,j+1) = d(k,j+1)*g(k,m)+g(k,j+1) ++ 1 *e(k,m)+e(k,j+1)+e(k,j)+e(k+1,j) ++ 2 *h(k,j+1)-h(k,j) ++ 300 ENDDO ++ 200 ENDDO ++ END +diff -urpN a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c +--- a/gcc/tree-ssa-loop-ivopts.c ++++ b/gcc/tree-ssa-loop-ivopts.c +@@ -4557,22 +4557,25 @@ get_address_cost (struct ivopts_data *data, struct iv_use *use, + static comp_cost + get_scaled_computation_cost_at (ivopts_data *data, gimple *at, comp_cost cost) + { +- int loop_freq = data->current_loop->header->count.to_frequency (cfun); +- int bb_freq = gimple_bb (at)->count.to_frequency (cfun); +- if (loop_freq != 0) +- { +- gcc_assert (cost.scratch <= cost.cost); +- int scaled_cost +- = cost.scratch + (cost.cost - cost.scratch) * bb_freq / loop_freq; ++ if (data->speed ++ && data->current_loop->header->count.to_frequency (cfun) > 0) ++ { ++ basic_block bb = gimple_bb (at); ++ gcc_assert (cost.scratch <= cost.cost); ++ int scale_factor = (int)(intptr_t) bb->aux; ++ if (scale_factor == 1) ++ return cost; + +- if (dump_file && (dump_flags & TDF_DETAILS)) +- fprintf (dump_file, "Scaling cost based on bb prob " +- "by %2.2f: %d (scratch: %d) -> %d (%d/%d)\n", +- 1.0f * bb_freq / loop_freq, cost.cost, +- cost.scratch, scaled_cost, bb_freq, loop_freq); ++ int scaled_cost ++ = cost.scratch + (cost.cost - cost.scratch) * scale_factor; + +- cost.cost = scaled_cost; +- } ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, "Scaling cost based on bb prob " ++ "by %2.2f: %d (scratch: %d) -> %d\n", ++ 1.0f * scale_factor, cost.cost, cost.scratch, scaled_cost); ++ ++ cost.cost = scaled_cost; ++ } + + return cost; + } +@@ -6678,9 +6681,8 @@ try_improve_iv_set (struct ivopts_data *data, + } + + iv_ca_delta_commit (data, ivs, best_delta, true); +- gcc_assert (best_cost == iv_ca_cost (ivs)); + iv_ca_delta_free (&best_delta); +- return true; ++ return best_cost == iv_ca_cost (ivs); + } + + /* Attempts to find the optimal set of induction variables. We do simple +@@ -6717,6 +6719,14 @@ find_optimal_iv_set_1 (struct ivopts_data *data, bool originalp) + } + } + ++ /* If the set has infinite_cost, it can't be optimal. */ ++ if (iv_ca_cost (set).infinite_cost_p ()) ++ { ++ if (dump_file && (dump_flags & TDF_DETAILS)) ++ fprintf (dump_file, ++ "Overflow to infinite cost in try_improve_iv_set.\n"); ++ iv_ca_free (&set); ++ } + return set; + } + +@@ -7522,6 +7532,49 @@ loop_body_includes_call (basic_block *body, unsigned num_nodes) + return false; + } + ++/* Determine cost scaling factor for basic blocks in loop. */ ++#define COST_SCALING_FACTOR_BOUND (20) ++ ++static void ++determine_scaling_factor (struct ivopts_data *data, basic_block *body) ++{ ++ int lfreq = data->current_loop->header->count.to_frequency (cfun); ++ if (!data->speed || lfreq <= 0) ++ return; ++ ++ int max_freq = lfreq; ++ for (unsigned i = 0; i < data->current_loop->num_nodes; i++) ++ { ++ body[i]->aux = (void *)(intptr_t) 1; ++ if (max_freq < body[i]->count.to_frequency (cfun)) ++ max_freq = body[i]->count.to_frequency (cfun); ++ } ++ if (max_freq > lfreq) ++ { ++ int divisor, factor; ++ /* Check if scaling factor itself needs to be scaled by the bound. This ++ is to avoid overflow when scaling cost according to profile info. */ ++ if (max_freq / lfreq > COST_SCALING_FACTOR_BOUND) ++ { ++ divisor = max_freq; ++ factor = COST_SCALING_FACTOR_BOUND; ++ } ++ else ++ { ++ divisor = lfreq; ++ factor = 1; ++ } ++ for (unsigned i = 0; i < data->current_loop->num_nodes; i++) ++ { ++ int bfreq = body[i]->count.to_frequency (cfun); ++ if (bfreq <= lfreq) ++ continue; ++ ++ body[i]->aux = (void*)(intptr_t) (factor * bfreq / divisor); ++ } ++ } ++} ++ + /* Optimizes the LOOP. Returns true if anything changed. */ + + static bool +@@ -7560,7 +7613,6 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop, + body = get_loop_body (loop); + data->body_includes_call = loop_body_includes_call (body, loop->num_nodes); + renumber_gimple_stmt_uids_in_blocks (body, loop->num_nodes); +- free (body); + + data->loop_single_exit_p = exit != NULL && loop_only_exit_p (loop, exit); + +@@ -7574,6 +7626,9 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop, + if (data->vgroups.length () > MAX_CONSIDERED_GROUPS) + goto finish; + ++ /* Determine cost scaling factor for basic blocks in loop. */ ++ determine_scaling_factor (data, body); ++ + /* Finds candidates for the induction variables (item 2). */ + find_iv_candidates (data); + +@@ -7584,6 +7639,9 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop, + + /* Find the optimal set of induction variables (item 3, part 2). */ + iv_ca = find_optimal_iv_set (data); ++ /* Cleanup basic block aux field. */ ++ for (unsigned i = 0; i < data->current_loop->num_nodes; i++) ++ body[i]->aux = NULL; + if (!iv_ca) + goto finish; + changed = true; +@@ -7599,6 +7657,7 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop, + remove_unused_ivs (data, toremove); + + finish: ++ free (body); + free_loop_data (data); + + return changed; diff --git a/ivopts-2.patch b/ivopts-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..c9cbec141f157fe14bd6e2a9e5e5d1477f2e08c7 --- /dev/null +++ b/ivopts-2.patch @@ -0,0 +1,407 @@ +diff -urpN a/gcc/testsuite/g++.dg/tree-ssa/pr90078.C b/gcc/testsuite/g++.dg/tree-ssa/pr90078.C +new file mode 100644 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/tree-ssa/pr90078.C +@@ -0,0 +1,199 @@ ++// { dg-do compile } ++// { dg-options "-std=c++14 -O2 -ftemplate-depth=1000000" } ++ ++template struct Tensor3; ++template ++struct Tensor3_Expr; ++ ++template struct Tensor4; ++template ++struct Tensor4_Expr; ++ ++template struct Index ++{}; ++template struct Number ++{ ++ Number(){}; ++ operator int() const { return N; } ++}; ++ ++template ++struct Tensor3 ++{ ++ T data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2]; ++ ++ T operator()(const int N1, const int N2, const int N3) const ++ { ++ return data[N1][N2][N3]; ++ } ++ ++ template ++ Tensor3_Expr, T, ++ Dim0, Dim1, Dim2, i, j, k> ++ operator()(const Index, const Index, ++ const Index) const ++ { ++ return Tensor3_Expr, ++ T, Dim0, Dim1, Dim2, i, j, k>(*this); ++ } ++}; ++ ++template ++struct Tensor3_Expr ++{ ++ A iter; ++ ++ Tensor3_Expr(const A &a) : iter(a) {} ++ T operator()(const int N1, const int N2, const int N3) const ++ { ++ return iter(N1, N2, N3); ++ } ++}; ++ ++template ++struct Tensor3_Expr, T, Dim0, ++ Dim1, Dim2, i, j, k> ++{ ++ Tensor3 &iter; ++ ++ Tensor3_Expr(Tensor3 &a) : iter(a) ++ {} ++ T operator()(const int N1, const int N2, const int N3) const ++ { ++ return iter(N1, N2, N3); ++ } ++}; ++ ++template ++struct Tensor3_times_Tensor3_21 ++{ ++ Tensor3_Expr iterA; ++ Tensor3_Expr iterB; ++ ++ template ++ T eval(const int N1, const int N2, const int N3, const int N4, ++ const Number &) const ++ { ++ return iterA(N1, N2, CurrentDim - 1) * iterB(CurrentDim - 1, N3, N4) ++ + eval(N1, N2, N3, N4, Number()); ++ } ++ T eval(const int N1, const int N2, const int N3, const int N4, ++ const Number<1> &) const ++ { ++ return iterA(N1, N2, 0) * iterB(0, N3, N4); ++ } ++ ++ Tensor3_times_Tensor3_21( ++ const Tensor3_Expr &a, ++ const Tensor3_Expr &b) ++ : iterA(a), iterB(b) ++ {} ++ T operator()(const int &N1, const int &N2, const int &N3, ++ const int &N4) const ++ { ++ return eval(N1, N2, N3, N4, Number()); ++ } ++}; ++ ++template ++Tensor4_Expr, ++ T, Dim0, Dim1, Dim4, Dim5, i, j, l, m> ++operator*(const Tensor3_Expr &a, ++ const Tensor3_Expr &b) ++{ ++ using TensorExpr = Tensor3_times_Tensor3_21; ++ return Tensor4_Expr( ++ TensorExpr(a, b)); ++}; ++ ++template ++struct Tensor4 ++{ ++ T data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2][Tensor_Dim3]; ++ ++ Tensor4() {} ++ T &operator()(const int N1, const int N2, const int N3, const int N4) ++ { ++ return data[N1][N2][N3][N4]; ++ } ++ ++ template ++ Tensor4_Expr, ++ T, Dim0, Dim1, Dim2, Dim3, i, j, k, l> ++ operator()(const Index, const Index, const Index, ++ const Index) ++ { ++ return Tensor4_Expr< ++ Tensor4, T, Dim0, ++ Dim1, Dim2, Dim3, i, j, k, l>(*this); ++ }; ++}; ++ ++template ++struct Tensor4_Expr ++{ ++ A iter; ++ ++ Tensor4_Expr(const A &a) : iter(a) {} ++ T operator()(const int N1, const int N2, const int N3, const int N4) const ++ { ++ return iter(N1, N2, N3, N4); ++ } ++}; ++ ++template ++struct Tensor4_Expr, T, Dim0, Dim1, Dim2, ++ Dim3, i, j, k, l> ++{ ++ Tensor4 &iter; ++ ++ Tensor4_Expr(Tensor4 &a) : iter(a) {} ++ T operator()(const int N1, const int N2, const int N3, const int N4) const ++ { ++ return iter(N1, N2, N3, N4); ++ } ++ ++ template ++ auto &operator=(const Tensor4_Expr &rhs) ++ { ++ for(int ii = 0; ii < Dim0; ++ii) ++ for(int jj = 0; jj < Dim1; ++jj) ++ for(int kk = 0; kk < Dim2; ++kk) ++ for(int ll = 0; ll < Dim3; ++ll) ++ { ++ iter(ii, jj, kk, ll) = rhs(ii, jj, kk, ll); ++ } ++ return *this; ++ } ++}; ++ ++int main() ++{ ++ Tensor3 t1; ++ Tensor3 t2; ++ ++ Index<'l', 100> l; ++ Index<'m', 100> m; ++ Index<'k', 1000> k; ++ Index<'n', 100> n; ++ Index<'o', 100> o; ++ ++ Tensor4 res; ++ res(l, m, n, o) = t1(l, m, k) * t2(k, n, o); ++ return 0; ++} ++ +diff -urpN a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c +--- a/gcc/tree-ssa-loop-ivopts.c ++++ b/gcc/tree-ssa-loop-ivopts.c +@@ -114,7 +114,7 @@ along with GCC; see the file COPYING3. If not see + interface between the GIMPLE and RTL worlds. */ + + /* The infinite cost. */ +-#define INFTY 10000000 ++#define INFTY 1000000000 + + /* Returns the expected number of loop iterations for LOOP. + The average trip count is computed from profile data if it +@@ -180,7 +180,7 @@ struct comp_cost + comp_cost (): cost (0), complexity (0), scratch (0) + {} + +- comp_cost (int cost, unsigned complexity, int scratch = 0) ++ comp_cost (int64_t cost, unsigned complexity, int64_t scratch = 0) + : cost (cost), complexity (complexity), scratch (scratch) + {} + +@@ -220,16 +220,16 @@ struct comp_cost + /* Returns true if COST1 is smaller or equal than COST2. */ + friend bool operator<= (comp_cost cost1, comp_cost cost2); + +- int cost; /* The runtime cost. */ ++ int64_t cost; /* The runtime cost. */ + unsigned complexity; /* The estimate of the complexity of the code for + the computation (in no concrete units -- + complexity field should be larger for more + complex expressions and addressing modes). */ +- int scratch; /* Scratch used during cost computation. */ ++ int64_t scratch; /* Scratch used during cost computation. */ + }; + + static const comp_cost no_cost; +-static const comp_cost infinite_cost (INFTY, INFTY, INFTY); ++static const comp_cost infinite_cost (INFTY, 0, INFTY); + + bool + comp_cost::infinite_cost_p () +@@ -243,6 +243,7 @@ operator+ (comp_cost cost1, comp_cost cost2) + if (cost1.infinite_cost_p () || cost2.infinite_cost_p ()) + return infinite_cost; + ++ gcc_assert (cost1.cost + cost2.cost < infinite_cost.cost); + cost1.cost += cost2.cost; + cost1.complexity += cost2.complexity; + +@@ -256,6 +257,7 @@ operator- (comp_cost cost1, comp_cost cost2) + return infinite_cost; + + gcc_assert (!cost2.infinite_cost_p ()); ++ gcc_assert (cost1.cost - cost2.cost < infinite_cost.cost); + + cost1.cost -= cost2.cost; + cost1.complexity -= cost2.complexity; +@@ -276,6 +278,7 @@ comp_cost::operator+= (HOST_WIDE_INT c) + if (infinite_cost_p ()) + return *this; + ++ gcc_assert (this->cost + c < infinite_cost.cost); + this->cost += c; + + return *this; +@@ -287,6 +290,7 @@ comp_cost::operator-= (HOST_WIDE_INT c) + if (infinite_cost_p ()) + return *this; + ++ gcc_assert (this->cost - c < infinite_cost.cost); + this->cost -= c; + + return *this; +@@ -295,6 +299,7 @@ comp_cost::operator-= (HOST_WIDE_INT c) + comp_cost + comp_cost::operator/= (HOST_WIDE_INT c) + { ++ gcc_assert (c != 0); + if (infinite_cost_p ()) + return *this; + +@@ -309,6 +314,7 @@ comp_cost::operator*= (HOST_WIDE_INT c) + if (infinite_cost_p ()) + return *this; + ++ gcc_assert (this->cost * c < infinite_cost.cost); + this->cost *= c; + + return *this; +@@ -638,7 +644,7 @@ struct iv_ca + comp_cost cand_use_cost; + + /* Total cost of candidates. */ +- unsigned cand_cost; ++ int64_t cand_cost; + + /* Number of times each invariant variable is used. */ + unsigned *n_inv_var_uses; +@@ -4025,16 +4031,16 @@ get_computation_at (struct loop *loop, gimple *at, + if we're optimizing for speed, amortize it over the per-iteration cost. + If ROUND_UP_P is true, the result is round up rather than to zero when + optimizing for speed. */ +-static unsigned +-adjust_setup_cost (struct ivopts_data *data, unsigned cost, ++static int64_t ++adjust_setup_cost (struct ivopts_data *data, int64_t cost, + bool round_up_p = false) + { + if (cost == INFTY) + return cost; + else if (optimize_loop_for_speed_p (data->current_loop)) + { +- HOST_WIDE_INT niters = avg_loop_niter (data->current_loop); +- return ((HOST_WIDE_INT) cost + (round_up_p ? niters - 1 : 0)) / niters; ++ int64_t niters = (int64_t) avg_loop_niter (data->current_loop); ++ return (cost + (round_up_p ? niters - 1 : 0)) / niters; + } + else + return cost; +@@ -4305,7 +4311,7 @@ enum ainc_type + + struct ainc_cost_data + { +- unsigned costs[AINC_NONE]; ++ int64_t costs[AINC_NONE]; + }; + + static comp_cost +@@ -4566,12 +4572,12 @@ get_scaled_computation_cost_at (ivopts_data *data, gimple *at, comp_cost cost) + if (scale_factor == 1) + return cost; + +- int scaled_cost ++ int64_t scaled_cost + = cost.scratch + (cost.cost - cost.scratch) * scale_factor; + + if (dump_file && (dump_flags & TDF_DETAILS)) +- fprintf (dump_file, "Scaling cost based on bb prob " +- "by %2.2f: %d (scratch: %d) -> %d\n", ++ fprintf (dump_file, "Scaling cost based on bb prob by %2.2f: " ++ "%" PRId64 " (scratch: %" PRId64 ") -> %" PRId64 "\n", + 1.0f * scale_factor, cost.cost, cost.scratch, scaled_cost); + + cost.cost = scaled_cost; +@@ -5539,7 +5545,7 @@ determine_group_iv_costs (struct ivopts_data *data) + || group->cost_map[j].cost.infinite_cost_p ()) + continue; + +- fprintf (dump_file, " %d\t%d\t%d\t", ++ fprintf (dump_file, " %d\t%" PRId64 "\t%d\t", + group->cost_map[j].cand->id, + group->cost_map[j].cost.cost, + group->cost_map[j].cost.complexity); +@@ -5569,7 +5575,7 @@ static void + determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand) + { + comp_cost cost_base; +- unsigned cost, cost_step; ++ int64_t cost, cost_step; + tree base; + + gcc_assert (cand->iv != NULL); +@@ -6139,11 +6145,11 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs) + unsigned i; + comp_cost cost = iv_ca_cost (ivs); + +- fprintf (file, " cost: %d (complexity %d)\n", cost.cost, ++ fprintf (file, " cost: %" PRId64 " (complexity %d)\n", cost.cost, + cost.complexity); +- fprintf (file, " cand_cost: %d\n cand_group_cost: %d (complexity %d)\n", +- ivs->cand_cost, ivs->cand_use_cost.cost, +- ivs->cand_use_cost.complexity); ++ fprintf (file, " cand_cost: %" PRId64 "\n cand_group_cost: " ++ "%" PRId64 " (complexity %d)\n", ivs->cand_cost, ++ ivs->cand_use_cost.cost, ivs->cand_use_cost.complexity); + bitmap_print (file, ivs->cands, " candidates: ","\n"); + + for (i = 0; i < ivs->upto; i++) +@@ -6151,9 +6157,9 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs) + struct iv_group *group = data->vgroups[i]; + struct cost_pair *cp = iv_ca_cand_for_group (ivs, group); + if (cp) +- fprintf (file, " group:%d --> iv_cand:%d, cost=(%d,%d)\n", +- group->id, cp->cand->id, cp->cost.cost, +- cp->cost.complexity); ++ fprintf (file, " group:%d --> iv_cand:%d, cost=(" ++ "%" PRId64 ",%d)\n", group->id, cp->cand->id, ++ cp->cost.cost, cp->cost.complexity); + else + fprintf (file, " group:%d --> ??\n", group->id); + } +@@ -6751,9 +6757,9 @@ find_optimal_iv_set (struct ivopts_data *data) + + if (dump_file && (dump_flags & TDF_DETAILS)) + { +- fprintf (dump_file, "Original cost %d (complexity %d)\n\n", ++ fprintf (dump_file, "Original cost %" PRId64 " (complexity %d)\n\n", + origcost.cost, origcost.complexity); +- fprintf (dump_file, "Final cost %d (complexity %d)\n\n", ++ fprintf (dump_file, "Final cost %" PRId64 " (complexity %d)\n\n", + cost.cost, cost.complexity); + } + diff --git a/loop-finite-bugfix.patch b/loop-finite-bugfix.patch new file mode 100644 index 0000000000000000000000000000000000000000..c159a8b1c300e3b8c94e677e8c7a93d40f7274d4 --- /dev/null +++ b/loop-finite-bugfix.patch @@ -0,0 +1,160 @@ +diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c +index 6b6c754ad86..58ba0948e79 100644 +--- a/gcc/c-family/c-opts.c ++++ b/gcc/c-family/c-opts.c +@@ -989,6 +989,10 @@ c_common_post_options (const char **pfilename) + if (!global_options_set.x_flag_new_ttp) + flag_new_ttp = (cxx_dialect >= cxx17); + ++ /* C++11 guarantees forward progress. */ ++ if (!global_options_set.x_flag_finite_loops) ++ flag_finite_loops = (optimize >= 2 && cxx_dialect >= cxx11); ++ + if (cxx_dialect >= cxx11) + { + /* If we're allowing C++0x constructs, don't warn about C++98 +diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h +index 1c49a8b8c2d..18b404e292f 100644 +--- a/gcc/cfgloop.h ++++ b/gcc/cfgloop.h +@@ -226,6 +226,10 @@ public: + /* True if the loop is part of an oacc kernels region. */ + unsigned in_oacc_kernels_region : 1; + ++ /* True if the loop is known to be finite. This is a localized ++ flag_finite_loops or similar pragmas state. */ ++ unsigned finite_p : 1; ++ + /* The number of times to unroll the loop. 0 means no information given, + just do what we always do. A value of 1 means do not unroll the loop. + A value of USHRT_MAX means unroll with no specific unrolling factor. +diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c +index c9375565f62..50c7267ec49 100644 +--- a/gcc/cfgloopmanip.c ++++ b/gcc/cfgloopmanip.c +@@ -1023,6 +1023,7 @@ copy_loop_info (class loop *loop, class loop *target) + target->dont_vectorize = loop->dont_vectorize; + target->force_vectorize = loop->force_vectorize; + target->in_oacc_kernels_region = loop->in_oacc_kernels_region; ++ target->finite_p = loop->finite_p; + target->unroll = loop->unroll; + target->owned_clique = loop->owned_clique; + } +diff --git a/gcc/common.opt b/gcc/common.opt +index 4368910cb54..bb2ea4c905d 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -1490,7 +1490,7 @@ Common Report Var(flag_finite_math_only) Optimization SetByCombined + Assume no NaNs or infinities are generated. + + ffinite-loops +-Common Report Var(flag_finite_loops) Optimization ++Common Report Var(flag_finite_loops) Optimization Init(0) + Assume that loops with an exit will terminate and not loop indefinitely. + + ffixed- +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index e9e1683e9a8..e3e652ff6c1 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -10432,7 +10432,8 @@ Assume that a loop with an exit will eventually take the exit and not loop + indefinitely. This allows the compiler to remove loops that otherwise have + no side-effects, not considering eventual endless looping as such. + +-This option is enabled by default at @option{-O2}. ++This option is enabled by default at @option{-O2} for C++ with -std=c++11 ++or higher. + + @item -ftree-dominator-opts + @opindex ftree-dominator-opts +diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c +index 9566e5ee102..244f5b8aa5c 100644 +--- a/gcc/lto-streamer-in.c ++++ b/gcc/lto-streamer-in.c +@@ -821,6 +821,7 @@ input_cfg (class lto_input_block *ib, class data_in *data_in, + loop->owned_clique = streamer_read_hwi (ib); + loop->dont_vectorize = streamer_read_hwi (ib); + loop->force_vectorize = streamer_read_hwi (ib); ++ loop->finite_p = streamer_read_hwi (ib); + loop->simduid = stream_read_tree (ib, data_in); + + place_new_loop (fn, loop); +diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c +index a219c1d0dd1..52ef94718db 100644 +--- a/gcc/lto-streamer-out.c ++++ b/gcc/lto-streamer-out.c +@@ -1950,6 +1950,7 @@ output_cfg (struct output_block *ob, struct function *fn) + streamer_write_hwi (ob, loop->owned_clique); + streamer_write_hwi (ob, loop->dont_vectorize); + streamer_write_hwi (ob, loop->force_vectorize); ++ streamer_write_hwi (ob, loop->finite_p); + stream_write_tree (ob, loop->simduid, true); + } + +diff --git a/gcc/opts.c b/gcc/opts.c +index 5dc7d65dedd..d4df8627bf7 100644 +--- a/gcc/opts.c ++++ b/gcc/opts.c +@@ -478,7 +478,6 @@ static const struct default_options default_options_table[] = + { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 }, +- { OPT_LEVELS_2_PLUS, OPT_ffinite_loops, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 }, +diff --git a/gcc/testsuite/gcc.dg/torture/pr94392.c b/gcc/testsuite/gcc.dg/torture/pr94392.c +new file mode 100644 +index 00000000000..373f18ce983 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/torture/pr94392.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-skip-if "finite loops" { *-*-* } { "-ffinite-loops" } } */ ++/* { dg-skip-if "LTO optimizes the test" { *-*-* } { "-flto" } } */ ++/* { dg-additional-options "-fdump-tree-optimized" } */ ++ ++int a, b; ++ ++int ++main() ++{ ++ while (1) ++ { ++ /* Try really hard. */ ++ if (a != b) ++ return 1; ++ } ++ return 0; ++} ++ ++/* ISO C does not guarantee forward progress like C++ does so we ++ cannot assume the loop is finite and optimize it to return 1. */ ++/* { dg-final { scan-tree-dump "if" "optimized" } } */ +diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c +index f7b817d94e6..e99fb9ff5d1 100644 +--- a/gcc/tree-cfg.c ++++ b/gcc/tree-cfg.c +@@ -324,6 +324,9 @@ replace_loop_annotate (void) + /* Then look into the latch, if any. */ + if (loop->latch) + replace_loop_annotate_in_block (loop->latch, loop); ++ ++ /* Push the global flag_finite_loops state down to individual loops. */ ++ loop->finite_p = flag_finite_loops; + } + + /* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */ +diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c +index 6e6df0bfdb8..7d61ef080eb 100644 +--- a/gcc/tree-ssa-loop-niter.c ++++ b/gcc/tree-ssa-loop-niter.c +@@ -2834,7 +2834,7 @@ finite_loop_p (class loop *loop) + return true; + } + +- if (flag_finite_loops) ++ if (loop->finite_p) + { + unsigned i; + vec exits = get_loop_exit_edges (loop); diff --git a/loop-finite.patch b/loop-finite.patch new file mode 100644 index 0000000000000000000000000000000000000000..945ea2849ba302482354a7b2df469a16c7d98700 --- /dev/null +++ b/loop-finite.patch @@ -0,0 +1,367 @@ +diff --git a/gcc/common.opt b/gcc/common.opt +index e1404165feb..a1544d06824 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -1437,6 +1437,10 @@ ffinite-math-only + Common Report Var(flag_finite_math_only) Optimization SetByCombined + Assume no NaNs or infinities are generated. + ++ffinite-loops ++Common Report Var(flag_finite_loops) Optimization ++Assume that loops with an exit will terminate and not loop indefinitely. ++ + ffixed- + Common Joined RejectNegative Var(common_deferred_options) Defer + -ffixed- Mark as being unavailable to the compiler. +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 090d606b3ba..bf9da0f0a6e 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -413,6 +413,7 @@ Objective-C and Objective-C++ Dialects}. + -fdevirtualize-at-ltrans -fdse @gol + -fearly-inlining -fipa-sra -fexpensive-optimizations -ffat-lto-objects @gol + -ffast-math -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol ++-ffinite-loops @gol + -fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol + -fgcse -fgcse-after-reload -fgcse-las -fgcse-lm -fgraphite-identity @gol + -fgcse-sm -fhoist-adjacent-loads -fif-conversion @gol +@@ -8303,6 +8304,7 @@ also turns on the following optimization flags: + -fdelete-null-pointer-checks @gol + -fdevirtualize -fdevirtualize-speculatively @gol + -fexpensive-optimizations @gol ++-ffinite-loops @gol + -fgcse -fgcse-lm @gol + -fhoist-adjacent-loads @gol + -finline-small-functions @gol +@@ -9524,6 +9526,15 @@ that may set @code{errno} but are otherwise free of side effects. This flag is + enabled by default at @option{-O2} and higher if @option{-Os} is not also + specified. + ++@item -ffinite-loops ++@opindex ffinite-loops ++@opindex fno-finite-loops ++Assume that a loop with an exit will eventually take the exit and not loop ++indefinitely. This allows the compiler to remove loops that otherwise have ++no side-effects, not considering eventual endless looping as such. ++ ++This option is enabled by default at @option{-O2}. ++ + @item -ftree-dominator-opts + @opindex ftree-dominator-opts + Perform a variety of simple scalar cleanups (constant/copy +diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c +index 97ae47b3135..c8a281c6d28 100644 +--- a/gcc/omp-offload.c ++++ b/gcc/omp-offload.c +@@ -300,7 +300,7 @@ oacc_xform_loop (gcall *call) + tree chunk_size = NULL_TREE; + unsigned mask = (unsigned) TREE_INT_CST_LOW (gimple_call_arg (call, 5)); + tree lhs = gimple_call_lhs (call); +- tree type = TREE_TYPE (lhs); ++ tree type = NULL_TREE; + tree diff_type = TREE_TYPE (range); + tree r = NULL_TREE; + gimple_seq seq = NULL; +@@ -308,6 +308,15 @@ oacc_xform_loop (gcall *call) + unsigned outer_mask = mask & (~mask + 1); // Outermost partitioning + unsigned inner_mask = mask & ~outer_mask; // Inner partitioning (if any) + ++ /* Skip lowering if return value of IFN_GOACC_LOOP call is not used. */ ++ if (!lhs) ++ { ++ gsi_replace_with_seq (&gsi, seq, true); ++ return; ++ } ++ ++ type = TREE_TYPE (lhs); ++ + #ifdef ACCEL_COMPILER + chunk_size = gimple_call_arg (call, 4); + if (integer_minus_onep (chunk_size) /* Force static allocation. */ +diff --git a/gcc/opts.c b/gcc/opts.c +index 64f94ac8ffd..b38bfb15a56 100644 +--- a/gcc/opts.c ++++ b/gcc/opts.c +@@ -494,6 +494,7 @@ static const struct default_options default_options_table[] = + { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 }, ++ { OPT_LEVELS_2_PLUS, OPT_ffinite_loops, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 }, +diff --git a/gcc/testsuite/g++.dg/tree-ssa/empty-loop.C b/gcc/testsuite/g++.dg/tree-ssa/empty-loop.C +new file mode 100644 +index 00000000000..6b1e879e6a9 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/tree-ssa/empty-loop.C +@@ -0,0 +1,33 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cddce2 -ffinite-loops" } */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++using namespace std; ++ ++int foo (vector &v, list &l, set &s, map &m) ++{ ++ for (vector::iterator it = v.begin (); it != v.end (); ++it) ++ it->length(); ++ ++ for (list::iterator it = l.begin (); it != l.end (); ++it) ++ it->length(); ++ ++ for (map::iterator it = m.begin (); it != m.end (); ++it) ++ it->first + it->second.length(); ++ ++ for (set::iterator it0 = s.begin (); it0 != s.end(); ++it0) ++ for (vector::reverse_iterator it1 = v.rbegin(); it1 != v.rend(); ++it1) ++ { ++ it0->length(); ++ it1->length(); ++ } ++ ++ return 0; ++} ++/* { dg-final { scan-tree-dump-not "if" "cddce2"} } */ ++ +diff --git a/gcc/testsuite/gcc.dg/const-1.c b/gcc/testsuite/gcc.dg/const-1.c +index a5b2b167728..2e95bd8e2ea 100644 +--- a/gcc/testsuite/gcc.dg/const-1.c ++++ b/gcc/testsuite/gcc.dg/const-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile { target nonpic } } */ +-/* { dg-options "-O2 -Wsuggest-attribute=const" } */ ++/* { dg-options "-O2 -Wsuggest-attribute=const -fno-finite-loops" } */ + + extern int extern_const(int a) __attribute__ ((const)); + +diff --git a/gcc/testsuite/gcc.dg/graphite/graphite.exp b/gcc/testsuite/gcc.dg/graphite/graphite.exp +index ea6144607e2..523a955e82d 100644 +--- a/gcc/testsuite/gcc.dg/graphite/graphite.exp ++++ b/gcc/testsuite/gcc.dg/graphite/graphite.exp +@@ -56,7 +56,7 @@ set vect_files [lsort [glob -nocomplain $srcdir/$subdir/vect-*.c ] ] + + # Tests to be compiled. + set dg-do-what-default compile +-dg-runtest $scop_files "" "-O2 -fgraphite -fdump-tree-graphite-all" ++dg-runtest $scop_files "" "-O2 -fgraphite -fdump-tree-graphite-all -fno-finite-loops" + dg-runtest $id_files "" "-O2 -fgraphite-identity -ffast-math -fdump-tree-graphite-details" + + # Tests to be run. +diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-1.c b/gcc/testsuite/gcc.dg/loop-unswitch-1.c +index f6fc41d6bcc..de2fb2c0e4b 100644 +--- a/gcc/testsuite/gcc.dg/loop-unswitch-1.c ++++ b/gcc/testsuite/gcc.dg/loop-unswitch-1.c +@@ -1,6 +1,6 @@ + /* For PR rtl-optimization/27735 */ + /* { dg-do compile } */ +-/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-details" } */ ++/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-details -fno-finite-loops" } */ + + void set_color(void); + void xml_colorize_line(unsigned int *p, int state) +diff --git a/gcc/testsuite/gcc.dg/predict-9.c b/gcc/testsuite/gcc.dg/predict-9.c +index 7e5ba085ece..f491c511bd9 100644 +--- a/gcc/testsuite/gcc.dg/predict-9.c ++++ b/gcc/testsuite/gcc.dg/predict-9.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-profile_estimate" } */ ++/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-profile_estimate -fno-finite-loops" } */ + + extern int global; + extern int global2; +diff --git a/gcc/testsuite/gcc.dg/pure-2.c b/gcc/testsuite/gcc.dg/pure-2.c +index fe6e2bce695..318cfd18630 100644 +--- a/gcc/testsuite/gcc.dg/pure-2.c ++++ b/gcc/testsuite/gcc.dg/pure-2.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -Wsuggest-attribute=pure" } */ ++/* { dg-options "-O2 -Wsuggest-attribute=pure -fno-finite-loops" } */ + /* { dg-add-options bind_pic_locally } */ + + extern int extern_const(int a) __attribute__ ((pure)); +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c +index d289e5d0f55..a9bdf26931a 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fdump-tree-cddce2" } */ ++/* { dg-options "-O2 -fdump-tree-cddce2 -fno-finite-loops" } */ + + struct rtx_def; + typedef struct rtx_def *rtx; +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dce-2.c b/gcc/testsuite/gcc.dg/tree-ssa/dce-2.c +new file mode 100644 +index 00000000000..18c1ddb819e +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/dce-2.c +@@ -0,0 +1,37 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cddce1 -ffinite-loops" } */ ++ ++typedef struct list { ++ char pad[15]; ++ struct list *next; ++} list; ++ ++int data; ++ ++list *head, *tail; ++ ++int __attribute__((pure)) pfn (int); ++ ++int foo (unsigned u, int s) ++{ ++ unsigned i; ++ list *p; ++ int j; ++ ++ for (i = 0; i < u; i += 2) ++ ; ++ ++ for (p = head; p; p = p->next) ++ ; ++ ++ for (j = data; j & s; j = pfn (j + 3)) ++ ; ++ ++ for (p = head; p != tail; p = p->next) ++ for (j = data + 1; j > s; j = pfn (j + 2)) ++ ; ++ ++ return 0; ++} ++/* { dg-final { scan-tree-dump-not "if" "cddce1"} } */ ++ +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-10.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-10.c +index a29c9fb2501..3d05ad2d073 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-10.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-10.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fdump-tree-optimized" } */ ++/* { dg-options "-O2 -fdump-tree-optimized -fno-finite-loops" } */ + /* { dg-require-effective-target int32plus } */ + + int bar (void); +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c b/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c +index e9b4f2628d5..187c08407d5 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -w" } */ ++/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -w -fno-finite-loops" } */ + + struct __sFILE + { +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c +index d829b04d177..67526762f2c 100644 +--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c ++++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -fdump-tree-thread2-details -fdump-tree-thread3-details -fdump-tree-thread4-details" } */ ++/* { dg-options "-O2 -fdump-tree-thread2-details -fdump-tree-thread3-details -fdump-tree-thread4-details -fno-finite-loops" } */ + /* { dg-final { scan-tree-dump "FSM" "thread2" } } */ + /* { dg-final { scan-tree-dump "FSM" "thread3" } } */ + /* { dg-final { scan-tree-dump "FSM" "thread4" { xfail *-*-* } } } */ +diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c +index 2478219d873..a38899edd6c 100644 +--- a/gcc/tree-ssa-dce.c ++++ b/gcc/tree-ssa-dce.c +@@ -245,6 +245,17 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive) + mark_stmt_necessary (stmt, true); + return; + } ++ /* IFN_GOACC_LOOP calls are necessary in that they are used to ++ represent parameter (i.e. step, bound) of a lowered OpenACC ++ partitioned loop. But this kind of partitioned loop might not ++ survive from aggressive loop removal for it has loop exit and ++ is assumed to be finite. Therefore, we need to explicitly mark ++ these calls. (An example is libgomp.oacc-c-c++-common/pr84955.c) */ ++ if (gimple_call_internal_p (stmt, IFN_GOACC_LOOP)) ++ { ++ mark_stmt_necessary (stmt, true); ++ return; ++ } + if (!gimple_call_lhs (stmt)) + return; + break; +diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c +index 84e6e313c85..f51385900ed 100644 +--- a/gcc/tree-ssa-loop-niter.c ++++ b/gcc/tree-ssa-loop-niter.c +@@ -2830,6 +2830,27 @@ finite_loop_p (struct loop *loop) + loop->num); + return true; + } ++ ++ if (flag_finite_loops) ++ { ++ unsigned i; ++ vec exits = get_loop_exit_edges (loop); ++ edge ex; ++ ++ /* If the loop has a normal exit, we can assume it will terminate. */ ++ FOR_EACH_VEC_ELT (exits, i, ex) ++ if (!(ex->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_FAKE))) ++ { ++ exits.release (); ++ if (dump_file) ++ fprintf (dump_file, "Assume loop %i to be finite: it has an exit " ++ "and -ffinite-loops is on.\n", loop->num); ++ return true; ++ } ++ ++ exits.release (); ++ } ++ + return false; + } + +diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr84955-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr84955-1.c +new file mode 100644 +index 00000000000..44767cd27c3 +--- /dev/null ++++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr84955-1.c +@@ -0,0 +1,31 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -fdump-tree-cddce2 -ffinite-loops" } */ ++ ++int ++f1 (void) ++{ ++ int i, j; ++ ++#pragma acc parallel loop tile(2,3) ++ for (i = 1; i < 10; i++) ++ for (j = 1; j < 10; j++) ++ for (;;) ++ ; ++ ++ return i + j; ++} ++ ++int ++f2 (void) ++{ ++ int i, j, k; ++ ++#pragma acc parallel loop tile(2,3) ++ for (i = 1; i < 10; i++) ++ for (j = 1; j < 10; j++) ++ for (k = 1; k < 10; k++) ++ ; ++ ++ return i + j; ++} ++/* { dg-final { scan-tree-dump-not "if" "cddce2"} } */ diff --git a/loop-split.patch b/loop-split.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6890601cea8c499e7ff429017a3cf609b7ca0e6 --- /dev/null +++ b/loop-split.patch @@ -0,0 +1,1276 @@ +diff --git a/gcc/params.def b/gcc/params.def +index 942447d77e6..df7d1f7c5e7 100644 +--- a/gcc/params.def ++++ b/gcc/params.def +@@ -415,6 +415,12 @@ DEFPARAM(PARAM_MAX_UNSWITCH_LEVEL, + "The maximum number of unswitchings in a single loop.", + 3, 0, 0) + ++DEFPARAM(PARAM_MIN_LOOP_COND_SPLIT_PROB, ++ "min-loop-cond-split-prob", ++ "The minimum threshold for probability of semi-invariant condition " ++ "statement to trigger loop split.", ++ 30, 0, 100) ++ + /* The maximum number of insns in loop header duplicated by the copy loop + headers pass. */ + DEFPARAM(PARAM_MAX_LOOP_HEADER_INSNS, +diff --git a/gcc/testsuite/g++.dg/tree-ssa/loop-cond-split-1.C b/gcc/testsuite/g++.dg/tree-ssa/loop-cond-split-1.C +new file mode 100644 +index 00000000000..0d679cb9035 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/tree-ssa/loop-cond-split-1.C +@@ -0,0 +1,33 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fdump-tree-lsplit-details" } */ ++ ++#include ++#include ++ ++using namespace std; ++ ++class A ++{ ++public: ++ bool empty; ++ void set (string s); ++}; ++ ++class B ++{ ++ map m; ++ void f (); ++}; ++ ++extern A *ga; ++ ++void B::f () ++{ ++ for (map::iterator iter = m.begin (); iter != m.end (); ++iter) ++ { ++ if (ga->empty) ++ ga->set (iter->second); ++ } ++} ++ ++/* { dg-final { scan-tree-dump-times "loop split on semi-invariant condition at false branch" 1 "lsplit" } } */ +diff --git a/gcc/testsuite/gcc.dg/torture/pr55107.c b/gcc/testsuite/gcc.dg/torture/pr55107.c +index 2402716be30..d757c041220 100644 +--- a/gcc/testsuite/gcc.dg/torture/pr55107.c ++++ b/gcc/testsuite/gcc.dg/torture/pr55107.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-additional-options "-fno-split-loops" } */ + + typedef unsigned short uint16_t; + +diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-cond-split-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-cond-split-1.c +new file mode 100644 +index 00000000000..feb776e8373 +--- /dev/null ++++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-cond-split-1.c +@@ -0,0 +1,97 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -fdump-tree-lsplit-details" } */ ++ ++extern const int step; ++ ++int ga, gb; ++ ++__attribute__((pure)) __attribute__((noinline)) int inc (int i) ++{ ++ return i + step; ++} ++ ++extern int do_something (void); ++ ++void test1 (int n) ++{ ++ int i; ++ ++ for (i = 0; i < n; i = inc (i)) ++ { ++ if (ga) ++ ga = do_something (); ++ } ++} ++ ++void test2 (int n, int p) ++{ ++ int i; ++ int v; ++ ++ for (i = 0; i < n ; i = inc (i)) ++ { ++ if (ga) ++ { ++ v = inc (2); ++ gb += 1; ++ } ++ else ++ { ++ v = p * p; ++ gb *= 3; ++ } ++ ++ if (v < 10) ++ ga = do_something (); ++ } ++} ++ ++void test3 (int n, int p) ++{ ++ int i; ++ int c = p + 1; ++ int v; ++ ++ for (i = 0; i < n ; i = inc (i)) ++ { ++ if (c) ++ { ++ v = inc (c); ++ gb += 1; ++ } ++ else ++ { ++ v = p * p; ++ gb *= 3; ++ } ++ ++ if (v < 10) ++ c = do_something (); ++ } ++} ++ ++void test4 (int n, int p) ++{ ++ int i; ++ int v; ++ ++ for (i = 0; i < n ; i = inc (i)) ++ { ++ if (ga) ++ { ++ v = inc (2); ++ if (gb > 16) ++ v = inc (5); ++ } ++ else ++ { ++ v = p * p; ++ gb += 2; ++ } ++ ++ if (v < 10) ++ ga = do_something (); ++ } ++} ++ ++/* { dg-final { scan-tree-dump-times "loop split on semi-invariant condition at false branch" 3 "lsplit" } } */ +diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c +index f5f083384bc..6302d044e09 100644 +--- a/gcc/tree-ssa-loop-split.c ++++ b/gcc/tree-ssa-loop-split.c +@@ -32,7 +32,10 @@ along with GCC; see the file COPYING3. If not see + #include "tree-ssa-loop.h" + #include "tree-ssa-loop-manip.h" + #include "tree-into-ssa.h" ++#include "tree-inline.h" ++#include "tree-cfgcleanup.h" + #include "cfgloop.h" ++#include "params.h" + #include "tree-scalar-evolution.h" + #include "gimple-iterator.h" + #include "gimple-pretty-print.h" +@@ -40,7 +43,9 @@ along with GCC; see the file COPYING3. If not see + #include "gimple-fold.h" + #include "gimplify-me.h" + +-/* This file implements loop splitting, i.e. transformation of loops like ++/* This file implements two kinds of loop splitting. ++ ++ One transformation of loops like: + + for (i = 0; i < 100; i++) + { +@@ -487,8 +492,9 @@ compute_new_first_bound (gimple_seq *stmts, class tree_niter_desc *niter, + single exit of LOOP. */ + + static bool +-split_loop (struct loop *loop1, struct tree_niter_desc *niter) ++split_loop (struct loop *loop1) + { ++ struct tree_niter_desc niter; + basic_block *bbs; + unsigned i; + bool changed = false; +@@ -496,8 +502,28 @@ split_loop (class loop *loop1, class tree_niter_desc *niter) + tree border = NULL_TREE; + affine_iv iv; + ++ if (!single_exit (loop1) ++ /* ??? We could handle non-empty latches when we split the latch edge ++ (not the exit edge), and put the new exit condition in the new block. ++ OTOH this executes some code unconditionally that might have been ++ skipped by the original exit before. */ ++ || !empty_block_p (loop1->latch) ++ || !easy_exit_values (loop1) ++ || !number_of_iterations_exit (loop1, single_exit (loop1), &niter, ++ false, true) ++ || niter.cmp == ERROR_MARK ++ /* We can't yet handle loops controlled by a != predicate. */ ++ || niter.cmp == NE_EXPR) ++ return false; ++ + bbs = get_loop_body (loop1); + ++ if (!can_copy_bbs_p (bbs, loop1->num_nodes)) ++ { ++ free (bbs); ++ return false; ++ } ++ + /* Find a splitting opportunity. */ + for (i = 0; i < loop1->num_nodes; i++) + if ((guard_iv = split_at_bb_p (loop1, bbs[i], &border, &iv))) +@@ -505,8 +531,8 @@ split_loop (class loop *loop1, class tree_niter_desc *niter) + /* Handling opposite steps is not implemented yet. Neither + is handling different step sizes. */ + if ((tree_int_cst_sign_bit (iv.step) +- != tree_int_cst_sign_bit (niter->control.step)) +- || !tree_int_cst_equal (iv.step, niter->control.step)) ++ != tree_int_cst_sign_bit (niter.control.step)) ++ || !tree_int_cst_equal (iv.step, niter.control.step)) + continue; + + /* Find a loop PHI node that defines guard_iv directly, +@@ -575,7 +601,7 @@ split_loop (class loop *loop1, class tree_niter_desc *niter) + Compute the new bound for the guarding IV and patch the + loop exit to use it instead of original IV and bound. */ + gimple_seq stmts = NULL; +- tree newend = compute_new_first_bound (&stmts, niter, border, ++ tree newend = compute_new_first_bound (&stmts, &niter, border, + guard_code, guard_init); + if (stmts) + gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop1), +@@ -612,6 +638,956 @@ split_loop (class loop *loop1, class tree_niter_desc *niter) + return changed; + } + ++/* Another transformation of loops like: ++ ++ for (i = INIT (); CHECK (i); i = NEXT ()) ++ { ++ if (expr (a_1, a_2, ..., a_n)) // expr is pure ++ a_j = ...; // change at least one a_j ++ else ++ S; // not change any a_j ++ } ++ ++ into: ++ ++ for (i = INIT (); CHECK (i); i = NEXT ()) ++ { ++ if (expr (a_1, a_2, ..., a_n)) ++ a_j = ...; ++ else ++ { ++ S; ++ i = NEXT (); ++ break; ++ } ++ } ++ ++ for (; CHECK (i); i = NEXT ()) ++ { ++ S; ++ } ++ ++ */ ++ ++/* Data structure to hold temporary information during loop split upon ++ semi-invariant conditional statement. */ ++class split_info { ++public: ++ /* Array of all basic blocks in a loop, returned by get_loop_body(). */ ++ basic_block *bbs; ++ ++ /* All memory store/clobber statements in a loop. */ ++ auto_vec memory_stores; ++ ++ /* Whether above memory stores vector has been filled. */ ++ int need_init; ++ ++ /* Control dependencies of basic blocks in a loop. */ ++ auto_vec *> control_deps; ++ ++ split_info () : bbs (NULL), need_init (true) { } ++ ++ ~split_info () ++ { ++ if (bbs) ++ free (bbs); ++ ++ for (unsigned i = 0; i < control_deps.length (); i++) ++ delete control_deps[i]; ++ } ++}; ++ ++/* Find all statements with memory-write effect in LOOP, including memory ++ store and non-pure function call, and keep those in a vector. This work ++ is only done one time, for the vector should be constant during analysis ++ stage of semi-invariant condition. */ ++ ++static void ++find_vdef_in_loop (struct loop *loop) ++{ ++ split_info *info = (split_info *) loop->aux; ++ gphi *vphi = get_virtual_phi (loop->header); ++ ++ /* Indicate memory store vector has been filled. */ ++ info->need_init = false; ++ ++ /* If loop contains memory operation, there must be a virtual PHI node in ++ loop header basic block. */ ++ if (vphi == NULL) ++ return; ++ ++ /* All virtual SSA names inside the loop are connected to be a cyclic ++ graph via virtual PHI nodes. The virtual PHI node in loop header just ++ links the first and the last virtual SSA names, by using the last as ++ PHI operand to define the first. */ ++ const edge latch = loop_latch_edge (loop); ++ const tree first = gimple_phi_result (vphi); ++ const tree last = PHI_ARG_DEF_FROM_EDGE (vphi, latch); ++ ++ /* The virtual SSA cyclic graph might consist of only one SSA name, who ++ is defined by itself. ++ ++ .MEM_1 = PHI <.MEM_2(loop entry edge), .MEM_1(latch edge)> ++ ++ This means the loop contains only memory loads, so we can skip it. */ ++ if (first == last) ++ return; ++ ++ auto_vec other_stores; ++ auto_vec worklist; ++ auto_bitmap visited; ++ ++ bitmap_set_bit (visited, SSA_NAME_VERSION (first)); ++ bitmap_set_bit (visited, SSA_NAME_VERSION (last)); ++ worklist.safe_push (last); ++ ++ do ++ { ++ tree vuse = worklist.pop (); ++ gimple *stmt = SSA_NAME_DEF_STMT (vuse); ++ ++ /* We mark the first and last SSA names as visited at the beginning, ++ and reversely start the process from the last SSA name towards the ++ first, which ensures that this do-while will not touch SSA names ++ defined outside the loop. */ ++ gcc_assert (gimple_bb (stmt) ++ && flow_bb_inside_loop_p (loop, gimple_bb (stmt))); ++ ++ if (gimple_code (stmt) == GIMPLE_PHI) ++ { ++ gphi *phi = as_a (stmt); ++ ++ for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) ++ { ++ tree arg = gimple_phi_arg_def (stmt, i); ++ ++ if (bitmap_set_bit (visited, SSA_NAME_VERSION (arg))) ++ worklist.safe_push (arg); ++ } ++ } ++ else ++ { ++ tree prev = gimple_vuse (stmt); ++ ++ /* Non-pure call statement is conservatively assumed to impact all ++ memory locations. So place call statements ahead of other memory ++ stores in the vector with an idea of of using them as shortcut ++ terminators to memory alias analysis. */ ++ if (gimple_code (stmt) == GIMPLE_CALL) ++ info->memory_stores.safe_push (stmt); ++ else ++ other_stores.safe_push (stmt); ++ ++ if (bitmap_set_bit (visited, SSA_NAME_VERSION (prev))) ++ worklist.safe_push (prev); ++ } ++ } while (!worklist.is_empty ()); ++ ++ info->memory_stores.safe_splice (other_stores); ++} ++ ++/* Two basic blocks have equivalent control dependency if one dominates to ++ the other, and it is post-dominated by the latter. Given a basic block ++ BB in LOOP, find farest equivalent dominating basic block. For BB, there ++ is a constraint that BB does not post-dominate loop header of LOOP, this ++ means BB is control-dependent on at least one basic block in LOOP. */ ++ ++static basic_block ++get_control_equiv_head_block (struct loop *loop, basic_block bb) ++{ ++ while (!bb->aux) ++ { ++ basic_block dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb); ++ ++ gcc_checking_assert (dom_bb && flow_bb_inside_loop_p (loop, dom_bb)); ++ ++ if (!dominated_by_p (CDI_POST_DOMINATORS, dom_bb, bb)) ++ break; ++ ++ bb = dom_bb; ++ } ++ return bb; ++} ++ ++/* Given a BB in LOOP, find out all basic blocks in LOOP that BB is control- ++ dependent on. */ ++ ++static hash_set * ++find_control_dep_blocks (struct loop *loop, basic_block bb) ++{ ++ /* BB has same control dependency as loop header, then it is not control- ++ dependent on any basic block in LOOP. */ ++ if (dominated_by_p (CDI_POST_DOMINATORS, loop->header, bb)) ++ return NULL; ++ ++ basic_block equiv_head = get_control_equiv_head_block (loop, bb); ++ ++ if (equiv_head->aux) ++ { ++ /* There is a basic block containing control dependency equivalent ++ to BB. No need to recompute that, and also set this information ++ to other equivalent basic blocks. */ ++ for (; bb != equiv_head; ++ bb = get_immediate_dominator (CDI_DOMINATORS, bb)) ++ bb->aux = equiv_head->aux; ++ return (hash_set *) equiv_head->aux; ++ } ++ ++ /* A basic block X is control-dependent on another Y iff there exists ++ a path from X to Y, in which every basic block other than X and Y ++ is post-dominated by Y, but X is not post-dominated by Y. ++ ++ According to this rule, traverse basic blocks in the loop backwards ++ starting from BB, if a basic block is post-dominated by BB, extend ++ current post-dominating path to this block, otherwise it is another ++ one that BB is control-dependent on. */ ++ ++ auto_vec pdom_worklist; ++ hash_set pdom_visited; ++ hash_set *dep_bbs = new hash_set; ++ ++ pdom_worklist.safe_push (equiv_head); ++ ++ do ++ { ++ basic_block pdom_bb = pdom_worklist.pop (); ++ edge_iterator ei; ++ edge e; ++ ++ if (pdom_visited.add (pdom_bb)) ++ continue; ++ ++ FOR_EACH_EDGE (e, ei, pdom_bb->preds) ++ { ++ basic_block pred_bb = e->src; ++ ++ if (!dominated_by_p (CDI_POST_DOMINATORS, pred_bb, bb)) ++ { ++ dep_bbs->add (pred_bb); ++ continue; ++ } ++ ++ pred_bb = get_control_equiv_head_block (loop, pred_bb); ++ ++ if (pdom_visited.contains (pred_bb)) ++ continue; ++ ++ if (!pred_bb->aux) ++ { ++ pdom_worklist.safe_push (pred_bb); ++ continue; ++ } ++ ++ /* If control dependency of basic block is available, fast extend ++ post-dominating path using the information instead of advancing ++ forward step-by-step. */ ++ hash_set *pred_dep_bbs ++ = (hash_set *) pred_bb->aux; ++ ++ for (hash_set::iterator iter = pred_dep_bbs->begin (); ++ iter != pred_dep_bbs->end (); ++iter) ++ { ++ basic_block pred_dep_bb = *iter; ++ ++ /* Basic blocks can either be in control dependency of BB, or ++ must be post-dominated by BB, if so, extend the path from ++ these basic blocks. */ ++ if (!dominated_by_p (CDI_POST_DOMINATORS, pred_dep_bb, bb)) ++ dep_bbs->add (pred_dep_bb); ++ else if (!pdom_visited.contains (pred_dep_bb)) ++ pdom_worklist.safe_push (pred_dep_bb); ++ } ++ } ++ } while (!pdom_worklist.is_empty ()); ++ ++ /* Record computed control dependencies in loop so that we can reach them ++ when reclaiming resources. */ ++ ((split_info *) loop->aux)->control_deps.safe_push (dep_bbs); ++ ++ /* Associate control dependence with related equivalent basic blocks. */ ++ for (equiv_head->aux = dep_bbs; bb != equiv_head; ++ bb = get_immediate_dominator (CDI_DOMINATORS, bb)) ++ bb->aux = dep_bbs; ++ ++ return dep_bbs; ++} ++ ++/* Forward declaration */ ++ ++static bool ++stmt_semi_invariant_p_1 (struct loop *loop, gimple *stmt, ++ const_basic_block skip_head, ++ hash_map &stmt_stat); ++ ++/* Given STMT, memory load or pure call statement, check whether it is impacted ++ by some memory store in LOOP, excluding trace starting from SKIP_HEAD (the ++ trace is composed of SKIP_HEAD and those basic block dominated by it, always ++ corresponds to one branch of a conditional statement). If SKIP_HEAD is ++ NULL, all basic blocks of LOOP are checked. */ ++ ++static bool ++vuse_semi_invariant_p (struct loop *loop, gimple *stmt, ++ const_basic_block skip_head) ++{ ++ split_info *info = (split_info *) loop->aux; ++ tree rhs = NULL_TREE; ++ ao_ref ref; ++ gimple *store; ++ unsigned i; ++ ++ /* Collect memory store/clobber statements if haven't done that. */ ++ if (info->need_init) ++ find_vdef_in_loop (loop); ++ ++ if (is_gimple_assign (stmt)) ++ rhs = gimple_assign_rhs1 (stmt); ++ ++ ao_ref_init (&ref, rhs); ++ ++ FOR_EACH_VEC_ELT (info->memory_stores, i, store) ++ { ++ /* Skip basic blocks dominated by SKIP_HEAD, if non-NULL. */ ++ if (skip_head ++ && dominated_by_p (CDI_DOMINATORS, gimple_bb (store), skip_head)) ++ continue; ++ ++ if (!ref.ref || stmt_may_clobber_ref_p_1 (store, &ref)) ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Suppose one condition branch, led by SKIP_HEAD, is not executed since ++ certain iteration of LOOP, check whether an SSA name (NAME) remains ++ unchanged in next iteration. We call this characteristic semi- ++ invariantness. SKIP_HEAD might be NULL, if so, nothing excluded, all basic ++ blocks and control flows in the loop will be considered. Semi-invariant ++ state of checked statement is cached in hash map STMT_STAT to avoid ++ redundant computation in possible following re-check. */ ++ ++static inline bool ++ssa_semi_invariant_p (struct loop *loop, tree name, ++ const_basic_block skip_head, ++ hash_map &stmt_stat) ++{ ++ gimple *def = SSA_NAME_DEF_STMT (name); ++ const_basic_block def_bb = gimple_bb (def); ++ ++ /* An SSA name defined outside loop is definitely semi-invariant. */ ++ if (!def_bb || !flow_bb_inside_loop_p (loop, def_bb)) ++ return true; ++ ++ return stmt_semi_invariant_p_1 (loop, def, skip_head, stmt_stat); ++} ++ ++/* Check whether a loop iteration PHI node (LOOP_PHI) defines a value that is ++ semi-invariant in LOOP. Basic blocks dominated by SKIP_HEAD (if non-NULL), ++ are excluded from LOOP. */ ++ ++static bool ++loop_iter_phi_semi_invariant_p (struct loop *loop, gphi *loop_phi, ++ const_basic_block skip_head) ++{ ++ const_edge latch = loop_latch_edge (loop); ++ tree name = gimple_phi_result (loop_phi); ++ tree from = PHI_ARG_DEF_FROM_EDGE (loop_phi, latch); ++ ++ gcc_checking_assert (from); ++ ++ /* Loop iteration PHI node locates in loop header, and it has two source ++ operands, one is an initial value coming from outside the loop, the other ++ is a value through latch of the loop, which is derived in last iteration, ++ we call the latter latch value. From the PHI node to definition of latch ++ value, if excluding branch trace starting from SKIP_HEAD, except copy- ++ assignment or likewise, there is no other kind of value redefinition, SSA ++ name defined by the PHI node is semi-invariant. ++ ++ loop entry ++ | .--- latch ---. ++ | | | ++ v v | ++ x_1 = PHI | ++ | | ++ v | ++ .------- if (cond) -------. | ++ | | | ++ | [ SKIP ] | ++ | | | ++ | x_2 = ... | ++ | | | ++ '---- T ---->.<---- F ----' | ++ | | ++ v | ++ x_3 = PHI | ++ | | ++ '----------------------' ++ ++ Suppose in certain iteration, execution flow in above graph goes through ++ true branch, which means that one source value to define x_3 in false ++ branch (x_2) is skipped, x_3 only comes from x_1, and x_1 in next ++ iterations is defined by x_3, we know that x_1 will never changed if COND ++ always chooses true branch from then on. */ ++ ++ while (from != name) ++ { ++ /* A new value comes from a CONSTANT. */ ++ if (TREE_CODE (from) != SSA_NAME) ++ return false; ++ ++ gimple *stmt = SSA_NAME_DEF_STMT (from); ++ const_basic_block bb = gimple_bb (stmt); ++ ++ /* A new value comes from outside the loop. */ ++ if (!bb || !flow_bb_inside_loop_p (loop, bb)) ++ return false; ++ ++ from = NULL_TREE; ++ ++ if (gimple_code (stmt) == GIMPLE_PHI) ++ { ++ gphi *phi = as_a (stmt); ++ ++ for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) ++ { ++ if (skip_head) ++ { ++ const_edge e = gimple_phi_arg_edge (phi, i); ++ ++ /* Don't consider redefinitions in excluded basic blocks. */ ++ if (dominated_by_p (CDI_DOMINATORS, e->src, skip_head)) ++ continue; ++ } ++ ++ tree arg = gimple_phi_arg_def (phi, i); ++ ++ if (!from) ++ from = arg; ++ else if (!operand_equal_p (from, arg, 0)) ++ /* There are more than one source operands that provide ++ different values to the SSA name, it is variant. */ ++ return false; ++ } ++ } ++ else if (gimple_code (stmt) == GIMPLE_ASSIGN) ++ { ++ /* For simple value copy, check its rhs instead. */ ++ if (gimple_assign_ssa_name_copy_p (stmt)) ++ from = gimple_assign_rhs1 (stmt); ++ } ++ ++ /* Any other kind of definition is deemed to introduce a new value ++ to the SSA name. */ ++ if (!from) ++ return false; ++ } ++ return true; ++} ++ ++/* Check whether conditional predicates that BB is control-dependent on, are ++ semi-invariant in LOOP. Basic blocks dominated by SKIP_HEAD (if non-NULL), ++ are excluded from LOOP. Semi-invariant state of checked statement is cached ++ in hash map STMT_STAT. */ ++ ++static bool ++control_dep_semi_invariant_p (struct loop *loop, basic_block bb, ++ const_basic_block skip_head, ++ hash_map &stmt_stat) ++{ ++ hash_set *dep_bbs = find_control_dep_blocks (loop, bb); ++ ++ if (!dep_bbs) ++ return true; ++ ++ for (hash_set::iterator iter = dep_bbs->begin (); ++ iter != dep_bbs->end (); ++iter) ++ { ++ gimple *last = last_stmt (*iter); ++ ++ if (!last) ++ return false; ++ ++ /* Only check condition predicates. */ ++ if (gimple_code (last) != GIMPLE_COND ++ && gimple_code (last) != GIMPLE_SWITCH) ++ return false; ++ ++ if (!stmt_semi_invariant_p_1 (loop, last, skip_head, stmt_stat)) ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Check whether STMT is semi-invariant in LOOP, iff all its operands are ++ semi-invariant, consequently, all its defined values are semi-invariant. ++ Basic blocks dominated by SKIP_HEAD (if non-NULL), are excluded from LOOP. ++ Semi-invariant state of checked statement is cached in hash map ++ STMT_STAT. */ ++ ++static bool ++stmt_semi_invariant_p_1 (struct loop *loop, gimple *stmt, ++ const_basic_block skip_head, ++ hash_map &stmt_stat) ++{ ++ bool existed; ++ bool &invar = stmt_stat.get_or_insert (stmt, &existed); ++ ++ if (existed) ++ return invar; ++ ++ /* A statement might depend on itself, which is treated as variant. So set ++ state of statement under check to be variant to ensure that. */ ++ invar = false; ++ ++ if (gimple_code (stmt) == GIMPLE_PHI) ++ { ++ gphi *phi = as_a (stmt); ++ ++ if (gimple_bb (stmt) == loop->header) ++ { ++ invar = loop_iter_phi_semi_invariant_p (loop, phi, skip_head); ++ return invar; ++ } ++ ++ /* For a loop PHI node that does not locate in loop header, it is semi- ++ invariant only if two conditions are met. The first is its source ++ values are derived from CONSTANT (including loop-invariant value), or ++ from SSA name defined by semi-invariant loop iteration PHI node. The ++ second is its source incoming edges are control-dependent on semi- ++ invariant conditional predicates. */ ++ for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) ++ { ++ const_edge e = gimple_phi_arg_edge (phi, i); ++ tree arg = gimple_phi_arg_def (phi, i); ++ ++ if (TREE_CODE (arg) == SSA_NAME) ++ { ++ if (!ssa_semi_invariant_p (loop, arg, skip_head, stmt_stat)) ++ return false; ++ ++ /* If source value is defined in location from where the source ++ edge comes in, no need to check control dependency again ++ since this has been done in above SSA name check stage. */ ++ if (e->src == gimple_bb (SSA_NAME_DEF_STMT (arg))) ++ continue; ++ } ++ ++ if (!control_dep_semi_invariant_p (loop, e->src, skip_head, ++ stmt_stat)) ++ return false; ++ } ++ } ++ else ++ { ++ ssa_op_iter iter; ++ tree use; ++ ++ /* Volatile memory load or return of normal (non-const/non-pure) call ++ should not be treated as constant in each iteration of loop. */ ++ if (gimple_has_side_effects (stmt)) ++ return false; ++ ++ /* Check if any memory store may kill memory load at this place. */ ++ if (gimple_vuse (stmt) && !vuse_semi_invariant_p (loop, stmt, skip_head)) ++ return false; ++ ++ /* Although operand of a statement might be SSA name, CONSTANT or ++ VARDECL, here we only need to check SSA name operands. This is ++ because check on VARDECL operands, which involve memory loads, ++ must have been done prior to invocation of this function in ++ vuse_semi_invariant_p. */ ++ FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) ++ if (!ssa_semi_invariant_p (loop, use, skip_head, stmt_stat)) ++ return false; ++ } ++ ++ if (!control_dep_semi_invariant_p (loop, gimple_bb (stmt), skip_head, ++ stmt_stat)) ++ return false; ++ ++ /* Here we SHOULD NOT use invar = true, since hash map might be changed due ++ to new insertion, and thus invar may point to invalid memory. */ ++ stmt_stat.put (stmt, true); ++ return true; ++} ++ ++/* A helper function to check whether STMT is semi-invariant in LOOP. Basic ++ blocks dominated by SKIP_HEAD (if non-NULL), are excluded from LOOP. */ ++ ++static bool ++stmt_semi_invariant_p (struct loop *loop, gimple *stmt, ++ const_basic_block skip_head) ++{ ++ hash_map stmt_stat; ++ return stmt_semi_invariant_p_1 (loop, stmt, skip_head, stmt_stat); ++} ++ ++/* Determine when conditional statement never transfers execution to one of its ++ branch, whether we can remove the branch's leading basic block (BRANCH_BB) ++ and those basic blocks dominated by BRANCH_BB. */ ++ ++static bool ++branch_removable_p (basic_block branch_bb) ++{ ++ edge_iterator ei; ++ edge e; ++ ++ if (single_pred_p (branch_bb)) ++ return true; ++ ++ FOR_EACH_EDGE (e, ei, branch_bb->preds) ++ { ++ if (dominated_by_p (CDI_DOMINATORS, e->src, branch_bb)) ++ continue; ++ ++ if (dominated_by_p (CDI_DOMINATORS, branch_bb, e->src)) ++ continue; ++ ++ /* The branch can be reached from opposite branch, or from some ++ statement not dominated by the conditional statement. */ ++ return false; ++ } ++ ++ return true; ++} ++ ++/* Find out which branch of a conditional statement (COND) is invariant in the ++ execution context of LOOP. That is: once the branch is selected in certain ++ iteration of the loop, any operand that contributes to computation of the ++ conditional statement remains unchanged in all following iterations. */ ++ ++static edge ++get_cond_invariant_branch (struct loop *loop, gcond *cond) ++{ ++ basic_block cond_bb = gimple_bb (cond); ++ basic_block targ_bb[2]; ++ bool invar[2]; ++ unsigned invar_checks = 0; ++ ++ for (unsigned i = 0; i < 2; i++) ++ { ++ targ_bb[i] = EDGE_SUCC (cond_bb, i)->dest; ++ ++ /* One branch directs to loop exit, no need to perform loop split upon ++ this conditional statement. Firstly, it is trivial if the exit branch ++ is semi-invariant, for the statement is just to break loop. Secondly, ++ if the opposite branch is semi-invariant, it means that the statement ++ is real loop-invariant, which is covered by loop unswitch. */ ++ if (!flow_bb_inside_loop_p (loop, targ_bb[i])) ++ return NULL; ++ } ++ ++ for (unsigned i = 0; i < 2; i++) ++ { ++ invar[!i] = false; ++ ++ if (!branch_removable_p (targ_bb[i])) ++ continue; ++ ++ /* Given a semi-invariant branch, if its opposite branch dominates ++ loop latch, it and its following trace will only be executed in ++ final iteration of loop, namely it is not part of repeated body ++ of the loop. Similar to the above case that the branch is loop ++ exit, no need to split loop. */ ++ if (dominated_by_p (CDI_DOMINATORS, loop->latch, targ_bb[i])) ++ continue; ++ ++ invar[!i] = stmt_semi_invariant_p (loop, cond, targ_bb[i]); ++ invar_checks++; ++ } ++ ++ /* With both branches being invariant (handled by loop unswitch) or ++ variant is not what we want. */ ++ if (invar[0] ^ !invar[1]) ++ return NULL; ++ ++ /* Found a real loop-invariant condition, do nothing. */ ++ if (invar_checks < 2 && stmt_semi_invariant_p (loop, cond, NULL)) ++ return NULL; ++ ++ return EDGE_SUCC (cond_bb, invar[0] ? 0 : 1); ++} ++ ++/* Calculate increased code size measured by estimated insn number if applying ++ loop split upon certain branch (BRANCH_EDGE) of a conditional statement. */ ++ ++static int ++compute_added_num_insns (struct loop *loop, const_edge branch_edge) ++{ ++ basic_block cond_bb = branch_edge->src; ++ unsigned branch = EDGE_SUCC (cond_bb, 1) == branch_edge; ++ basic_block opposite_bb = EDGE_SUCC (cond_bb, !branch)->dest; ++ basic_block *bbs = ((split_info *) loop->aux)->bbs; ++ int num = 0; ++ ++ for (unsigned i = 0; i < loop->num_nodes; i++) ++ { ++ /* Do no count basic blocks only in opposite branch. */ ++ if (dominated_by_p (CDI_DOMINATORS, bbs[i], opposite_bb)) ++ continue; ++ ++ num += estimate_num_insns_seq (bb_seq (bbs[i]), &eni_size_weights); ++ } ++ ++ /* It is unnecessary to evaluate expression of the conditional statement ++ in new loop that contains only invariant branch. This expression should ++ be constant value (either true or false). Exclude code size of insns ++ that contribute to computation of the expression. */ ++ ++ auto_vec worklist; ++ hash_set removed; ++ gimple *stmt = last_stmt (cond_bb); ++ ++ worklist.safe_push (stmt); ++ removed.add (stmt); ++ num -= estimate_num_insns (stmt, &eni_size_weights); ++ ++ do ++ { ++ ssa_op_iter opnd_iter; ++ use_operand_p opnd_p; ++ ++ stmt = worklist.pop (); ++ FOR_EACH_PHI_OR_STMT_USE (opnd_p, stmt, opnd_iter, SSA_OP_USE) ++ { ++ tree opnd = USE_FROM_PTR (opnd_p); ++ ++ if (TREE_CODE (opnd) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (opnd)) ++ continue; ++ ++ gimple *opnd_stmt = SSA_NAME_DEF_STMT (opnd); ++ use_operand_p use_p; ++ imm_use_iterator use_iter; ++ ++ if (removed.contains (opnd_stmt) ++ || !flow_bb_inside_loop_p (loop, gimple_bb (opnd_stmt))) ++ continue; ++ ++ FOR_EACH_IMM_USE_FAST (use_p, use_iter, opnd) ++ { ++ gimple *use_stmt = USE_STMT (use_p); ++ ++ if (!is_gimple_debug (use_stmt) && !removed.contains (use_stmt)) ++ { ++ opnd_stmt = NULL; ++ break; ++ } ++ } ++ ++ if (opnd_stmt) ++ { ++ worklist.safe_push (opnd_stmt); ++ removed.add (opnd_stmt); ++ num -= estimate_num_insns (opnd_stmt, &eni_size_weights); ++ } ++ } ++ } while (!worklist.is_empty ()); ++ ++ gcc_assert (num >= 0); ++ return num; ++} ++ ++/* Find out loop-invariant branch of a conditional statement (COND) if it has, ++ and check whether it is eligible and profitable to perform loop split upon ++ this branch in LOOP. */ ++ ++static edge ++get_cond_branch_to_split_loop (struct loop *loop, gcond *cond) ++{ ++ edge invar_branch = get_cond_invariant_branch (loop, cond); ++ if (!invar_branch) ++ return NULL; ++ ++ /* When accurate profile information is available, and execution ++ frequency of the branch is too low, just let it go. */ ++ profile_probability prob = invar_branch->probability; ++ if (prob.reliable_p ()) ++ { ++ int thres = PARAM_VALUE (PARAM_MIN_LOOP_COND_SPLIT_PROB); ++ ++ if (prob < profile_probability::always ().apply_scale (thres, 100)) ++ return NULL; ++ } ++ ++ /* Add a threshold for increased code size to disable loop split. */ ++ if (compute_added_num_insns (loop, invar_branch) ++ > PARAM_VALUE (PARAM_MAX_PEELED_INSNS)) ++ return NULL; ++ ++ return invar_branch; ++} ++ ++/* Given a loop (LOOP1) with a loop-invariant branch (INVAR_BRANCH) of some ++ conditional statement, perform loop split transformation illustrated ++ as the following graph. ++ ++ .-------T------ if (true) ------F------. ++ | .---------------. | ++ | | | | ++ v | v v ++ pre-header | pre-header ++ | .------------. | | .------------. ++ | | | | | | | ++ | v | | | v | ++ header | | header | ++ | | | | | ++ .--- if (cond) ---. | | .--- if (true) ---. | ++ | | | | | | | ++ invariant | | | invariant | | ++ | | | | | | | ++ '---T--->.<---F---' | | '---T--->.<---F---' | ++ | | / | | ++ stmts | / stmts | ++ | F T | | ++ / \ | / / \ | ++ .-------* * [ if (cond) ] .-------* * | ++ | | | | | | ++ | latch | | latch | ++ | | | | | | ++ | '------------' | '------------' ++ '------------------------. .-----------' ++ loop1 | | loop2 ++ v v ++ exits ++ ++ In the graph, loop1 represents the part derived from original one, and ++ loop2 is duplicated using loop_version (), which corresponds to the part ++ of original one being splitted out. In original latch edge of loop1, we ++ insert a new conditional statement duplicated from the semi-invariant cond, ++ and one of its branch goes back to loop1 header as a latch edge, and the ++ other branch goes to loop2 pre-header as an entry edge. And also in loop2, ++ we abandon the variant branch of the conditional statement by setting a ++ constant bool condition, based on which branch is semi-invariant. */ ++ ++static bool ++do_split_loop_on_cond (struct loop *loop1, edge invar_branch) ++{ ++ basic_block cond_bb = invar_branch->src; ++ bool true_invar = !!(invar_branch->flags & EDGE_TRUE_VALUE); ++ gcond *cond = as_a (last_stmt (cond_bb)); ++ ++ gcc_assert (cond_bb->loop_father == loop1); ++ ++ if (dump_enabled_p ()) ++ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, cond, ++ "loop split on semi-invariant condition at %s branch\n", ++ true_invar ? "true" : "false"); ++ ++ initialize_original_copy_tables (); ++ ++ struct loop *loop2 = loop_version (loop1, boolean_true_node, NULL, ++ profile_probability::always (), ++ profile_probability::never (), ++ profile_probability::always (), ++ profile_probability::always (), ++ true); ++ if (!loop2) ++ { ++ free_original_copy_tables (); ++ return false; ++ } ++ ++ basic_block cond_bb_copy = get_bb_copy (cond_bb); ++ gcond *cond_copy = as_a (last_stmt (cond_bb_copy)); ++ ++ /* Replace the condition in loop2 with a bool constant to let PassManager ++ remove the variant branch after current pass completes. */ ++ if (true_invar) ++ gimple_cond_make_true (cond_copy); ++ else ++ gimple_cond_make_false (cond_copy); ++ ++ update_stmt (cond_copy); ++ ++ /* Insert a new conditional statement on latch edge of loop1, its condition ++ is duplicated from the semi-invariant. This statement acts as a switch ++ to transfer execution from loop1 to loop2, when loop1 enters into ++ invariant state. */ ++ basic_block latch_bb = split_edge (loop_latch_edge (loop1)); ++ basic_block break_bb = split_edge (single_pred_edge (latch_bb)); ++ gimple *break_cond = gimple_build_cond (gimple_cond_code(cond), ++ gimple_cond_lhs (cond), ++ gimple_cond_rhs (cond), ++ NULL_TREE, NULL_TREE); ++ ++ gimple_stmt_iterator gsi = gsi_last_bb (break_bb); ++ gsi_insert_after (&gsi, break_cond, GSI_NEW_STMT); ++ ++ edge to_loop1 = single_succ_edge (break_bb); ++ edge to_loop2 = make_edge (break_bb, loop_preheader_edge (loop2)->src, 0); ++ ++ to_loop1->flags &= ~EDGE_FALLTHRU; ++ to_loop1->flags |= true_invar ? EDGE_FALSE_VALUE : EDGE_TRUE_VALUE; ++ to_loop2->flags |= true_invar ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE; ++ ++ update_ssa (TODO_update_ssa); ++ ++ /* Due to introduction of a control flow edge from loop1 latch to loop2 ++ pre-header, we should update PHIs in loop2 to reflect this connection ++ between loop1 and loop2. */ ++ connect_loop_phis (loop1, loop2, to_loop2); ++ ++ free_original_copy_tables (); ++ ++ rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_USE, loop1); ++ ++ return true; ++} ++ ++/* Traverse all conditional statements in LOOP, to find out a good candidate ++ upon which we can do loop split. */ ++ ++static bool ++split_loop_on_cond (struct loop *loop) ++{ ++ split_info *info = new split_info (); ++ basic_block *bbs = info->bbs = get_loop_body (loop); ++ bool do_split = false; ++ ++ /* Allocate an area to keep temporary info, and associate its address ++ with loop aux field. */ ++ loop->aux = info; ++ ++ for (unsigned i = 0; i < loop->num_nodes; i++) ++ bbs[i]->aux = NULL; ++ ++ for (unsigned i = 0; i < loop->num_nodes; i++) ++ { ++ basic_block bb = bbs[i]; ++ ++ /* We only consider conditional statement, which be executed at most once ++ in each iteration of the loop. So skip statements in inner loops. */ ++ if ((bb->loop_father != loop) || (bb->flags & BB_IRREDUCIBLE_LOOP)) ++ continue; ++ ++ /* Actually this check is not a must constraint. With it, we can ensure ++ conditional statement will always be executed in each iteration. */ ++ if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb)) ++ continue; ++ ++ gimple *last = last_stmt (bb); ++ ++ if (!last || gimple_code (last) != GIMPLE_COND) ++ continue; ++ ++ gcond *cond = as_a (last); ++ edge branch_edge = get_cond_branch_to_split_loop (loop, cond); ++ ++ if (branch_edge) ++ { ++ do_split_loop_on_cond (loop, branch_edge); ++ do_split = true; ++ break; ++ } ++ } ++ ++ delete info; ++ loop->aux = NULL; ++ ++ return do_split; ++} ++ + /* Main entry point. Perform loop splitting on all suitable loops. */ + + static unsigned int +@@ -621,13 +1597,15 @@ tree_ssa_split_loops (void) + bool changed = false; + + gcc_assert (scev_initialized_p ()); ++ ++ calculate_dominance_info (CDI_POST_DOMINATORS); ++ + FOR_EACH_LOOP (loop, LI_INCLUDE_ROOT) + loop->aux = NULL; + + /* Go through all loops starting from innermost. */ + FOR_EACH_LOOP (loop, LI_FROM_INNERMOST) + { +- struct tree_niter_desc niter; + if (loop->aux) + { + /* If any of our inner loops was split, don't split us, +@@ -636,35 +1614,24 @@ tree_ssa_split_loops (void) + continue; + } + +- if (single_exit (loop) +- /* ??? We could handle non-empty latches when we split +- the latch edge (not the exit edge), and put the new +- exit condition in the new block. OTOH this executes some +- code unconditionally that might have been skipped by the +- original exit before. */ +- && empty_block_p (loop->latch) +- && !optimize_loop_for_size_p (loop) +- && easy_exit_values (loop) +- && number_of_iterations_exit (loop, single_exit (loop), &niter, +- false, true) +- && niter.cmp != ERROR_MARK +- /* We can't yet handle loops controlled by a != predicate. */ +- && niter.cmp != NE_EXPR +- && can_duplicate_loop_p (loop)) ++ if (optimize_loop_for_size_p (loop)) ++ continue; ++ ++ if (split_loop (loop) || split_loop_on_cond (loop)) + { +- if (split_loop (loop, &niter)) +- { +- /* Mark our containing loop as having had some split inner +- loops. */ +- loop_outer (loop)->aux = loop; +- changed = true; +- } ++ /* Mark our containing loop as having had some split inner loops. */ ++ loop_outer (loop)->aux = loop; ++ changed = true; + } + } + + FOR_EACH_LOOP (loop, LI_INCLUDE_ROOT) + loop->aux = NULL; + ++ clear_aux_for_blocks (); ++ ++ free_dominance_info (CDI_POST_DOMINATORS); ++ + if (changed) + return TODO_cleanup_cfg; + return 0; diff --git a/mark-pattern-as-clobbering-CC-REGNUM.patch b/mark-pattern-as-clobbering-CC-REGNUM.patch deleted file mode 100644 index b65621edab17810ebd7101f962addd91bbb7aafc..0000000000000000000000000000000000000000 --- a/mark-pattern-as-clobbering-CC-REGNUM.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -N -urp a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md ---- a/gcc/config/aarch64/aarch64.md 2019-05-30 16:12:52.950606040 +0800 -+++ b/gcc/config/aarch64/aarch64.md 2019-05-30 16:15:56.606599549 +0800 -@@ -3110,7 +3110,8 @@ - (define_insn_and_split "*compare_cstore_insn" - [(set (match_operand:GPI 0 "register_operand" "=r") - (EQL:GPI (match_operand:GPI 1 "register_operand" "r") -- (match_operand:GPI 2 "aarch64_imm24" "n")))] -+ (match_operand:GPI 2 "aarch64_imm24" "n"))) -+ (clobber (reg:CC CC_REGNUM))] - "!aarch64_move_imm (INTVAL (operands[2]), mode) - && !aarch64_plus_operand (operands[2], mode) - && !reload_completed" diff --git a/option-mfentry-and-mlong-calls-bugfix.patch b/option-mfentry-and-mlong-calls-bugfix.patch deleted file mode 100644 index c242567f7a4ae29d94cb82236385a734a860ca2e..0000000000000000000000000000000000000000 --- a/option-mfentry-and-mlong-calls-bugfix.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff -N -urp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c ---- a/gcc/config/aarch64/aarch64.c 2018-09-19 17:11:42.583520820 +0800 -+++ b/gcc/config/aarch64/aarch64.c 2018-09-19 17:10:22.715520820 +0800 -@@ -1260,29 +1260,32 @@ aarch64_is_long_call_p (rtx sym) - void - aarch64_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) - { -- if (!TARGET_LONG_CALLS) -+ if (flag_fentry) - { -- fprintf (file, "\tmov\tx9, x30\n"); -- fprintf (file, "\tbl\t__fentry__\n"); -- fprintf (file, "\tmov\tx30, x9\n"); -- } -- else -- { -- if (flag_pic) -+ if (!TARGET_LONG_CALLS) - { - fprintf (file, "\tmov\tx9, x30\n"); -- fprintf (file, "\tadrp\tx10, :got:__fentry__\n"); -- fprintf (file, "\tldr\tx10, [x10, #:got_lo12:__fentry__]\n"); -- fprintf (file, "\tblr\tx10\n"); -+ fprintf (file, "\tbl\t__fentry__\n"); - fprintf (file, "\tmov\tx30, x9\n"); - } - else - { -- fprintf (file, "\tmov\tx9, x30\n"); -- fprintf (file, "\tadrp\tx10, __fentry__\n"); -- fprintf (file, "\tadd\tx10, x10, :lo12:__fentry__\n"); -- fprintf (file, "\tblr\tx10\n"); -- fprintf (file, "\tmov\tx30, x9\n"); -+ if (flag_pic) -+ { -+ fprintf (file, "\tmov\tx9, x30\n"); -+ fprintf (file, "\tadrp\tx10, :got:__fentry__\n"); -+ fprintf (file, "\tldr\tx10, [x10, #:got_lo12:__fentry__]\n"); -+ fprintf (file, "\tblr\tx10\n"); -+ fprintf (file, "\tmov\tx30, x9\n"); -+ } -+ else -+ { -+ fprintf (file, "\tmov\tx9, x30\n"); -+ fprintf (file, "\tadrp\tx10, __fentry__\n"); -+ fprintf (file, "\tadd\tx10, x10, :lo12:__fentry__\n"); -+ fprintf (file, "\tblr\tx10\n"); -+ fprintf (file, "\tmov\tx30, x9\n"); -+ } - } - } - } -@@ -12020,6 +12023,15 @@ aarch64_emit_unlikely_jump (rtx insn) - add_int_reg_note (jump, REG_BR_PROB, very_unlikely); - } - -+/* Return true, if profiling code should be emitted before -+ prologue. Otherwise it returns false. -+ Note: For x86 with "hotfix" it is sorried. */ -+static bool -+aarch64_profile_before_prologue (void) -+{ -+ return flag_fentry != 0; -+} -+ - /* Expand a compare and swap pattern. */ - - void -@@ -14952,6 +14964,9 @@ aarch64_run_selftests (void) - #undef TARGET_ASM_ALIGNED_SI_OP - #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" - -+#undef TARGET_PROFILE_BEFORE_PROLOGUE -+#define TARGET_PROFILE_BEFORE_PROLOGUE aarch64_profile_before_prologue -+ - #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK - #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \ - hook_bool_const_tree_hwi_hwi_const_tree_true -diff -N -urp a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h ---- a/gcc/config/aarch64/aarch64.h 2018-09-19 17:11:42.587520820 +0800 -+++ b/gcc/config/aarch64/aarch64.h 2018-09-19 17:10:22.715520820 +0800 -@@ -850,9 +850,12 @@ typedef struct - { \ - rtx fun, lr; \ - const rtx_insn* tmp = get_insns (); \ -- lr = get_hard_reg_initial_val (Pmode, LR_REGNUM); \ -- fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \ -- emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lr, Pmode); \ -+ if (!flag_fentry) \ -+ { \ -+ lr = get_hard_reg_initial_val (Pmode, LR_REGNUM); \ -+ fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \ -+ emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lr, Pmode); \ -+ } \ - if (TARGET_LONG_CALLS) \ - { \ - emit_insn (gen_blockage ()); \ -diff -N -urp a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt ---- a/gcc/config/aarch64/aarch64.opt 2018-09-19 17:11:42.587520820 +0800 -+++ b/gcc/config/aarch64/aarch64.opt 2018-09-19 17:10:22.715520820 +0800 -@@ -192,3 +192,7 @@ single precision and to 32 bits for doub - mverbose-cost-dump - Common Undocumented Var(flag_aarch64_verbose_cost) - Enables verbose cost model dumping in the debug dump files. -+ -+mfentry -+Target Report Var(flag_fentry) Init(0) -+Emit profiling counter call at function entry immediately after prologue. diff --git a/option-mlong-calls.patch b/option-mlong-calls.patch deleted file mode 100644 index 7aadfbe06b96a1319106194b115f7e1534fadc05..0000000000000000000000000000000000000000 --- a/option-mlong-calls.patch +++ /dev/null @@ -1,362 +0,0 @@ -diff -N -urp a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h ---- a/gcc/config/aarch64/aarch64-protos.h 2018-11-06 10:43:27.862079389 +0800 -+++ b/gcc/config/aarch64/aarch64-protos.h 2018-11-06 10:44:34.930081154 +0800 -@@ -353,6 +353,10 @@ bool aarch64_use_return_insn_p (void); - const char *aarch64_mangle_builtin_type (const_tree); - const char *aarch64_output_casesi (rtx *); - -+extern void aarch64_pr_long_calls (struct cpp_reader *); -+extern void aarch64_pr_no_long_calls (struct cpp_reader *); -+extern void aarch64_pr_long_calls_off (struct cpp_reader *); -+ - enum aarch64_symbol_type aarch64_classify_symbol (rtx, rtx); - enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx); - enum reg_class aarch64_regno_regclass (unsigned); -@@ -384,6 +388,7 @@ void aarch64_expand_epilogue (bool); - void aarch64_expand_mov_immediate (rtx, rtx); - void aarch64_expand_prologue (void); - void aarch64_expand_vector_init (rtx, rtx); -+void aarch64_function_profiler (FILE *, int); - void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx, - const_tree, unsigned); - void aarch64_init_expanders (void); -diff -N -urp a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c ---- a/gcc/config/aarch64/aarch64.c 2018-11-06 10:43:27.870079389 +0800 -+++ b/gcc/config/aarch64/aarch64.c 2018-11-06 10:44:34.934081154 +0800 -@@ -70,6 +70,9 @@ - /* This file should be included last. */ - #include "target-def.h" - -+static void aarch64_set_default_type_attributes (tree); -+static int aarch64_comp_type_attributes (const_tree, const_tree); -+ - /* Defined for convenience. */ - #define POINTER_BYTES (POINTER_SIZE / BITS_PER_UNIT) - -@@ -1092,12 +1095,163 @@ aarch64_hard_regno_caller_save_mode (uns - return choose_hard_reg_mode (regno, nregs, false); - } - -+/* Table of machine attributes. */ -+static const struct attribute_spec aarch64_attribute_table[] = -+{ -+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, -+ affects_type_identity }. */ -+ /* Function calls made to this symbol must be done indirectly, because -+ it may lie outside of the 26 bit addressing range of a normal function -+ call. */ -+ { "long_call", 0, 0, false, true, true, NULL, false }, -+ /* Whereas these functions are always known to reside within the 26 bit -+ addressing range. */ -+ { "short_call", 0, 0, false, true, true, NULL, false }, -+ { NULL, 0, 0, false, false, false, NULL, false } -+}; -+ -+/* Encode the current state of the #pragma[no_]long_calls. */ -+typedef enum -+{ -+ OFF, /* No #pragma[no_]long_calls is in effect. */ -+ LONG, /* #pragma long_calls is in effect. */ -+ SHORT /* #pragma no_long_calls is in effect. */ -+} aarch64_pragma_enum; -+ -+static aarch64_pragma_enum aarch64_pragma_long_calls = OFF; -+ -+void -+aarch64_pr_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED) -+{ -+ aarch64_pragma_long_calls = LONG; -+} -+ -+void -+aarch64_pr_no_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED) -+{ -+ aarch64_pragma_long_calls = SHORT; -+} -+ -+void -+aarch64_pr_long_calls_off (struct cpp_reader * pfile ATTRIBUTE_UNUSED) -+{ -+ aarch64_pragma_long_calls = OFF; -+} -+ -+/* Return 0 if the attributes for two types are incompatible, 1 if they -+ are compatible. */ -+static int -+aarch64_comp_type_attributes (const_tree type1, const_tree type2) -+{ -+ int l1, l2, s1, s2; -+ -+ /* Check for mismatch of non-default calling convention. */ -+ if (TREE_CODE (type1) != FUNCTION_TYPE) -+ return 1; -+ -+ /* Check for mismatched call attributes. */ -+ l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL; -+ l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL; -+ s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL; -+ s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL; -+ -+ /* Only bother to check if an attribute is defined. */ -+ if (l1 | l2 | s1 | s2) -+ { -+ /* If one type has an attribute, the other -+ must have the same attribute. */ -+ if ((l1 != l2) || (s1 != s2)) -+ { -+ return 0; -+ } -+ -+ /* Disallow mixed attributes. */ -+ if ((l1 && s2) || (l2 && s1)) -+ { -+ return 0; -+ } -+ } -+ -+ return 1; -+} -+ -+/* Assigns default attributes to newly defined type. This is used to -+ set short_call/long_call attributes for function types of -+ functions defined inside corresponding #pragma scopes. */ -+static void -+aarch64_set_default_type_attributes (tree type) -+{ -+ /* Add __attribute__ ((long_call)) to all functions, when -+ inside #pragma long_calls or __attribute__ ((short_call)), -+ when inside #pragma no_long_calls. */ -+ if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) -+ { -+ tree type_attr_list = NULL; -+ tree attr_name = NULL; -+ type_attr_list = TYPE_ATTRIBUTES (type); -+ -+ if (aarch64_pragma_long_calls == LONG) -+ { -+ attr_name = get_identifier ("long_call"); -+ } -+ else if (aarch64_pragma_long_calls == SHORT) -+ { -+ attr_name = get_identifier ("short_call"); -+ } -+ else -+ { -+ return; -+ } -+ -+ type_attr_list = tree_cons (attr_name, NULL_TREE, type_attr_list); -+ TYPE_ATTRIBUTES (type) = type_attr_list; -+ } -+} -+ -+/* Return true if DECL is known to be linked into section SECTION. */ -+static bool -+aarch64_function_in_section_p (tree decl, section *section) -+{ -+ /* We can only be certain about the prevailing symbol definition. */ -+ if (!decl_binds_to_current_def_p (decl)) -+ return false; -+ -+ /* If DECL_SECTION_NAME is set, assume it is trustworthy. */ -+ if (!DECL_SECTION_NAME (decl)) -+ { -+ /* Make sure that we will not create a unique section for DECL. */ -+ if (flag_function_sections || DECL_COMDAT_GROUP (decl)) -+ return false; -+ } -+ -+ return function_section (decl) == section; -+} -+ - /* Return true if calls to DECL should be treated as - long-calls (ie called via a register). */ - static bool --aarch64_decl_is_long_call_p (const_tree decl ATTRIBUTE_UNUSED) -+aarch64_decl_is_long_call_p (tree decl) - { -- return false; -+ tree attrs = NULL; -+ -+ if (!decl) -+ return TARGET_LONG_CALLS; -+ -+ attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl)); -+ if (lookup_attribute ("short_call", attrs)) -+ return false; -+ -+ /* For "f", be conservative, and only cater for cases in which the -+ whole of the current function is placed in the same section. */ -+ if (!flag_reorder_blocks_and_partition -+ && TREE_CODE (decl) == FUNCTION_DECL -+ && aarch64_function_in_section_p (decl, current_function_section ())) -+ return false; -+ -+ if (lookup_attribute ("long_call", attrs)) -+ return true; -+ -+ return TARGET_LONG_CALLS; - } - - /* Return true if calls to symbol-ref SYM should be treated as -@@ -1108,6 +1257,36 @@ aarch64_is_long_call_p (rtx sym) - return aarch64_decl_is_long_call_p (SYMBOL_REF_DECL (sym)); - } - -+void -+aarch64_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) -+{ -+ if (!TARGET_LONG_CALLS) -+ { -+ fprintf (file, "\tmov\tx9, x30\n"); -+ fprintf (file, "\tbl\t__fentry__\n"); -+ fprintf (file, "\tmov\tx30, x9\n"); -+ } -+ else -+ { -+ if (flag_pic) -+ { -+ fprintf (file, "\tmov\tx9, x30\n"); -+ fprintf (file, "\tadrp\tx10, :got:__fentry__\n"); -+ fprintf (file, "\tldr\tx10, [x10, #:got_lo12:__fentry__]\n"); -+ fprintf (file, "\tblr\tx10\n"); -+ fprintf (file, "\tmov\tx30, x9\n"); -+ } -+ else -+ { -+ fprintf (file, "\tmov\tx9, x30\n"); -+ fprintf (file, "\tadrp\tx10, __fentry__\n"); -+ fprintf (file, "\tadd\tx10, x10, :lo12:__fentry__\n"); -+ fprintf (file, "\tblr\tx10\n"); -+ fprintf (file, "\tmov\tx30, x9\n"); -+ } -+ } -+} -+ - /* Return true if calls to symbol-ref SYM should not go through - plt stubs. */ - -@@ -15099,6 +15278,15 @@ aarch64_libgcc_floating_mode_supported_p - #undef TARGET_SCHED_CAN_SPECULATE_INSN - #define TARGET_SCHED_CAN_SPECULATE_INSN aarch64_sched_can_speculate_insn - -+#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES -+#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES aarch64_set_default_type_attributes -+ -+#undef TARGET_ATTRIBUTE_TABLE -+#define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table -+ -+#undef TARGET_COMP_TYPE_ATTRIBUTES -+#define TARGET_COMP_TYPE_ATTRIBUTES aarch64_comp_type_attributes -+ - #undef TARGET_CAN_USE_DOLOOP_P - #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost - -diff -N -urp a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h ---- a/gcc/config/aarch64/aarch64.h 2018-11-06 10:43:27.870079389 +0800 -+++ b/gcc/config/aarch64/aarch64.h 2018-11-06 10:49:29.574088911 +0800 -@@ -28,7 +28,6 @@ - - - --#define REGISTER_TARGET_PRAGMAS() aarch64_register_pragmas () - - /* Target machine storage layout. */ - -@@ -659,6 +658,14 @@ typedef struct - } CUMULATIVE_ARGS; - #endif - -+/* Handle pragmas for compatibility with Intel's compilers. */ -+#define REGISTER_TARGET_PRAGMAS() do { \ -+ c_register_pragma (0, "long_calls", aarch64_pr_long_calls); \ -+ c_register_pragma (0, "no_long_calls", aarch64_pr_no_long_calls); \ -+ c_register_pragma (0, "long_calls_off", aarch64_pr_long_calls_off); \ -+ aarch64_register_pragmas (); \ -+} while (0) -+ - #define FUNCTION_ARG_PADDING(MODE, TYPE) \ - (aarch64_pad_arg_upward (MODE, TYPE) ? upward : downward) - -@@ -842,13 +849,20 @@ typedef struct - #define PROFILE_HOOK(LABEL) \ - { \ - rtx fun, lr; \ -+ const rtx_insn* tmp = get_insns (); \ - lr = get_hard_reg_initial_val (Pmode, LR_REGNUM); \ - fun = gen_rtx_SYMBOL_REF (Pmode, MCOUNT_NAME); \ - emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lr, Pmode); \ -+ if (TARGET_LONG_CALLS) \ -+ { \ -+ emit_insn (gen_blockage ()); \ -+ emit_insn_after (gen_blockage (), NEXT_INSN (tmp)); \ -+ } \ - } - - /* All the work done in PROFILE_HOOK, but still required. */ --#define FUNCTION_PROFILER(STREAM, LABELNO) do { } while (0) -+#define FUNCTION_PROFILER(STREAM, LABELNO) \ -+ aarch64_function_profiler (STREAM, LABELNO) - - /* For some reason, the Linux headers think they know how to define - these macros. They don't!!! */ -diff -N -urp a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md ---- a/gcc/config/aarch64/aarch64.md 2018-11-06 10:43:27.874079389 +0800 -+++ b/gcc/config/aarch64/aarch64.md 2018-11-06 10:44:34.934081154 +0800 -@@ -850,9 +850,10 @@ - { - rtx pat; - rtx callee = XEXP (operands[0], 0); -- if (!REG_P (callee) -- && ((GET_CODE (callee) != SYMBOL_REF) -- || aarch64_is_noplt_call_p (callee))) -+ -+ if (GET_CODE (callee) == SYMBOL_REF -+ ? (aarch64_is_long_call_p (callee) || aarch64_is_noplt_call_p (callee)) -+ : !REG_P (callee)) - XEXP (operands[0], 0) = force_reg (Pmode, callee); - - if (operands[2] == NULL_RTX) -@@ -881,9 +882,10 @@ - { - rtx pat; - rtx callee = XEXP (operands[1], 0); -- if (!REG_P (callee) -- && ((GET_CODE (callee) != SYMBOL_REF) -- || aarch64_is_noplt_call_p (callee))) -+ -+ if (GET_CODE (callee) == SYMBOL_REF -+ ? (aarch64_is_long_call_p (callee) || aarch64_is_noplt_call_p (callee)) -+ : !REG_P (callee)) - XEXP (operands[1], 0) = force_reg (Pmode, callee); - - if (operands[3] == NULL_RTX) -diff -N -urp a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt ---- a/gcc/config/aarch64/aarch64.opt 2018-11-06 10:43:27.874079389 +0800 -+++ b/gcc/config/aarch64/aarch64.opt 2018-11-06 10:44:34.934081154 +0800 -@@ -80,6 +80,10 @@ mlittle-endian - Target Report RejectNegative InverseMask(BIG_END) - Assume target CPU is configured as little endian. - -+mlong-calls -+Target Report Mask(LONG_CALLS) -+Generate call insns as indirect calls, if necessary. -+ - mcmodel= - Target RejectNegative Joined Enum(cmodel) Var(aarch64_cmodel_var) Init(AARCH64_CMODEL_SMALL) Save - Specify the code model. -diff -N -urp a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md ---- a/gcc/config/aarch64/predicates.md 2018-11-06 10:43:27.878079389 +0800 -+++ b/gcc/config/aarch64/predicates.md 2018-11-06 10:44:34.938081154 +0800 -@@ -27,8 +27,9 @@ - ) - - (define_predicate "aarch64_call_insn_operand" -- (ior (match_code "symbol_ref") -- (match_operand 0 "register_operand"))) -+ (ior (and (match_code "symbol_ref") -+ (match_test "!aarch64_is_long_call_p (op)")) -+ (match_operand 0 "register_operand"))) - - ;; Return true if OP a (const_int 0) operand. - (define_predicate "const0_operand" diff --git a/remove-array-index-inliner-hint.patch b/remove-array-index-inliner-hint.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0c09fbf3ac8176288544d056851492ca3f75791 --- /dev/null +++ b/remove-array-index-inliner-hint.patch @@ -0,0 +1,321 @@ +diff -uprN a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -11895,12 +11895,6 @@ of iterations of a loop known, it adds a bonus of + @option{ipa-cp-loop-hint-bonus} to the profitability score of + the candidate. + +-@item ipa-cp-array-index-hint-bonus +-When IPA-CP determines that a cloning candidate would make the index of +-an array access known, it adds a bonus of +-@option{ipa-cp-array-index-hint-bonus} to the profitability +-score of the candidate. +- + @item ipa-max-aa-steps + During its analysis of function bodies, IPA-CP employs alias analysis + in order to track values pointed to by function parameters. In order +diff -uprN a/gcc/ipa-cp.c b/gcc/ipa-cp.c +--- a/gcc/ipa-cp.c ++++ b/gcc/ipa-cp.c +@@ -2607,8 +2607,6 @@ hint_time_bonus (ipa_hints hints) + int result = 0; + if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride)) + result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS); +- if (hints & INLINE_HINT_array_index) +- result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS); + return result; + } + +diff -uprN a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c +--- a/gcc/ipa-fnsummary.c ++++ b/gcc/ipa-fnsummary.c +@@ -134,11 +134,6 @@ ipa_dump_hints (FILE *f, ipa_hints hints) + hints &= ~INLINE_HINT_declared_inline; + fprintf (f, " declared_inline"); + } +- if (hints & INLINE_HINT_array_index) +- { +- hints &= ~INLINE_HINT_array_index; +- fprintf (f, " array_index"); +- } + if (hints & INLINE_HINT_known_hot) + { + hints &= ~INLINE_HINT_known_hot; +@@ -549,8 +544,6 @@ ipa_fn_summary::~ipa_fn_summary () + edge_predicate_pool.remove (loop_iterations); + if (loop_stride) + edge_predicate_pool.remove (loop_stride); +- if (array_index) +- edge_predicate_pool.remove (array_index); + vec_free (conds); + vec_free (size_time_table); + } +@@ -703,8 +696,6 @@ ipa_fn_summary_t::duplicate (cgraph_node *src, + possible_truths); + remap_hint_predicate_after_duplication (&info->loop_stride, + possible_truths); +- remap_hint_predicate_after_duplication (&info->array_index, +- possible_truths); + + /* If inliner or someone after inliner will ever start producing + non-trivial clones, we will get trouble with lack of information +@@ -727,12 +718,6 @@ ipa_fn_summary_t::duplicate (cgraph_node *src, + info->loop_stride = NULL; + set_hint_predicate (&info->loop_stride, p); + } +- if (info->array_index) +- { +- predicate p = *info->array_index; +- info->array_index = NULL; +- set_hint_predicate (&info->array_index, p); +- } + } + if (!dst->global.inlined_to) + ipa_update_overall_fn_summary (dst); +@@ -894,11 +879,6 @@ ipa_dump_fn_summary (FILE *f, struct cgraph_node *node) + fprintf (f, " loop stride:"); + s->loop_stride->dump (f, s->conds); + } +- if (s->array_index) +- { +- fprintf (f, " array index:"); +- s->array_index->dump (f, s->conds); +- } + fprintf (f, " calls:\n"); + dump_ipa_call_summary (f, 4, node, s); + fprintf (f, "\n"); +@@ -1824,27 +1804,6 @@ predicate_for_phi_result (class ipa_fn_summary *summary, gphi *phi, + nonconstant_names[SSA_NAME_VERSION (gimple_phi_result (phi))] = *p; + } + +-/* Return predicate specifying when array index in access OP becomes non-constant. */ +- +-static predicate +-array_index_predicate (ipa_fn_summary *info, +- vec< predicate> nonconstant_names, tree op) +-{ +- predicate p = false; +- while (handled_component_p (op)) +- { +- if (TREE_CODE (op) == ARRAY_REF || TREE_CODE (op) == ARRAY_RANGE_REF) +- { +- if (TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME) +- p = p.or_with (info->conds, +- nonconstant_names[SSA_NAME_VERSION +- (TREE_OPERAND (op, 1))]); +- } +- op = TREE_OPERAND (op, 0); +- } +- return p; +-} +- + /* For a typical usage of __builtin_expect (a nonconstant_names = vNULL; + int nblocks, n; + int *order; +- predicate array_index = true; + gimple *fix_builtin_expect_stmt; + + gcc_assert (my_function && my_function->cfg); +@@ -2146,26 +2104,6 @@ analyze_function_body (struct cgraph_node *node, bool early) + this_time); + } + +- if (gimple_assign_load_p (stmt) && nonconstant_names.exists ()) +- { +- predicate this_array_index; +- this_array_index = +- array_index_predicate (info, nonconstant_names, +- gimple_assign_rhs1 (stmt)); +- if (this_array_index != false) +- array_index &= this_array_index; +- } +- if (gimple_store_p (stmt) && nonconstant_names.exists ()) +- { +- predicate this_array_index; +- this_array_index = +- array_index_predicate (info, nonconstant_names, +- gimple_get_lhs (stmt)); +- if (this_array_index != false) +- array_index &= this_array_index; +- } +- +- + if (is_gimple_call (stmt) + && !gimple_call_internal_p (stmt)) + { +@@ -2273,14 +2211,40 @@ analyze_function_body (struct cgraph_node *node, bool early) + if (dump_file) + fprintf (dump_file, " fp_expression set\n"); + } ++ } + +- gcc_assert (time >= 0); +- gcc_assert (size >= 0); ++ /* Account cost of address calculations in the statements. */ ++ for (unsigned int i = 0; i < gimple_num_ops (stmt); i++) ++ { ++ for (tree op = gimple_op (stmt, i); ++ op && handled_component_p (op); ++ op = TREE_OPERAND (op, 0)) ++ if ((TREE_CODE (op) == ARRAY_REF ++ || TREE_CODE (op) == ARRAY_RANGE_REF) ++ && TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME) ++ { ++ predicate p = bb_predicate; ++ if (fbi.info) ++ p = p & will_be_nonconstant_expr_predicate ++ (&fbi, info, TREE_OPERAND (op, 1), ++ nonconstant_names); ++ if (p != false) ++ { ++ time += freq; ++ size += 1; ++ if (dump_file) ++ fprintf (dump_file, ++ "\t\tAccounting address calculation.\n"); ++ info->account_size_time (ipa_fn_summary::size_scale, ++ freq, ++ bb_predicate, ++ p); ++ } ++ } + } ++ + } + } +- set_hint_predicate (&ipa_fn_summaries->get_create (node)->array_index, +- array_index); + free (order); + + if (nonconstant_names.exists () && !early) +@@ -2783,9 +2747,6 @@ estimate_node_size_and_time (struct cgraph_node *node, + if (info->loop_stride + && !info->loop_stride->evaluate (possible_truths)) + hints |= INLINE_HINT_loop_stride; +- if (info->array_index +- && !info->array_index->evaluate (possible_truths)) +- hints |= INLINE_HINT_array_index; + if (info->scc_no) + hints |= INLINE_HINT_in_scc; + if (DECL_DECLARED_INLINE_P (node->decl)) +@@ -3106,9 +3067,6 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge) + remap_hint_predicate (info, callee_info, + &callee_info->loop_stride, + operand_map, offset_map, clause, &toplev_predicate); +- remap_hint_predicate (info, callee_info, +- &callee_info->array_index, +- operand_map, offset_map, clause, &toplev_predicate); + + ipa_call_summary *s = ipa_call_summaries->get (edge); + inline_update_callee_summaries (edge->callee, s->loop_depth); +@@ -3366,9 +3324,6 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data, + p.stream_in (&ib); + if (info) + set_hint_predicate (&info->loop_stride, p); +- p.stream_in (&ib); +- if (info) +- set_hint_predicate (&info->array_index, p); + for (e = node->callees; e; e = e->next_callee) + read_ipa_call_summary (&ib, e, info != NULL); + for (e = node->indirect_calls; e; e = e->next_callee) +@@ -3517,10 +3472,6 @@ ipa_fn_summary_write (void) + info->loop_stride->stream_out (ob); + else + streamer_write_uhwi (ob, 0); +- if (info->array_index) +- info->array_index->stream_out (ob); +- else +- streamer_write_uhwi (ob, 0); + for (edge = cnode->callees; edge; edge = edge->next_callee) + write_ipa_call_summary (ob, edge); + for (edge = cnode->indirect_calls; edge; edge = edge->next_callee) +diff -uprN a/gcc/ipa-fnsummary.h b/gcc/ipa-fnsummary.h +--- a/gcc/ipa-fnsummary.h ++++ b/gcc/ipa-fnsummary.h +@@ -48,11 +48,8 @@ enum ipa_hints_vals { + if functions are in different modules, inlining may not be so important. + Set by simple_edge_hints in ipa-inline-analysis.c. */ + INLINE_HINT_cross_module = 64, +- /* If array indexes of loads/stores become known there may be room for +- further optimization. */ +- INLINE_HINT_array_index = 128, + /* We know that the callee is hot by profile. */ +- INLINE_HINT_known_hot = 256 ++ INLINE_HINT_known_hot = 128 + }; + + typedef int ipa_hints; +@@ -97,7 +94,7 @@ public: + fp_expressions (false), estimated_stack_size (false), + stack_frame_offset (false), time (0), size (0), conds (NULL), + size_time_table (NULL), loop_iterations (NULL), loop_stride (NULL), +- array_index (NULL), growth (0), scc_no (0) ++ growth (0), scc_no (0) + { + } + +@@ -111,7 +108,7 @@ public: + stack_frame_offset (s.stack_frame_offset), time (s.time), size (s.size), + conds (s.conds), size_time_table (s.size_time_table), + loop_iterations (s.loop_iterations), loop_stride (s.loop_stride), +- array_index (s.array_index), growth (s.growth), scc_no (s.scc_no) ++ growth (s.growth), scc_no (s.scc_no) + {} + + /* Default constructor. */ +@@ -157,8 +154,6 @@ public: + /* Predicate on when some loop in the function becomes to have known + stride. */ + predicate * GTY((skip)) loop_stride; +- /* Predicate on when some array indexes become constants. */ +- predicate * GTY((skip)) array_index; + /* Estimated growth for inlining all copies of the function before start + of small functions inlining. + This value will get out of date as the callers are duplicated, but +diff -uprN a/gcc/ipa-inline.c b/gcc/ipa-inline.c +--- a/gcc/ipa-inline.c ++++ b/gcc/ipa-inline.c +@@ -807,7 +807,6 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) + || (!(hints & (INLINE_HINT_indirect_call + | INLINE_HINT_known_hot + | INLINE_HINT_loop_iterations +- | INLINE_HINT_array_index + | INLINE_HINT_loop_stride)) + && !(big_speedup = big_speedup_p (e))))) + { +@@ -833,7 +832,6 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report) + && !(hints & INLINE_HINT_known_hot) + && growth >= ((hints & (INLINE_HINT_indirect_call + | INLINE_HINT_loop_iterations +- | INLINE_HINT_array_index + | INLINE_HINT_loop_stride)) + ? MAX (MAX_INLINE_INSNS_AUTO, + MAX_INLINE_INSNS_SINGLE) +@@ -1227,7 +1225,6 @@ edge_badness (struct cgraph_edge *edge, bool dump) + badness = badness.shift (badness > 0 ? 4 : -4); + if ((hints & (INLINE_HINT_indirect_call + | INLINE_HINT_loop_iterations +- | INLINE_HINT_array_index + | INLINE_HINT_loop_stride)) + || callee_info->growth <= 0) + badness = badness.shift (badness > 0 ? -2 : 2); +diff -uprN a/gcc/params.def b/gcc/params.def +--- a/gcc/params.def ++++ b/gcc/params.def +@@ -1109,12 +1109,6 @@ DEFPARAM (PARAM_IPA_CP_LOOP_HINT_BONUS, + "bounds or strides known.", + 64, 0, 0) + +-DEFPARAM (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS, +- "ipa-cp-array-index-hint-bonus", +- "Compile-time bonus IPA-CP assigns to candidates which make an array " +- "index known.", +- 48, 0, 0) +- + DEFPARAM (PARAM_IPA_MAX_AA_STEPS, + "ipa-max-aa-steps", + "Maximum number of statements that will be visited by IPA formal " diff --git a/sanitizer-pr-85835.patch b/sanitizer-pr-85835.patch deleted file mode 100644 index 0e2558483ae3f2100dfb3fb9c04e56c50cbb945e..0000000000000000000000000000000000000000 --- a/sanitizer-pr-85835.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc -index 858bb21..de18e56 100644 (file) ---- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc -+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc -@@ -157,7 +157,6 @@ typedef struct user_fpregs elf_fpregset_t; - # include - #endif - #include --#include - #include - #include - #include -@@ -250,7 +249,19 @@ namespace __sanitizer { - #endif // SANITIZER_LINUX || SANITIZER_FREEBSD - - #if SANITIZER_LINUX && !SANITIZER_ANDROID -- unsigned struct_ustat_sz = sizeof(struct ustat); -+ // Use pre-computed size of struct ustat to avoid which -+ // has been removed from glibc 2.28. -+#if defined(__aarch64__) || defined(__s390x__) || defined (__mips64) \ -+ || defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) \ -+ || defined(__x86_64__) -+#define SIZEOF_STRUCT_USTAT 32 -+#elif defined(__arm__) || defined(__i386__) || defined(__mips__) \ -+ || defined(__powerpc__) || defined(__s390__) -+#define SIZEOF_STRUCT_USTAT 20 -+#else -+#error Unknown size of struct ustat -+#endif -+ unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT; - unsigned struct_rlimit64_sz = sizeof(struct rlimit64); - unsigned struct_statvfs64_sz = sizeof(struct statvfs64); - #endif // SANITIZER_LINUX && !SANITIZER_ANDROID diff --git a/skip-debug-insns-when-computing-inline-costs.patch b/skip-debug-insns-when-computing-inline-costs.patch new file mode 100644 index 0000000000000000000000000000000000000000..61555906b6a5a146215fde8c02d2ac5c1df382e6 --- /dev/null +++ b/skip-debug-insns-when-computing-inline-costs.patch @@ -0,0 +1,14 @@ +diff -uprN a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c +--- a/gcc/ipa-fnsummary.c ++++ b/gcc/ipa-fnsummary.c +@@ -2078,8 +2078,8 @@ analyze_function_body (struct cgraph_node *node, bool early) + + fix_builtin_expect_stmt = find_foldable_builtin_expect (bb); + +- for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi); +- gsi_next (&bsi)) ++ for (gimple_stmt_iterator bsi = gsi_start_nondebug_bb (bb); ++ !gsi_end_p (bsi); gsi_next_nondebug (&bsi)) + { + gimple *stmt = gsi_stmt (bsi); + int this_size = estimate_num_insns (stmt, &eni_size_weights); diff --git a/try-unroll.patch b/try-unroll.patch deleted file mode 100644 index 6f564f8054e00e95f0a031f785697257b6c3eac3..0000000000000000000000000000000000000000 --- a/try-unroll.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/gcc/tree-ssa-loop-ivcanon.c 2018-12-06 05:05:43.841181211 +0800 -+++ b/gcc/tree-ssa-loop-ivcanon.c 2018-12-06 05:03:17.545185153 +0800 -@@ -726,7 +726,7 @@ try_unroll_loop_completely (struct loop - edge_to_cancel = NULL; - } - -- if (!n_unroll_found) -+ if (!n_unroll_found || SCEV_NOT_KNOWN == TREE_CODE (niter)) - return false; - - if (n_unroll > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES)) diff --git a/turn-on-funwind-tables-by-default.patch b/turn-on-funwind-tables-by-default.patch deleted file mode 100644 index 878d88744e4e55e41cf6126f6aeba2b930ca65d4..0000000000000000000000000000000000000000 --- a/turn-on-funwind-tables-by-default.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff -N -urp a/gcc/common/config/aarch64/aarch64-common.c b/gcc/common/config/aarch64/aarch64-common.c ---- a/gcc/common/config/aarch64/aarch64-common.c 2019-07-02 09:28:49.798701181 +0800 -+++ b/gcc/common/config/aarch64/aarch64-common.c 2019-07-02 09:30:15.436282799 +0800 -@@ -51,6 +51,10 @@ static const struct default_options aarc - { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, - /* Enable redundant extension instructions removal at -O2 and higher. */ - { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 }, -+#if (TARGET_DEFAULT_ASYNC_UNWIND_TABLES == 1) -+ { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 }, -+ { OPT_LEVELS_ALL, OPT_funwind_tables, NULL, 1}, -+#endif - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - -diff -N -urp a/gcc/config.gcc b/gcc/config.gcc ---- a/gcc/config.gcc 2019-07-02 09:28:50.114701170 +0800 -+++ b/gcc/config.gcc 2019-07-02 09:31:50.636196118 +0800 -@@ -966,6 +966,7 @@ aarch64*-*-linux*) - tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h" - tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-linux.h" - tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-linux" -+ tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1" - case $target in - aarch64_be-*) - tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"