aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2023-02-12 16:20:58 +0100
committerThomas Schwinge <thomas@codesourcery.com>2023-02-12 16:20:58 +0100
commit81007c525482143fdee017545ac44438b37da0e6 (patch)
treeeb3910b6002d21d3652fd7b706f05da75432d93c /gcc
parent3a8c8d0d41b57fbb49ab39715b70495d5d1e8dd1 (diff)
parente165214777acfe5621ad36e55b16e098d50e1596 (diff)
downloadgcc-81007c525482143fdee017545ac44438b37da0e6.zip
gcc-81007c525482143fdee017545ac44438b37da0e6.tar.gz
gcc-81007c525482143fdee017545ac44438b37da0e6.tar.bz2
Merge commit '95dc11475dac06b5eecd904079de8aa94827a36a^' into HEAD
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog207
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/config/aarch64/aarch64.md2
-rw-r--r--gcc/config/i386/i386.md47
-rw-r--r--gcc/doc/invoke.texi13
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/parse.cc2
-rw-r--r--gcc/ipa-cp.cc25
-rw-r--r--gcc/ipa-param-manipulation.cc153
-rw-r--r--gcc/ipa-param-manipulation.h19
-rw-r--r--gcc/ipa-prop.cc209
-rw-r--r--gcc/ipa-sra.cc695
-rw-r--r--gcc/jit/jit-recording.h9
-rw-r--r--gcc/lto-cgraph.cc2
-rw-r--r--gcc/lto-streamer-out.cc3
-rw-r--r--gcc/params.opt10
-rw-r--r--gcc/rust/ChangeLog391
-rw-r--r--gcc/testsuite/ChangeLog763
-rw-r--r--gcc/testsuite/g++.dg/ipa/ipa-sra-5.C23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr108064.c28
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c17
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-26.c31
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-27.c49
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-28.c51
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr107640-2.c50
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-43.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/pr108044-1.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/pr108044-2.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/pr108044-3.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/pr108044-4.c21
-rw-r--r--gcc/testsuite/gfortran.dg/ipa-sra-1.f9037
-rw-r--r--gcc/testsuite/gfortran.dg/pr107423.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/pr48636-2.f902
-rw-r--r--gcc/testsuite/jit.dg/test-vector-types.cc13
-rw-r--r--gcc/tree-inline.cc2
-rw-r--r--gcc/tree-ssa-ccp.cc4
-rw-r--r--gcc/tree-ssa-sccvn.cc25
-rw-r--r--gcc/tree-vect-patterns.cc10
38 files changed, 2665 insertions, 373 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 547b067..46b85d5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,210 @@
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-param-manipulation.cc
+ (ipa_param_body_adjustments::modify_expression): Bail out early if
+ there are no replacements.
+ (ipa_param_body_adjustments::modify_assignment): Likewise.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-sra.cc (isra_param_desc): New fields safe_size,
+ conditionally_dereferenceable and safe_size_set.
+ (struct gensum_param_desc): New field conditionally_dereferenceable.
+ (struct isra_param_flow): Updated comment of field unit_size.
+ (ipa_sra_function_summaries::duplicate): Copy the new fields.
+ (isra_call_summary::dump): Dump unit_size when representing safe_size.
+ (dump_gensum_param_descriptor): Dump new flag.
+ (dump_isra_param_descriptor): Dump new fields.
+ (isra_analyze_call): Fill unit_size when it represents known safe
+ size.
+ (check_gensum_access): Instead of disqualifying pointers which are not
+ always dereference, mark them as conditionally dereferencable if loads
+ are frequent enough.
+ (process_scan_results): Copy the conditionally_dereferenceable flag.
+ (isra_write_node_summary): Stream new fields, or assert they are not
+ initialized yet.
+ (isra_read_node_info): Stream new fields.
+ (update_safe_size): New function.
+ (propagate_param_hints_accross_call): Propagate safe_sizes.
+ (propagate_hints_to_all_callees): New function.
+ (adjust_parameter_descriptions): Check conditionally_dereferenceable
+ candidates, rework dumping.
+ (ipa_sra_analysis): Move most of hint propagation for one node to
+ propagate_hints_to_all_callees. Add another loop to stabilize within
+ SCCs and another one to verify.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-sra.cc (isra_param_desc): New field not_specially_constructed.
+ (struct isra_param_flow): New field constructed_for_calls.
+ (isra_call_summary::dump): Dump the new flag.
+ (loaded_decls): New variable.
+ (dump_isra_param_descriptor): New parameter hints, dump
+ not_specially_constructed if it is true.
+ (dump_isra_param_descriptors): New parameter hints, pass it to
+ dump_isra_param_descriptor.
+ (ipa_sra_function_summaries::duplicate): Duplicate new flag.
+ (create_parameter_descriptors): Adjust comment.
+ (get_gensum_param_desc): Bail out when decl2desc is NULL.
+ (scan_expr_access): Add loaded local variables to loaded_decls.
+ (scan_function): Survive if final_bbs is NULL.
+ (isra_analyze_call): Compute constructed_for_calls flag.
+ (process_scan_results): Be optimistic about size limits. Do not dump
+ computed param hints when dumpint IPA-SRA structures.
+ (isra_write_edge_summary): Stream constructed_for_calls.
+ (isra_read_edge_summary): Likewise.
+ (ipa_sra_dump_all_summaries): New parameter hints, pass it to
+ dump_isra_param_descriptor.
+ (flip_all_hints_pessimistic): New function.
+ (flip_all_param_hints_pessimistic): Likewise.
+ (propagate_param_hints): Likewise.
+ (disable_unavailable_parameters): Renamed to
+ adjust_parameter_descriptions. Expand size limits for parameters
+ which are specially contstructed by all callers. Check limits again.p
+ (ipa_sra_analysis): Pass required hints to ipa_sra_dump_all_summaries.
+ Add hint propagation.
+ (ipa_sra_summarize_function): Initialize and destory loaded_decls,
+ rearrange so that scan_function is called even when there are no
+ candidates.
+ * params.opt (ipa-sra-ptrwrap-growth-factor): New parameter.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-sra.cc (ipa_sra_analysis): Move top-down analysis before
+ bottom-up analysis. Replace FOR_EACH_VEC_ELT with C++11 iteration.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/103585
+ * params.opt (ipa-sra-deref-prob-threshold): New parameter.
+ * doc/invoke.texi (ipa-sra-deref-prob-threshold): Document it.
+ * ipa-sra.cc (struct gensum_param_access): New field load_count.
+ (struct gensum_param_desc): New field safe_ref, adjusted comments.
+ (by_ref_count): Renamed to unsafe_by_ref_count, adjusted all uses.
+ (dump_gensum_access): Dump the new field.
+ (dump_gensum_param_descriptor): Likewise.
+ (create_parameter_descriptors): Set safe_ref field, move setting
+ by_ref forward. Only increment unsafe_by_ref_count for unsafe
+ by_ref parameters.
+ (allocate_access): Initialize new field.
+ (mark_param_dereference): Adjust indentation. Only add data to
+ bb_dereferences for unsafe by_ref parameters.
+ (scan_expr_access): For loads, accumulate BB counts.
+ (dereference_probable_p): New function.
+ (check_gensum_access): Fix leading comment, add parameter FUN.
+ Check cumulative counts of loads for safe by_ref accesses instead
+ of dereferences.
+ (process_scan_results): Do not propagate dereference distances for
+ safe by_ref parameters. Pass fun to check_gensum_access. Safe
+ by_ref params do not need the postdominance check.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.cc (clone_for_param_removal_p): New function.
+ (estimate_local_effects): Call it before considering cloning
+ just to remove unused parameters.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/103227
+ * ipa-param-manipulation.h (class ipa_param_adjustments): Removed
+ member function get_updated_index_or_split.
+ (class ipa_param_body_adjustments): New overload of
+ register_replacement, new member function append_init_stmts, new
+ member m_split_agg_csts_inits.
+ * ipa-param-manipulation.cc: Include ipa-prop.h.
+ (ipa_param_adjustments::get_updated_index_or_split): Removed.
+ (ipa_param_body_adjustments::register_replacement): New overload, use
+ it from the older one.
+ (ipa_param_body_adjustments::common_initialization): Added the
+ capability to create replacements for conflicting IPA-CP discovered
+ constants.
+ (ipa_param_body_adjustments::ipa_param_body_adjustments): Construct
+ the new member.
+ (ipa_param_body_adjustments::append_init_stmts): New function.
+ * ipa-sra.cc: Include ipa-prop.h.
+ (push_param_adjustments_for_index): Require IPA-CP transformation
+ summary as a parameter, do not create replacements which are known to
+ have constant values.
+ (process_isra_node_results): Find and pass to the above function the
+ IPA-CP transformation summary.
+ * ipa-prop.cc (adjust_agg_replacement_values): Remove the
+ functionality replacing IPA-SRA created scalar parameters with
+ constants. Simplify, do not require parameter descriptors, do not
+ return anything.
+ (ipcp_transform_function): Simplify now that
+ adjust_agg_replacement_values does not change cfg. Move definition
+ and initialization of descriptors lower.
+ * tree-inline.cc (tree_function_versioning): Call append_init_stmts of
+ param_body_adjs, if there are any.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-prop.cc (useful_ipcp_transformation_info_p): New function.
+ (write_ipcp_transformation_info): Added a parameter, simplified
+ given that is known not to be NULL.
+ (ipcp_write_transformation_summaries): Write out all useful
+ transformation summaries.
+ (read_ipcp_transformation_info): Simplify given that some info
+ will be read.
+ (read_replacements_section): Remove assert.
+ * lto-cgraph.cc (add_node_to): Also set encode_body for clones.
+ * lto-streamer-out.cc (lto_output): Do not output virtual clones.
+
+2022-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/108044
+ * config/i386/i386.md (*concat<half><mode>3_5, *concat<mode><dwi>3_6,
+ *concat<mode><dwi>3_7): Split alternative with =ro output constraint
+ into =r,o,o and use Wd input constraint for the last alternative which
+ is enabled for TARGET_64BIT. Reject ix86_endbr_immediate_operand
+ in the input constant.
+
+2022-12-13 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64.md (tbranch_<code><mode>3): Use gen_int_mode.
+
+2022-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/108064
+ * tree-vect-patterns.cc (vect_recog_rotate_pattern): Pass uvectype
+ as 4th argument to append_pattern_def_seq for statements with lhs
+ with utype type.
+
+2022-12-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/105801
+ * tree-ssa-ccp.cc (likely_value): .DEFERRED_INIT produces
+ UNDEFINED.
+ * doc/invoke.texi (ftrivial-auto-var-init): Explicitely
+ mention we treat variables without an initializer as
+ undefined also for optimization purposes.
+
+2022-12-13 Tom Tromey <tom@tromey.com>
+ Mark Wielaard <mark@klomp.org>
+ Marc Poulhiès <dkm@kataplop.net>
+
+ * dwarf2out.cc (is_rust): New.
+ (base_type_die): Use DW_ATE_UTF for the Rust 'char' type.
+ (gen_compile_unit_die): Handle "GNU Rust".
+
+2022-12-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/108076
+ * tree-if-conv.cc (if_convertible_loop_p_1): Reject blocks
+ with non-local or forced labels that we later remove
+ labels from.
+
+2022-12-13 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * config/rs6000/rs6000.md (cbranchcc4): New expander.
+
+2022-12-13 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * optabs.cc (prepare_cmp_insn): Return a NULL rtx other than
+ assertion failure when targets don't have cbranch optab or
+ predicate check fails.
+
2022-12-12 Wilco Dijkstra <wilco.dijkstra@arm.com>
* config/aarch64/aarch64.cc (aarch64_rtx_costs): Add correct costs
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 349ad3e..fb5d5da 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20221213
+20221214
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index d749c98..6c27fb8 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -957,7 +957,7 @@
{
rtx bitvalue = gen_reg_rtx (<ZEROM>mode);
rtx reg = gen_lowpart (<ZEROM>mode, operands[0]);
- rtx val = GEN_INT (1UL << UINTVAL (operands[1]));
+ rtx val = gen_int_mode (HOST_WIDE_INT_1U << UINTVAL (operands[1]), <MODE>mode);
emit_insn (gen_and<zerom>3 (bitvalue, reg, val));
operands[1] = const0_rtx;
operands[0] = aarch64_gen_compare_reg (<CODE>, bitvalue,
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 04a5d63..0626752 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -11470,11 +11470,11 @@
})
(define_insn_and_split "*concat<half><mode>3_5"
- [(set (match_operand:DWI 0 "nonimmediate_operand" "=ro")
+ [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
(any_or_plus:DWI
- (ashift:DWI (match_operand:DWI 1 "register_operand" "r")
+ (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
(match_operand:DWI 2 "const_int_operand"))
- (match_operand:DWI 3 "const_scalar_int_operand")))]
+ (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
"INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
&& (<MODE>mode == DImode
? CONST_INT_P (operands[3])
@@ -11482,7 +11482,12 @@
: CONST_INT_P (operands[3])
? INTVAL (operands[3]) >= 0
: CONST_WIDE_INT_NUNITS (operands[3]) == 2
- && CONST_WIDE_INT_ELT (operands[3], 1) == 0)"
+ && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
+ && !(CONST_INT_P (operands[3])
+ ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
+ : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
+ 0)),
+ VOIDmode))"
"#"
"&& reload_completed"
[(clobber (const_int 0))]
@@ -11491,16 +11496,17 @@
split_double_concat (<MODE>mode, operands[0], op3,
gen_lowpart (<HALF>mode, operands[1]));
DONE;
-})
+}
+ [(set_attr "isa" "*,nox64,x64")])
(define_insn_and_split "*concat<mode><dwi>3_6"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
(any_or_plus:<DWI>
(ashift:<DWI>
(zero_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
+ (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
(match_operand:<DWI> 2 "const_int_operand"))
- (match_operand:<DWI> 3 "const_scalar_int_operand")))]
+ (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
"INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
&& (<DWI>mode == DImode
? CONST_INT_P (operands[3])
@@ -11508,7 +11514,12 @@
: CONST_INT_P (operands[3])
? INTVAL (operands[3]) >= 0
: CONST_WIDE_INT_NUNITS (operands[3]) == 2
- && CONST_WIDE_INT_ELT (operands[3], 1) == 0)"
+ && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
+ && !(CONST_INT_P (operands[3])
+ ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
+ : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
+ 0)),
+ VOIDmode))"
"#"
"&& reload_completed"
[(clobber (const_int 0))]
@@ -11516,20 +11527,25 @@
rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
DONE;
-})
+}
+ [(set_attr "isa" "*,nox64,x64,*")])
(define_insn_and_split "*concat<mode><dwi>3_7"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
(any_or_plus:<DWI>
(zero_extend:<DWI>
- (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
- (match_operand:<DWI> 2 "const_scalar_int_operand")))]
+ (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
+ (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
"<DWI>mode == DImode
? CONST_INT_P (operands[2])
&& (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
+ && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
: CONST_WIDE_INT_P (operands[2])
&& CONST_WIDE_INT_NUNITS (operands[2]) == 2
- && CONST_WIDE_INT_ELT (operands[2], 0) == 0"
+ && CONST_WIDE_INT_ELT (operands[2], 0) == 0
+ && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
+ 1)),
+ VOIDmode)"
"#"
"&& reload_completed"
[(clobber (const_int 0))]
@@ -11541,7 +11557,8 @@
op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
split_double_concat (<DWI>mode, operands[0], operands[1], op2);
DONE;
-})
+}
+ [(set_attr "isa" "*,nox64,x64,*")])
;; Negation instructions
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index cb40b38..7dc1d45e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13208,7 +13208,8 @@ disclosure and use.
GCC still considers an automatic variable that doesn't have an explicit
initializer as uninitialized, @option{-Wuninitialized} and
@option{-Wanalyzer-use-of-uninitialized-value} will still report
-warning messages on such automatic variables.
+warning messages on such automatic variables and the compiler will
+perform optimization as if the variable were uninitialized.
With this option, GCC will also initialize any padding of automatic variables
that have structure or union types to zeroes.
However, the current implementation cannot initialize automatic variables that
@@ -15508,12 +15509,22 @@ the parameter is reserved exclusively for debug insns created by
@option{-fvar-tracking-assignments}, but debug insns may get
(non-overlapping) uids above it if the reserved range is exhausted.
+@item ipa-sra-deref-prob-threshold
+IPA-SRA replaces a pointer which is known not be NULL with one or more
+new parameters only when the probability (in percent, relative to
+function entry) of it being dereferenced is higher than this parameter.
+
@item ipa-sra-ptr-growth-factor
IPA-SRA replaces a pointer to an aggregate with one or more new
parameters only when their cumulative size is less or equal to
@option{ipa-sra-ptr-growth-factor} times the size of the original
pointer parameter.
+@item ipa-sra-ptrwrap-growth-factor
+Additional maximum allowed growth of total size of new parameters
+that ipa-sra replaces a pointer to an aggregate with,
+if it points to a local variable that the caller never writes to.
+
@item ipa-sra-max-replacements
Maximum pieces of an aggregate that IPA-SRA tracks. As a
consequence, it is also the maximum number of replacements of a formal
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 4535398..cbb0ecf 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2022-12-13 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107423
+ * parse.cc (parse_spec): Avoid NULL pointer dereference when parsing
+ a function and an error occured.
+
2022-12-12 Harald Anlauf <anlauf@gmx.de>
PR fortran/102180
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index cdae43f..bc2b218 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -4015,7 +4015,7 @@ parse_spec (gfc_statement st)
gfc_symbol* proc = gfc_current_ns->proc_name;
gcc_assert (proc);
- if (proc->result->ts.type == BT_UNKNOWN)
+ if (proc->result && proc->result->ts.type == BT_UNKNOWN)
function_result_typed = true;
}
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index cc031eb..300bec5 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -3700,6 +3700,29 @@ get_max_overall_size (cgraph_node *node)
return max_new_size;
}
+/* Return true if NODE should be cloned just for a parameter removal, possibly
+ dumping a reason if not. */
+
+static bool
+clone_for_param_removal_p (cgraph_node *node)
+{
+ if (!node->can_change_signature)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Not considering cloning to remove parameters, "
+ "function cannot change signature.\n");
+ return false;
+ }
+ if (node->can_be_local_p ())
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Not considering cloning to remove parameters, "
+ "IPA-SRA can do it potentially better.\n");
+ return false;
+ }
+ return true;
+}
+
/* Iterate over known values of parameters of NODE and estimate the local
effects in terms of time and size they have. */
@@ -3722,7 +3745,7 @@ estimate_local_effects (struct cgraph_node *node)
&removable_params_cost);
int devirt_bonus = devirtualization_time_bonus (node, &avals);
if (always_const || devirt_bonus
- || (removable_params_cost && node->can_change_signature))
+ || (removable_params_cost && clone_for_param_removal_p (node)))
{
struct caller_statistics stats;
ipa_call_estimates estimates;
diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc
index cee0e23..da19d64 100644
--- a/gcc/ipa-param-manipulation.cc
+++ b/gcc/ipa-param-manipulation.cc
@@ -46,7 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-phinodes.h"
#include "cfgexpand.h"
#include "attribs.h"
-
+#include "ipa-prop.h"
/* Actual prefixes of different newly synthetized parameters. Keep in sync
with IPA_PARAM_PREFIX_* defines. */
@@ -449,39 +449,6 @@ ipa_param_adjustments::get_updated_indices (vec<int> *new_indices)
}
}
-/* If a parameter with original INDEX has survived intact, return its new
- index. Otherwise return -1. In that case, if it has been split and there
- is a new parameter representing a portion at unit OFFSET for which a value
- of a TYPE can be substituted, store its new index into SPLIT_INDEX,
- otherwise store -1 there. */
-int
-ipa_param_adjustments::get_updated_index_or_split (int index,
- unsigned unit_offset,
- tree type, int *split_index)
-{
- unsigned adj_len = vec_safe_length (m_adj_params);
- for (unsigned i = 0; i < adj_len ; i++)
- {
- ipa_adjusted_param *apm = &(*m_adj_params)[i];
- if (apm->base_index != index)
- continue;
- if (apm->op == IPA_PARAM_OP_COPY)
- return i;
- if (apm->op == IPA_PARAM_OP_SPLIT
- && apm->unit_offset == unit_offset)
- {
- if (useless_type_conversion_p (apm->type, type))
- *split_index = i;
- else
- *split_index = -1;
- return -1;
- }
- }
-
- *split_index = -1;
- return -1;
-}
-
/* Return the original index for the given new parameter index. Return a
negative number if not available. */
@@ -1020,6 +987,21 @@ ipa_param_adjustments::debug ()
dump (stderr);
}
+/* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */
+
+void
+ipa_param_body_adjustments::register_replacement (tree base,
+ unsigned unit_offset,
+ tree replacement)
+{
+ ipa_param_body_replacement psr;
+ psr.base = base;
+ psr.repl = replacement;
+ psr.dummy = NULL_TREE;
+ psr.unit_offset = unit_offset;
+ m_replacements.safe_push (psr);
+}
+
/* Register that REPLACEMENT should replace parameter described in APM. */
void
@@ -1029,12 +1011,8 @@ ipa_param_body_adjustments::register_replacement (ipa_adjusted_param *apm,
gcc_checking_assert (apm->op == IPA_PARAM_OP_SPLIT
|| apm->op == IPA_PARAM_OP_NEW);
gcc_checking_assert (!apm->prev_clone_adjustment);
- ipa_param_body_replacement psr;
- psr.base = m_oparms[apm->prev_clone_index];
- psr.repl = replacement;
- psr.dummy = NULL_TREE;
- psr.unit_offset = apm->unit_offset;
- m_replacements.safe_push (psr);
+ register_replacement (m_oparms[apm->prev_clone_index], apm->unit_offset,
+ replacement);
}
/* Copy or not, as appropriate given m_id and decl context, a pre-existing
@@ -1386,23 +1364,73 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl,
gcc_unreachable ();
}
- if (tree_map)
+ auto_vec <int, 16> index_mapping;
+ bool need_remap = false;
+ if (m_id)
{
- /* Do not treat parameters which were replaced with a constant as
- completely vanished. */
- auto_vec <int, 16> index_mapping;
- bool need_remap = false;
+ clone_info *cinfo = clone_info::get (m_id->src_node);
+ if (cinfo && cinfo->param_adjustments)
+ {
+ cinfo->param_adjustments->get_updated_indices (&index_mapping);
+ need_remap = true;
+ }
- if (m_id)
+ if (ipcp_transformation *ipcp_ts
+ = ipcp_get_transformation_summary (m_id->src_node))
{
- clone_info *cinfo = clone_info::get (m_id->src_node);
- if (cinfo && cinfo->param_adjustments)
+ for (const ipa_argagg_value &av : ipcp_ts->m_agg_values)
{
- cinfo->param_adjustments->get_updated_indices (&index_mapping);
- need_remap = true;
+ int parm_num = av.index;
+
+ if (need_remap)
+ {
+ /* FIXME: We cannot handle the situation when IPA-CP
+ identified that a parameter is a pointer to a global
+ variable and at the same time the variable has some known
+ constant contents (PR 107640). The best place to make
+ sure we don't drop such constants on the floor probably is
+ not here, but we have to make sure that it does not
+ confuse the remapping. */
+ if (parm_num >= (int) index_mapping.length ())
+ continue;
+ parm_num = index_mapping[parm_num];
+ if (parm_num < 0)
+ continue;
+ }
+
+ if (!kept[parm_num])
+ {
+ /* IPA-CP has detected an aggregate constant in a parameter
+ that will not be kept, which means that IPA-SRA would have
+ split it if there wasn't a constant. Because we are about
+ to remove the original, this is the last chance where we
+ can substitute the uses with a constant (for values passed
+ by reference) or do the split but initialize the
+ replacement with a constant (for split aggregates passed
+ by value). */
+
+ tree repl;
+ if (av.by_ref)
+ repl = av.value;
+ else
+ {
+ repl = create_tmp_var (TREE_TYPE (av.value),
+ "removed_ipa_cp");
+ gimple *init_stmt = gimple_build_assign (repl, av.value);
+ m_split_agg_csts_inits.safe_push (init_stmt);
+ }
+ register_replacement (m_oparms[parm_num], av.unit_offset,
+ repl);
+ split[parm_num] = true;
+ }
}
}
+ }
+ if (tree_map)
+ {
+ /* Do not treat parameters which were replaced with a constant as
+ completely vanished. */
for (unsigned i = 0; i < tree_map->length (); i++)
{
int parm_num = (*tree_map)[i]->parm_num;
@@ -1473,8 +1501,9 @@ ipa_param_body_adjustments
: m_adj_params (adj_params), m_adjustments (NULL), m_reset_debug_decls (),
m_dead_stmts (), m_dead_ssas (), m_dead_ssa_debug_equiv (),
m_dead_stmt_debug_equiv (), m_fndecl (fndecl), m_id (NULL), m_oparms (),
- m_new_decls (), m_new_types (), m_replacements (), m_removed_decls (),
- m_removed_map (), m_method2func (false)
+ m_new_decls (), m_new_types (), m_replacements (),
+ m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
+ m_method2func (false)
{
common_initialization (fndecl, NULL, NULL);
}
@@ -1491,7 +1520,8 @@ ipa_param_body_adjustments
m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
m_id (NULL), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
- m_removed_decls (), m_removed_map (), m_method2func (false)
+ m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
+ m_method2func (false)
{
common_initialization (fndecl, NULL, NULL);
}
@@ -1514,7 +1544,8 @@ ipa_param_body_adjustments
m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
m_id (id), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
- m_removed_decls (), m_removed_map (), m_method2func (false)
+ m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
+ m_method2func (false)
{
common_initialization (old_fndecl, vars, tree_map);
}
@@ -1731,6 +1762,8 @@ ipa_param_body_adjustments::modify_expression (tree *expr_p, bool convert)
{
tree expr = *expr_p;
+ if (m_replacements.is_empty ())
+ return false;
if (TREE_CODE (expr) == BIT_FIELD_REF
|| TREE_CODE (expr) == IMAGPART_EXPR
|| TREE_CODE (expr) == REALPART_EXPR)
@@ -1778,7 +1811,7 @@ ipa_param_body_adjustments::modify_assignment (gimple *stmt,
tree *lhs_p, *rhs_p;
bool any;
- if (!gimple_assign_single_p (stmt))
+ if (m_replacements.is_empty () || !gimple_assign_single_p (stmt))
return false;
rhs_p = gimple_assign_rhs1_ptr (stmt);
@@ -2383,6 +2416,16 @@ ipa_param_body_adjustments::perform_cfun_body_modifications ()
}
+/* If there are any initialization statements that need to be emitted into
+ the basic block BB right at ther start of the new function, do so. */
+void
+ipa_param_body_adjustments::append_init_stmts (basic_block bb)
+{
+ gimple_stmt_iterator si = gsi_last_bb (bb);
+ while (!m_split_agg_csts_inits.is_empty ())
+ gsi_insert_after (&si, m_split_agg_csts_inits.pop (), GSI_NEW_STMT);
+}
+
/* Deallocate summaries which otherwise stay alive until the end of
compilation. */
diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h
index e5654f4..e20d349 100644
--- a/gcc/ipa-param-manipulation.h
+++ b/gcc/ipa-param-manipulation.h
@@ -236,13 +236,6 @@ public:
void get_surviving_params (vec<bool> *surviving_params);
/* Fill a vector with new indices of surviving original parameters. */
void get_updated_indices (vec<int> *new_indices);
- /* If a parameter with original INDEX has survived intact, return its new
- index. Otherwise return -1. In that case, if it has been split and there
- is a new parameter representing a portion at UNIT_OFFSET for which a value
- of a TYPE can be substituted, store its new index into SPLIT_INDEX,
- otherwise store -1 there. */
- int get_updated_index_or_split (int index, unsigned unit_offset, tree type,
- int *split_index);
/* Return the original index for the given new parameter index. Return a
negative number if not available. */
int get_original_index (int newidx);
@@ -321,6 +314,8 @@ public:
/* Change the PARM_DECLs. */
void modify_formal_parameters ();
+ /* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */
+ void register_replacement (tree base, unsigned unit_offset, tree replacement);
/* Register a replacement decl for the transformation done in APM. */
void register_replacement (ipa_adjusted_param *apm, tree replacement);
/* Lookup a replacement for a given offset within a given parameter. */
@@ -340,6 +335,10 @@ public:
they are mapped to. */
void remap_with_debug_expressions (tree *t);
+ /* If there are any initialization statements that need to be emitted into
+ the basic block BB right at ther start of the new function, do so. */
+ void append_init_stmts (basic_block bb);
+
/* Pointers to data structures defining how the function should be
modified. */
vec<ipa_adjusted_param, va_gc> *m_adj_params;
@@ -405,6 +404,12 @@ private:
auto_vec<ipa_param_body_replacement, 16> m_replacements;
+ /* List of initialization assignments to be put at the beginning of the
+ cloned function to deal with split aggregates which however have known
+ constant value and so their PARM_DECL disappears. */
+
+ auto_vec<gimple *, 8> m_split_agg_csts_inits;
+
/* Vector for remapping SSA_BASES from old parameter declarations that are
being removed as a part of the transformation. Before a new VAR_DECL is
created, it holds the old PARM_DECL, once the variable is built it is
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index e6cf255..08c7f97 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -5279,80 +5279,72 @@ ipa_prop_read_jump_functions (void)
}
}
-void
-write_ipcp_transformation_info (output_block *ob, cgraph_node *node)
+/* Return true if the IPA-CP transformation summary TS is non-NULL and contains
+ useful info. */
+static bool
+useful_ipcp_transformation_info_p (ipcp_transformation *ts)
{
- int node_ref;
- unsigned int count = 0;
- lto_symtab_encoder_t encoder;
+ if (!ts)
+ return false;
+ if (!vec_safe_is_empty (ts->m_agg_values)
+ || !vec_safe_is_empty (ts->bits)
+ || !vec_safe_is_empty (ts->m_vr))
+ return true;
+ return false;
+}
- encoder = ob->decl_state->symtab_node_encoder;
- node_ref = lto_symtab_encoder_encode (encoder, node);
+/* Write into OB IPA-CP transfromation summary TS describing NODE. */
+
+void
+write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
+ ipcp_transformation *ts)
+{
+ lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
+ int node_ref = lto_symtab_encoder_encode (encoder, node);
streamer_write_uhwi (ob, node_ref);
- ipcp_transformation *ts = ipcp_get_transformation_summary (node);
- if (ts && !vec_safe_is_empty (ts->m_agg_values))
+ streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
+ for (const ipa_argagg_value &av : ts->m_agg_values)
{
- streamer_write_uhwi (ob, ts->m_agg_values->length ());
- for (const ipa_argagg_value &av : ts->m_agg_values)
- {
- struct bitpack_d bp;
+ struct bitpack_d bp;
- stream_write_tree (ob, av.value, true);
- streamer_write_uhwi (ob, av.unit_offset);
- streamer_write_uhwi (ob, av.index);
+ stream_write_tree (ob, av.value, true);
+ streamer_write_uhwi (ob, av.unit_offset);
+ streamer_write_uhwi (ob, av.index);
- bp = bitpack_create (ob->main_stream);
- bp_pack_value (&bp, av.by_ref, 1);
- streamer_write_bitpack (&bp);
- }
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, av.by_ref, 1);
+ streamer_write_bitpack (&bp);
}
- else
- streamer_write_uhwi (ob, 0);
- if (ts && vec_safe_length (ts->m_vr) > 0)
+ streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
+ for (const ipa_vr &parm_vr : ts->m_vr)
{
- count = ts->m_vr->length ();
- streamer_write_uhwi (ob, count);
- for (unsigned i = 0; i < count; ++i)
+ struct bitpack_d bp;
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, parm_vr.known, 1);
+ streamer_write_bitpack (&bp);
+ if (parm_vr.known)
{
- struct bitpack_d bp;
- ipa_vr *parm_vr = &(*ts->m_vr)[i];
- bp = bitpack_create (ob->main_stream);
- bp_pack_value (&bp, parm_vr->known, 1);
- streamer_write_bitpack (&bp);
- if (parm_vr->known)
- {
- streamer_write_enum (ob->main_stream, value_rang_type,
- VR_LAST, parm_vr->type);
- streamer_write_wide_int (ob, parm_vr->min);
- streamer_write_wide_int (ob, parm_vr->max);
- }
+ streamer_write_enum (ob->main_stream, value_rang_type,
+ VR_LAST, parm_vr.type);
+ streamer_write_wide_int (ob, parm_vr.min);
+ streamer_write_wide_int (ob, parm_vr.max);
}
}
- else
- streamer_write_uhwi (ob, 0);
- if (ts && vec_safe_length (ts->bits) > 0)
+ streamer_write_uhwi (ob, vec_safe_length (ts->bits));
+ for (const ipa_bits *bits_jfunc : ts->bits)
{
- count = ts->bits->length ();
- streamer_write_uhwi (ob, count);
-
- for (unsigned i = 0; i < count; ++i)
+ struct bitpack_d bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, !!bits_jfunc, 1);
+ streamer_write_bitpack (&bp);
+ if (bits_jfunc)
{
- const ipa_bits *bits_jfunc = (*ts->bits)[i];
- struct bitpack_d bp = bitpack_create (ob->main_stream);
- bp_pack_value (&bp, !!bits_jfunc, 1);
- streamer_write_bitpack (&bp);
- if (bits_jfunc)
- {
- streamer_write_widest_int (ob, bits_jfunc->value);
- streamer_write_widest_int (ob, bits_jfunc->mask);
- }
+ streamer_write_widest_int (ob, bits_jfunc->value);
+ streamer_write_widest_int (ob, bits_jfunc->mask);
}
}
- else
- streamer_write_uhwi (ob, 0);
}
/* Stream in the aggregate value replacement chain for NODE from IB. */
@@ -5362,12 +5354,12 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
data_in *data_in)
{
unsigned int count, i;
+ ipcp_transformation_initialize ();
+ ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
count = streamer_read_uhwi (ib);
if (count > 0)
{
- ipcp_transformation_initialize ();
- ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
vec_safe_grow_cleared (ts->m_agg_values, count, true);
for (i = 0; i <count; i++)
{
@@ -5385,8 +5377,6 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
count = streamer_read_uhwi (ib);
if (count > 0)
{
- ipcp_transformation_initialize ();
- ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
vec_safe_grow_cleared (ts->m_vr, count, true);
for (i = 0; i < count; i++)
{
@@ -5407,10 +5397,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
count = streamer_read_uhwi (ib);
if (count > 0)
{
- ipcp_transformation_initialize ();
- ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
vec_safe_grow_cleared (ts->bits, count, true);
-
for (i = 0; i < count; i++)
{
struct bitpack_d bp = streamer_read_bitpack (ib);
@@ -5432,31 +5419,38 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
void
ipcp_write_transformation_summaries (void)
{
- struct cgraph_node *node;
struct output_block *ob;
unsigned int count = 0;
- lto_symtab_encoder_iterator lsei;
lto_symtab_encoder_t encoder;
ob = create_output_block (LTO_section_ipcp_transform);
encoder = ob->decl_state->symtab_node_encoder;
ob->symbol = NULL;
- for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
- lsei_next_function_in_partition (&lsei))
+
+ for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- node = lsei_cgraph_node (lsei);
- if (node->has_gimple_body_p ())
+ symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ if (!cnode)
+ continue;
+ ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
+ if (useful_ipcp_transformation_info_p (ts)
+ && lto_symtab_encoder_encode_body_p (encoder, cnode))
count++;
}
streamer_write_uhwi (ob, count);
- for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
- lsei_next_function_in_partition (&lsei))
+ for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- node = lsei_cgraph_node (lsei);
- if (node->has_gimple_body_p ())
- write_ipcp_transformation_info (ob, node);
+ symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ if (!cnode)
+ continue;
+ ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
+ if (useful_ipcp_transformation_info_p (ts)
+ && lto_symtab_encoder_encode_body_p (encoder, cnode))
+ write_ipcp_transformation_info (ob, cnode, ts);
}
streamer_write_char_stream (ob->main_stream, 0);
produce_asm (ob, NULL);
@@ -5497,7 +5491,6 @@ read_replacements_section (struct lto_file_decl_data *file_data,
encoder = file_data->symtab_node_encoder;
node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
index));
- gcc_assert (node->definition);
read_ipcp_transformation_info (&ib_main, node, data_in);
}
lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
@@ -5525,29 +5518,21 @@ ipcp_read_transformation_summaries (void)
}
}
-/* Adjust the aggregate replacements in TS to reflect parameters skipped in
- NODE but also if any parameter was IPA-SRAed into a scalar go ahead with
- substitution of the default_definitions of that new param with the
- appropriate constant.
+/* Adjust the aggregate replacements in TS to reflect any parameter removals
+ which might have already taken place. If after adjustments there are no
+ aggregate replacements left, the m_agg_values will be set to NULL. In other
+ cases, it may be shrunk. */
- If after adjustments there are no aggregate replacements left, the
- m_agg_values will be set to NULL. In other cases, it may be shrunk.
-
- Return true if any values were already substituted for scalarized parameters
- and update_cfg shuld be run after replace_uses_by. */
-
-static bool
-adjust_agg_replacement_values (cgraph_node *node,
- ipcp_transformation *ts,
- const vec<ipa_param_descriptor, va_gc>
- &descriptors)
+static void
+adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
{
clone_info *cinfo = clone_info::get (node);
if (!cinfo || !cinfo->param_adjustments)
- return false;
+ return;
+ auto_vec<int, 16> new_indices;
+ cinfo->param_adjustments->get_updated_indices (&new_indices);
bool removed_item = false;
- bool done_replacement = false;
unsigned dst_index = 0;
unsigned count = ts->m_agg_values->length ();
for (unsigned i = 0; i < count; i++)
@@ -5555,13 +5540,10 @@ adjust_agg_replacement_values (cgraph_node *node,
ipa_argagg_value *v = &(*ts->m_agg_values)[i];
gcc_checking_assert (v->index >= 0);
- tree cst_type = TREE_TYPE (v->value);
- int split_idx;
- int new_idx
- = cinfo->param_adjustments->get_updated_index_or_split (v->index,
- v->unit_offset,
- cst_type,
- &split_idx);
+ int new_idx = -1;
+ if ((unsigned) v->index < new_indices.length ())
+ new_idx = new_indices[v->index];
+
if (new_idx >= 0)
{
v->index = new_idx;
@@ -5570,19 +5552,7 @@ adjust_agg_replacement_values (cgraph_node *node,
dst_index++;
}
else
- {
- removed_item = true;
- if (split_idx >= 0)
- {
- tree parm = ipa_get_param (descriptors, split_idx);
- tree ddef = ssa_default_def (cfun, parm);
- if (ddef)
- {
- replace_uses_by (ddef, v->value);
- done_replacement = true;
- }
- }
- }
+ removed_item = true;
}
if (dst_index == 0)
@@ -5593,7 +5563,7 @@ adjust_agg_replacement_values (cgraph_node *node,
else if (removed_item)
ts->m_agg_values->truncate (dst_index);
- return done_replacement;
+ return;
}
/* Dominator walker driving the ipcp modification phase. */
@@ -5962,7 +5932,6 @@ ipcp_update_vr (struct cgraph_node *node)
unsigned int
ipcp_transform_function (struct cgraph_node *node)
{
- vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
struct ipa_func_body_info fbi;
int param_count;
@@ -5981,18 +5950,13 @@ ipcp_transform_function (struct cgraph_node *node)
param_count = count_formal_params (node->decl);
if (param_count == 0)
return 0;
- vec_safe_grow_cleared (descriptors, param_count, true);
- ipa_populate_param_decls (node, *descriptors);
- bool cfg_changed = adjust_agg_replacement_values (node, ts, *descriptors);
+ adjust_agg_replacement_values (node, ts);
if (vec_safe_is_empty (ts->m_agg_values))
{
- vec_free (descriptors);
if (dump_file)
fprintf (dump_file, " All affected aggregate parameters were either "
"removed or converted into scalars, phase done.\n");
- if (cfg_changed)
- delete_unreachable_blocks_update_callgraph (node, false);
return 0;
}
if (dump_file)
@@ -6009,12 +5973,15 @@ ipcp_transform_function (struct cgraph_node *node)
fbi.param_count = param_count;
fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
+ vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
+ vec_safe_grow_cleared (descriptors, param_count, true);
+ ipa_populate_param_decls (node, *descriptors);
bool modified_mem_access = false;
calculate_dominance_info (CDI_DOMINATORS);
ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
free_dominance_info (CDI_DOMINATORS);
- cfg_changed |= walker.cleanup_eh ();
+ bool cfg_changed = walker.cleanup_eh ();
int i;
struct ipa_bb_info *bi;
diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
index 718201d..93f5e34 100644
--- a/gcc/ipa-sra.cc
+++ b/gcc/ipa-sra.cc
@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
#include "internal-fn.h"
#include "symtab-clones.h"
#include "attribs.h"
+#include "ipa-prop.h"
static void ipa_sra_summarize_function (cgraph_node *);
@@ -150,6 +151,8 @@ struct gensum_param_access
arguments. */
tree alias_ptr_type;
+ /* Cumulative count of all loads. */
+ profile_count load_count;
/* Have there been writes to or reads from this exact location except for as
arguments to a function call that can be tracked. */
bool nonarg;
@@ -170,6 +173,10 @@ struct GTY(()) isra_param_desc
unsigned param_size_limit : ISRA_ARG_SIZE_LIMIT_BITS;
/* Sum of unit sizes of all certain replacements. */
unsigned size_reached : ISRA_ARG_SIZE_LIMIT_BITS;
+ /* Minimum offset that is known to be safe to dereference because of callers
+ pass pointers to DECLs of at least this size or because of dereferences in
+ callers. */
+ unsigned safe_size : ISRA_ARG_SIZE_LIMIT_BITS;
/* A parameter that is used only in call arguments and can be removed if all
concerned actual arguments are removed. */
@@ -178,6 +185,16 @@ struct GTY(()) isra_param_desc
unsigned split_candidate : 1;
/* Is this a parameter passing stuff by reference? */
unsigned by_ref : 1;
+ /* Parameter hint set during IPA analysis when there is a caller which does
+ not construct the argument just to pass it to calls. Only meaningful for
+ by_ref parameters. */
+ unsigned not_specially_constructed : 1;
+ /* Only meaningful for by_ref parameters. If set, this parameter can only be
+ a split candidate if all callers pass pointers that are known to point to
+ a chunk of memory large enough to contain all accesses. */
+ unsigned conditionally_dereferenceable : 1;
+ /* Set when safe_size has been updated from at least one caller. */
+ unsigned safe_size_set : 1;
};
/* Structure used when generating summaries that describes a parameter. */
@@ -206,8 +223,17 @@ struct gensum_param_desc
by reference that is a candidate for being converted to a set of
parameters passing those data by value. */
bool split_candidate;
- /* Is this a parameter passing stuff by reference? */
+ /* Is this a parameter passing stuff by reference (either a pointer or a
+ source language reference type)? */
bool by_ref;
+ /* If this parameter passes stuff by reference, can it be safely dereferenced
+ without performing further checks (for example because it is a
+ REFERENCE_TYPE)? */
+ bool safe_ref;
+ /* Only meaningful for by_ref parameters. If set, this parameter can only be
+ a split candidate if all callers pass pointers that are known to point to
+ a chunk of memory large enough to contain all accesses. */
+ bool conditionally_dereferenceable;
/* The number of this parameter as they are ordered in function decl. */
int param_number;
@@ -320,10 +346,12 @@ struct isra_param_flow
/* Offset within the formal parameter. */
unsigned unit_offset;
- /* Size of the portion of the formal parameter that is being passed. */
+ /* When aggregate_pass_through is set, this is the size of the portion of an
+ aggregate formal parameter that is being passed. Otherwise, this is size
+ of pointed to memory that is known to be valid be dereferenced. */
unsigned unit_size : ISRA_ARG_SIZE_LIMIT_BITS;
- /* True when the value of this actual copy is a portion of a formal
+ /* True when the value of this actual argument is a portion of a formal
parameter. */
unsigned aggregate_pass_through : 1;
/* True when the value of this actual copy is a verbatim pass through of an
@@ -332,6 +360,10 @@ struct isra_param_flow
/* True when it is safe to copy access candidates here from the callee, which
would mean introducing dereferences into callers of the caller. */
unsigned safe_to_import_accesses : 1;
+ /* True when the passed value is an address of a structure that has been
+ constructed in the caller just to be passed by reference to functions
+ (i.e. is never read). */
+ unsigned constructed_for_calls : 1;
};
/* Structure used to convey information about calls from the intra-procedural
@@ -409,9 +441,13 @@ ipa_sra_function_summaries::duplicate (cgraph_node *, cgraph_node *,
d->param_size_limit = s->param_size_limit;
d->size_reached = s->size_reached;
+ d->safe_size = s->safe_size;
d->locally_unused = s->locally_unused;
d->split_candidate = s->split_candidate;
d->by_ref = s->by_ref;
+ d->not_specially_constructed = s->not_specially_constructed;
+ d->conditionally_dereferenceable = s->conditionally_dereferenceable;
+ d->safe_size_set = s->safe_size_set;
unsigned acc_count = vec_safe_length (s->accesses);
vec_safe_reserve_exact (d->accesses, acc_count);
@@ -520,9 +556,14 @@ isra_call_summary::dump (FILE *f)
fprintf (f, " Aggregate pass through from the param given above, "
"unit offset: %u , unit size: %u\n",
ipf->unit_offset, ipf->unit_size);
+ else if (ipf->unit_size > 0)
+ fprintf (f, " Known dereferenceable size: %u\n", ipf->unit_size);
if (ipf->pointer_pass_through)
fprintf (f, " Pointer pass through from the param given above, "
"safe_to_import_accesses: %u\n", ipf->safe_to_import_accesses);
+ if (ipf->constructed_for_calls)
+ fprintf (f, " Variable constructed just to be passed to "
+ "calls.\n");
}
}
@@ -551,6 +592,10 @@ namespace {
hash_map<tree, gensum_param_desc *> *decl2desc;
+/* All local DECLs ever loaded from. */
+
+hash_set <tree> *loaded_decls;
+
/* Countdown of allowed Alias Analysis steps during summary building. */
int aa_walking_limit;
@@ -560,7 +605,7 @@ int aa_walking_limit;
accessed in that BB. */
HOST_WIDE_INT *bb_dereferences = NULL;
/* How many by-reference parameters there are in the current function. */
-int by_ref_count;
+int unsafe_by_ref_count;
/* Bitmap of BBs that can cause the function to "stop" progressing by
returning, throwing externally, looping infinitely or calling a function
@@ -642,6 +687,8 @@ dump_gensum_access (FILE *f, gensum_param_access *access, unsigned indent)
print_generic_expr (f, access->type);
fprintf (f, ", alias_ptr_type: ");
print_generic_expr (f, access->alias_ptr_type);
+ fprintf (f, ", load_count: ");
+ access->load_count.dump (f);
fprintf (f, ", nonarg: %u, reverse: %u\n", access->nonarg, access->reverse);
for (gensum_param_access *ch = access->first_child;
ch;
@@ -691,7 +738,11 @@ dump_gensum_param_descriptor (FILE *f, gensum_param_desc *desc)
return;
}
if (desc->by_ref)
- fprintf (f, " by_ref with %u pass throughs\n", desc->ptr_pt_count);
+ fprintf (f, " %s%s by_ref with %u pass throughs\n",
+ desc->safe_ref ? "safe" : "unsafe",
+ desc->conditionally_dereferenceable
+ ? " conditionally_dereferenceable" : " ok",
+ desc->ptr_pt_count);
for (gensum_param_access *acc = desc->accesses; acc; acc = acc->next_sibling)
dump_gensum_access (f, acc, 2);
@@ -717,10 +768,11 @@ dump_gensum_param_descriptors (FILE *f, tree fndecl,
}
-/* Dump DESC to F. */
+/* Dump DESC to F. If HINTS is true, also dump IPA-analysis computed
+ hints. */
static void
-dump_isra_param_descriptor (FILE *f, isra_param_desc *desc)
+dump_isra_param_descriptor (FILE *f, isra_param_desc *desc, bool hints)
{
if (desc->locally_unused)
{
@@ -728,12 +780,25 @@ dump_isra_param_descriptor (FILE *f, isra_param_desc *desc)
}
if (!desc->split_candidate)
{
- fprintf (f, " not a candidate for splitting\n");
+ fprintf (f, " not a candidate for splitting");
+ if (hints && desc->by_ref && desc->safe_size_set)
+ fprintf (f, ", safe_size: %u", (unsigned) desc->safe_size);
+ fprintf (f, "\n");
return;
}
- fprintf (f, " param_size_limit: %u, size_reached: %u%s\n",
+ fprintf (f, " param_size_limit: %u, size_reached: %u%s",
desc->param_size_limit, desc->size_reached,
desc->by_ref ? ", by_ref" : "");
+ if (desc->by_ref && desc->conditionally_dereferenceable)
+ fprintf (f, ", conditionally_dereferenceable");
+ if (hints)
+ {
+ if (desc->by_ref && !desc->not_specially_constructed)
+ fprintf (f, ", args_specially_constructed");
+ if (desc->by_ref && desc->safe_size_set)
+ fprintf (f, ", safe_size: %u", (unsigned) desc->safe_size);
+ }
+ fprintf (f, "\n");
for (unsigned i = 0; i < vec_safe_length (desc->accesses); ++i)
{
@@ -742,12 +807,12 @@ dump_isra_param_descriptor (FILE *f, isra_param_desc *desc)
}
}
-/* Dump all parameter descriptors in IFS, assuming it describes FNDECL, to
- F. */
+/* Dump all parameter descriptors in IFS, assuming it describes FNDECL, to F.
+ If HINTS is true, also dump IPA-analysis computed hints. */
static void
-dump_isra_param_descriptors (FILE *f, tree fndecl,
- isra_func_summary *ifs)
+dump_isra_param_descriptors (FILE *f, tree fndecl, isra_func_summary *ifs,
+ bool hints)
{
tree parm = DECL_ARGUMENTS (fndecl);
if (!ifs->m_parameters)
@@ -763,7 +828,7 @@ dump_isra_param_descriptors (FILE *f, tree fndecl,
fprintf (f, " Descriptor for parameter %i ", i);
print_generic_expr (f, parm, TDF_UID);
fprintf (f, "\n");
- dump_isra_param_descriptor (f, &(*ifs->m_parameters)[i]);
+ dump_isra_param_descriptor (f, &(*ifs->m_parameters)[i], hints);
}
}
@@ -1075,7 +1140,7 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
/* Initialize vector of parameter descriptors of NODE. Return true if there
are any candidates for splitting or unused aggregate parameter removal (the
function may return false if there are candidates for removal of register
- parameters) and function body must be scanned. */
+ parameters). */
static bool
create_parameter_descriptors (cgraph_node *node,
@@ -1139,6 +1204,8 @@ create_parameter_descriptors (cgraph_node *node,
if (POINTER_TYPE_P (type))
{
+ desc->by_ref = true;
+ desc->safe_ref = (TREE_CODE (type) == REFERENCE_TYPE);
type = TREE_TYPE (type);
if (TREE_CODE (type) == FUNCTION_TYPE
@@ -1186,7 +1253,6 @@ create_parameter_descriptors (cgraph_node *node,
"nonarg uses\n");
continue;
}
- desc->by_ref = true;
}
else if (!AGGREGATE_TYPE_P (type))
{
@@ -1230,8 +1296,8 @@ create_parameter_descriptors (cgraph_node *node,
ret = true;
desc->split_candidate = true;
- if (desc->by_ref)
- desc->deref_index = by_ref_count++;
+ if (desc->by_ref && !desc->safe_ref)
+ desc->deref_index = unsafe_by_ref_count++;
}
return ret;
}
@@ -1242,6 +1308,8 @@ create_parameter_descriptors (cgraph_node *node,
static gensum_param_desc *
get_gensum_param_desc (tree decl)
{
+ if (!decl2desc)
+ return NULL;
gcc_checking_assert (TREE_CODE (decl) == PARM_DECL);
gensum_param_desc **slot = decl2desc->get (decl);
if (!slot)
@@ -1300,6 +1368,7 @@ allocate_access (gensum_param_desc *desc,
memset (access, 0, sizeof (*access));
access->offset = offset;
access->size = size;
+ access->load_count = profile_count::zero ();
return access;
}
@@ -1554,15 +1623,16 @@ asm_visit_addr (gimple *, tree op, tree, void *)
static void
mark_param_dereference (gensum_param_desc *desc, HOST_WIDE_INT dist,
- basic_block bb)
+ basic_block bb)
{
gcc_assert (desc->by_ref);
gcc_checking_assert (desc->split_candidate);
- if (bitmap_bit_p (final_bbs, bb->index))
+ if (desc->safe_ref
+ || bitmap_bit_p (final_bbs, bb->index))
return;
- int idx = bb->index * by_ref_count + desc->deref_index;
+ int idx = bb->index * unsafe_by_ref_count + desc->deref_index;
if (bb_dereferences[idx] < dist)
bb_dereferences[idx] = dist;
}
@@ -1691,6 +1761,12 @@ scan_expr_access (tree expr, gimple *stmt, isra_scan_context ctx,
return;
deref = true;
}
+ else if (TREE_CODE (base) == VAR_DECL
+ && !TREE_STATIC (base)
+ && (ctx == ISRA_CTX_ARG
+ || ctx == ISRA_CTX_LOAD))
+ loaded_decls->add (base);
+
if (TREE_CODE (base) != PARM_DECL)
return;
@@ -1810,6 +1886,8 @@ scan_expr_access (tree expr, gimple *stmt, isra_scan_context ctx,
other. */
access->nonarg = true;
}
+ else if (ctx == ISRA_CTX_LOAD && bb->count.initialized_p ())
+ access->load_count += bb->count;
if (!access->type)
{
@@ -1868,7 +1946,7 @@ scan_function (cgraph_node *node, struct function *fun)
{
gimple *stmt = gsi_stmt (gsi);
- if (stmt_can_throw_external (fun, stmt))
+ if (final_bbs && stmt_can_throw_external (fun, stmt))
bitmap_set_bit (final_bbs, bb->index);
switch (gimple_code (stmt))
{
@@ -1877,7 +1955,8 @@ scan_function (cgraph_node *node, struct function *fun)
tree t = gimple_return_retval (as_a <greturn *> (stmt));
if (t != NULL_TREE)
scan_expr_access (t, stmt, ISRA_CTX_LOAD, bb);
- bitmap_set_bit (final_bbs, bb->index);
+ if (final_bbs)
+ bitmap_set_bit (final_bbs, bb->index);
}
break;
@@ -1922,8 +2001,9 @@ scan_function (cgraph_node *node, struct function *fun)
if (lhs)
scan_expr_access (lhs, stmt, ISRA_CTX_STORE, bb);
int flags = gimple_call_flags (stmt);
- if (((flags & (ECF_CONST | ECF_PURE)) == 0)
- || (flags & ECF_LOOPING_CONST_OR_PURE))
+ if (final_bbs
+ && (((flags & (ECF_CONST | ECF_PURE)) == 0)
+ || (flags & ECF_LOOPING_CONST_OR_PURE)))
bitmap_set_bit (final_bbs, bb->index);
}
break;
@@ -1933,7 +2013,8 @@ scan_function (cgraph_node *node, struct function *fun)
gasm *asm_stmt = as_a <gasm *> (stmt);
walk_stmt_load_store_addr_ops (asm_stmt, NULL, NULL, NULL,
asm_visit_addr);
- bitmap_set_bit (final_bbs, bb->index);
+ if (final_bbs)
+ bitmap_set_bit (final_bbs, bb->index);
for (unsigned i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
{
@@ -2029,6 +2110,34 @@ isra_analyze_call (cgraph_edge *cs)
for (unsigned i = 0; i < count; i++)
{
tree arg = gimple_call_arg (call_stmt, i);
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ {
+ poly_int64 poffset, psize, pmax_size;
+ bool reverse;
+ tree base = get_ref_base_and_extent (TREE_OPERAND (arg, 0), &poffset,
+ &psize, &pmax_size, &reverse);
+ HOST_WIDE_INT offset;
+ unsigned HOST_WIDE_INT ds;
+ if (DECL_P (base)
+ && (poffset.is_constant (&offset))
+ && tree_fits_uhwi_p (DECL_SIZE (base))
+ && ((ds = tree_to_uhwi (DECL_SIZE (base)) - offset)
+ < ISRA_ARG_SIZE_LIMIT * BITS_PER_UNIT))
+ {
+ csum->init_inputs (count);
+ gcc_assert (!csum->m_arg_flow[i].aggregate_pass_through);
+ csum->m_arg_flow[i].unit_size = ds / BITS_PER_UNIT;
+ }
+
+ if (TREE_CODE (base) == VAR_DECL
+ && !TREE_STATIC (base)
+ && !loaded_decls->contains (base))
+ {
+ csum->init_inputs (count);
+ csum->m_arg_flow[i].constructed_for_calls = true;
+ }
+ }
+
if (is_gimple_reg (arg))
continue;
@@ -2091,9 +2200,9 @@ dump_dereferences_table (FILE *f, struct function *fun, const char *str)
if (bb != EXIT_BLOCK_PTR_FOR_FN (fun))
{
int i;
- for (i = 0; i < by_ref_count; i++)
+ for (i = 0; i < unsafe_by_ref_count; i++)
{
- int idx = bb->index * by_ref_count + i;
+ int idx = bb->index * unsafe_by_ref_count + i;
fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", bb_dereferences[idx]);
}
}
@@ -2138,15 +2247,15 @@ propagate_dereference_distances (struct function *fun)
if (bitmap_bit_p (final_bbs, bb->index))
continue;
- for (i = 0; i < by_ref_count; i++)
+ for (i = 0; i < unsafe_by_ref_count; i++)
{
- int idx = bb->index * by_ref_count + i;
+ int idx = bb->index * unsafe_by_ref_count + i;
bool first = true;
HOST_WIDE_INT inh = 0;
FOR_EACH_EDGE (e, ei, bb->succs)
{
- int succ_idx = e->dest->index * by_ref_count + i;
+ int succ_idx = e->dest->index * unsafe_by_ref_count + i;
if (e->dest == EXIT_BLOCK_PTR_FOR_FN (fun))
continue;
@@ -2183,13 +2292,24 @@ propagate_dereference_distances (struct function *fun)
"Dereference table after propagation:\n");
}
-/* Perform basic checks on ACCESS to PARM described by DESC and all its
- children, return true if the parameter cannot be split, otherwise return
- true and update *TOTAL_SIZE and *ONLY_CALLS. ENTRY_BB_INDEX must be the
- index of the entry BB in the function of PARM. */
+/* Return true if the ACCESS loads happen frequently enough in FUN to risk
+ moving them to the caller and only pass the result. */
static bool
-check_gensum_access (tree parm, gensum_param_desc *desc,
+dereference_probable_p (struct function *fun, gensum_param_access *access)
+{
+ int threshold = opt_for_fn (fun->decl, param_ipa_sra_deref_prob_threshold);
+ return access->load_count
+ >= ENTRY_BLOCK_PTR_FOR_FN (fun)->count.apply_scale (threshold, 100);
+}
+
+/* Perform basic checks on ACCESS to PARM (of FUN) described by DESC and all
+ its children, return true if the parameter cannot be split, otherwise return
+ false and update *NONARG_ACC_SIZE and *ONLY_CALLS. ENTRY_BB_INDEX must be
+ the index of the entry BB in the function of PARM. */
+
+static bool
+check_gensum_access (struct function *fun, tree parm, gensum_param_desc *desc,
gensum_param_access *access,
HOST_WIDE_INT *nonarg_acc_size, bool *only_calls,
int entry_bb_index)
@@ -2217,19 +2337,36 @@ check_gensum_access (tree parm, gensum_param_desc *desc,
if (desc->by_ref)
{
- int idx = (entry_bb_index * by_ref_count + desc->deref_index);
- if ((access->offset + access->size) > bb_dereferences[idx])
+ if (desc->safe_ref)
{
- disqualify_split_candidate (desc, "Would create a possibly "
- "illegal dereference in a caller.");
- return true;
+ if (!dereference_probable_p (fun, access))
+ {
+ disqualify_split_candidate (desc, "Dereferences in callers "
+ "would happen much more frequently.");
+ return true;
+ }
+ }
+ else
+ {
+ int idx = (entry_bb_index * unsafe_by_ref_count + desc->deref_index);
+ if ((access->offset + access->size) > bb_dereferences[idx])
+ {
+ if (!dereference_probable_p (fun, access))
+ {
+ disqualify_split_candidate (desc, "Would create a possibly "
+ "illegal dereference in a "
+ "caller.");
+ return true;
+ }
+ desc->conditionally_dereferenceable = true;
+ }
}
}
for (gensum_param_access *ch = access->first_child;
ch;
ch = ch->next_sibling)
- if (check_gensum_access (parm, desc, ch, nonarg_acc_size, only_calls,
+ if (check_gensum_access (fun, parm, desc, ch, nonarg_acc_size, only_calls,
entry_bb_index))
return true;
@@ -2287,6 +2424,7 @@ process_scan_results (cgraph_node *node, struct function *fun,
if (!dereferences_propagated
&& desc->by_ref
+ && !desc->safe_ref
&& desc->accesses)
{
propagate_dereference_distances (fun);
@@ -2301,8 +2439,8 @@ process_scan_results (cgraph_node *node, struct function *fun,
for (gensum_param_access *acc = desc->accesses;
acc;
acc = acc->next_sibling)
- if (check_gensum_access (parm, desc, acc, &nonarg_acc_size, &only_calls,
- entry_bb_index))
+ if (check_gensum_access (fun, parm, desc, acc, &nonarg_acc_size,
+ &only_calls, entry_bb_index))
{
check_failed = true;
break;
@@ -2315,18 +2453,28 @@ process_scan_results (cgraph_node *node, struct function *fun,
HOST_WIDE_INT cur_param_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm)));
- HOST_WIDE_INT param_size_limit;
+ HOST_WIDE_INT param_size_limit, optimistic_limit;
if (!desc->by_ref || optimize_function_for_size_p (fun))
- param_size_limit = cur_param_size;
+ {
+ param_size_limit = cur_param_size;
+ optimistic_limit = cur_param_size;
+ }
else
+ {
param_size_limit
= opt_for_fn (node->decl,
param_ipa_sra_ptr_growth_factor) * cur_param_size;
- if (nonarg_acc_size > param_size_limit
+ optimistic_limit
+ = (opt_for_fn (node->decl, param_ipa_sra_ptrwrap_growth_factor)
+ * param_size_limit);
+ }
+
+ if (nonarg_acc_size > optimistic_limit
|| (!desc->by_ref && nonarg_acc_size == param_size_limit))
{
disqualify_split_candidate (desc, "Would result into a too big set "
- "of replacements.");
+ "of replacements even in best "
+ "scenarios.");
}
else
{
@@ -2393,6 +2541,12 @@ process_scan_results (cgraph_node *node, struct function *fun,
if (!uses_memory_as_obtained)
continue;
+ if (desc->safe_ref)
+ {
+ csum->m_arg_flow[argidx].safe_to_import_accesses = true;
+ continue;
+ }
+
/* Post-dominator check placed last, hoping that it usually won't
be needed. */
if (!pdoms_calculated)
@@ -2433,6 +2587,7 @@ process_scan_results (cgraph_node *node, struct function *fun,
d->locally_unused = s->locally_unused;
d->split_candidate = s->split_candidate;
d->by_ref = s->by_ref;
+ d->conditionally_dereferenceable = s->conditionally_dereferenceable;
for (gensum_param_access *acc = s->accesses;
acc;
@@ -2441,7 +2596,7 @@ process_scan_results (cgraph_node *node, struct function *fun,
}
if (dump_file)
- dump_isra_param_descriptors (dump_file, node->decl, ifs);
+ dump_isra_param_descriptors (dump_file, node->decl, ifs, false);
}
/* Return true if there are any overlaps among certain accesses of DESC. If
@@ -2542,6 +2697,7 @@ isra_write_edge_summary (output_block *ob, cgraph_edge *e)
bp_pack_value (&bp, ipf->aggregate_pass_through, 1);
bp_pack_value (&bp, ipf->pointer_pass_through, 1);
bp_pack_value (&bp, ipf->safe_to_import_accesses, 1);
+ bp_pack_value (&bp, ipf->constructed_for_calls, 1);
streamer_write_bitpack (&bp);
streamer_write_uhwi (ob, ipf->unit_offset);
streamer_write_uhwi (ob, ipf->unit_size);
@@ -2586,10 +2742,14 @@ isra_write_node_summary (output_block *ob, cgraph_node *node)
}
streamer_write_uhwi (ob, desc->param_size_limit);
streamer_write_uhwi (ob, desc->size_reached);
+ gcc_assert (desc->safe_size == 0);
bitpack_d bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, desc->locally_unused, 1);
bp_pack_value (&bp, desc->split_candidate, 1);
bp_pack_value (&bp, desc->by_ref, 1);
+ gcc_assert (!desc->not_specially_constructed);
+ bp_pack_value (&bp, desc->conditionally_dereferenceable, 1);
+ gcc_assert (!desc->safe_size_set);
streamer_write_bitpack (&bp);
}
bitpack_d bp = bitpack_create (ob->main_stream);
@@ -2663,6 +2823,7 @@ isra_read_edge_summary (struct lto_input_block *ib, cgraph_edge *cs)
ipf->aggregate_pass_through = bp_unpack_value (&bp, 1);
ipf->pointer_pass_through = bp_unpack_value (&bp, 1);
ipf->safe_to_import_accesses = bp_unpack_value (&bp, 1);
+ ipf->constructed_for_calls = bp_unpack_value (&bp, 1);
ipf->unit_offset = streamer_read_uhwi (ib);
ipf->unit_size = streamer_read_uhwi (ib);
}
@@ -2705,10 +2866,14 @@ isra_read_node_info (struct lto_input_block *ib, cgraph_node *node,
}
desc->param_size_limit = streamer_read_uhwi (ib);
desc->size_reached = streamer_read_uhwi (ib);
+ desc->safe_size = 0;
bitpack_d bp = streamer_read_bitpack (ib);
desc->locally_unused = bp_unpack_value (&bp, 1);
desc->split_candidate = bp_unpack_value (&bp, 1);
desc->by_ref = bp_unpack_value (&bp, 1);
+ desc->not_specially_constructed = 0;
+ desc->conditionally_dereferenceable = bp_unpack_value (&bp, 1);
+ desc->safe_size_set = 0;
}
bitpack_d bp = streamer_read_bitpack (ib);
ifs->m_candidate = bp_unpack_value (&bp, 1);
@@ -2791,10 +2956,11 @@ ipa_sra_read_summary (void)
}
}
-/* Dump all IPA-SRA summary data for all cgraph nodes and edges to file F. */
+/* Dump all IPA-SRA summary data for all cgraph nodes and edges to file F. If
+ HINTS is true, also dump IPA-analysis computed hints. */
static void
-ipa_sra_dump_all_summaries (FILE *f)
+ipa_sra_dump_all_summaries (FILE *f, bool hints)
{
cgraph_node *node;
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
@@ -2817,7 +2983,7 @@ ipa_sra_dump_all_summaries (FILE *f)
for (unsigned i = 0; i < ifs->m_parameters->length (); ++i)
{
fprintf (f, " Descriptor for parameter %i:\n", i);
- dump_isra_param_descriptor (f, &(*ifs->m_parameters)[i]);
+ dump_isra_param_descriptor (f, &(*ifs->m_parameters)[i], hints);
}
fprintf (f, "\n");
}
@@ -3154,6 +3320,130 @@ isra_mark_caller_param_used (isra_func_summary *from_ifs, int input_idx,
}
}
+/* Combine safe_size of DESC with SIZE and return true if it has changed. */
+
+static bool
+update_safe_size (isra_param_desc *desc, unsigned size)
+{
+ if (!desc->safe_size_set)
+ {
+ desc->safe_size_set = 1;
+ desc->safe_size = size;
+ return true;
+ }
+ if (desc->safe_size <= size)
+ return false;
+ desc->safe_size = size;
+ return true;
+}
+
+/* Set all param hints in DESC to the pessimistic values. Return true if any
+ hints that need to potentially trigger further propagation have changed. */
+
+static bool
+flip_all_hints_pessimistic (isra_param_desc *desc)
+{
+ desc->not_specially_constructed = true;
+ return update_safe_size (desc, 0);
+}
+
+/* Because we have not analyzed or otherwise problematic caller, go over all
+ parameter int flags of IFS describing a call graph node of a calllee and
+ turn them pessimistic. Return true if any hints that need to potentially
+ trigger further propagation have changed. */
+
+static bool
+flip_all_param_hints_pessimistic (isra_func_summary *ifs)
+{
+ if (!ifs || !ifs->m_candidate)
+ return false;
+
+ bool ret = false;
+ unsigned param_count = vec_safe_length (ifs->m_parameters);
+
+ for (unsigned i = 0; i < param_count; i++)
+ ret |= flip_all_hints_pessimistic (&(*ifs->m_parameters)[i]);
+
+ return ret;
+}
+
+/* Propagate hints accross edge CS which ultimately leads to a node described
+ by TO_IFS. Return true if any hints of the callee which should potentially
+ trigger further propagation have changed. */
+
+static bool
+propagate_param_hints_accross_call (cgraph_edge *cs, isra_func_summary *to_ifs)
+{
+ if (!to_ifs || !to_ifs->m_candidate)
+ return false;
+
+ isra_call_summary *csum = call_sums->get (cs);
+ bool ret = false;
+ unsigned args_count = csum->m_arg_flow.length ();
+ unsigned param_count = vec_safe_length (to_ifs->m_parameters);
+
+ for (unsigned i = 0; i < param_count; i++)
+ {
+ isra_param_desc *desc = &(*to_ifs->m_parameters)[i];
+ if (i >= args_count)
+ {
+ ret |= flip_all_hints_pessimistic (desc);
+ continue;
+ }
+
+ if (desc->by_ref)
+ {
+ isra_param_flow *ipf = &csum->m_arg_flow[i];
+
+ if (!ipf->constructed_for_calls)
+ desc->not_specially_constructed = true;
+
+ if (ipf->pointer_pass_through)
+ {
+ isra_func_summary *from_ifs = func_sums->get (cs->caller);
+ int srcidx = get_single_param_flow_source (ipf);
+ if (vec_safe_length (from_ifs->m_parameters) > (unsigned) srcidx)
+ {
+ isra_param_desc *src_d = &(*from_ifs->m_parameters)[srcidx];
+ if (src_d->safe_size_set)
+ ret |= update_safe_size (desc, src_d->safe_size);
+ }
+ else
+ ret |= update_safe_size (desc, 0);
+ }
+ else if (!ipf->aggregate_pass_through)
+ ret |= update_safe_size (desc, ipf->unit_size);
+ else
+ /* LTOing type-mismatched programs can end up here. */
+ ret |= update_safe_size (desc, 0);
+ }
+ }
+ return ret;
+}
+
+/* Propagate hints from NODE described by FROM_IFS to all its (dorect) callees,
+ push those that may need re-visiting onto STACK. */
+
+static void
+propagate_hints_to_all_callees (cgraph_node *node, isra_func_summary *from_ifs,
+ vec<cgraph_node *> *stack)
+{
+ for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
+ {
+ enum availability availability;
+ cgraph_node *callee = cs->callee->function_symbol (&availability);
+ isra_func_summary *to_ifs = func_sums->get (callee);
+ if (!from_ifs)
+ {
+ if (flip_all_param_hints_pessimistic (to_ifs)
+ && ipa_edge_within_scc (cs))
+ isra_push_node_to_stack (callee, to_ifs, stack);
+ }
+ else if (propagate_param_hints_accross_call (cs, to_ifs)
+ && ipa_edge_within_scc (cs))
+ isra_push_node_to_stack (callee, to_ifs, stack);
+ }
+}
/* Propagate information that any parameter is not used only locally within a
SCC across CS to the caller, which must be in the same SCC as the
@@ -3605,13 +3895,16 @@ retval_used_p (cgraph_node *node, void *)
/* Push into NEW_PARAMS all required parameter adjustment entries to copy or
modify parameter which originally had index BASE_INDEX, in the adjustment
vector of parent clone (if any) had PREV_CLONE_INDEX and was described by
- PREV_ADJUSTMENT. If the parent clone is the original function,
- PREV_ADJUSTMENT is NULL and PREV_CLONE_INDEX is equal to BASE_INDEX. */
+ PREV_ADJUSTMENT. If IPA-CP has created a transformation summary for the
+ original node, it needs to be passed in IPCP_TS, otherwise it should be
+ NULL. If the parent clone is the original function, PREV_ADJUSTMENT is NULL
+ and PREV_CLONE_INDEX is equal to BASE_INDEX. */
static void
push_param_adjustments_for_index (isra_func_summary *ifs, unsigned base_index,
unsigned prev_clone_index,
ipa_adjusted_param *prev_adjustment,
+ ipcp_transformation *ipcp_ts,
vec<ipa_adjusted_param, va_gc> **new_params)
{
isra_param_desc *desc = &(*ifs->m_parameters)[base_index];
@@ -3652,6 +3945,23 @@ push_param_adjustments_for_index (isra_func_summary *ifs, unsigned base_index,
param_access *pa = (*desc->accesses)[j];
if (!pa->certain)
continue;
+
+ if (ipcp_ts)
+ {
+ ipa_argagg_value_list avl (ipcp_ts);
+ tree value = avl.get_value (base_index, pa->unit_offset);
+ if (value
+ && (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (value))) / BITS_PER_UNIT
+ == pa->unit_size))
+ {
+ if (dump_file)
+ fprintf (dump_file, " - omitting component at byte "
+ "offset %u which is known to have a constant value\n ",
+ pa->unit_offset);
+ continue;
+ }
+ }
+
if (dump_file)
fprintf (dump_file, " - component at byte offset %u, "
"size %u\n", pa->unit_offset, pa->unit_size);
@@ -3732,6 +4042,7 @@ process_isra_node_results (cgraph_node *node,
fprintf (dump_file, " Will remove return value.\n");
}
+ ipcp_transformation *ipcp_ts = ipcp_get_transformation_summary (node);
vec<ipa_adjusted_param, va_gc> *new_params = NULL;
if (ipa_param_adjustments *old_adjustments
= cinfo ? cinfo->param_adjustments : NULL)
@@ -3741,12 +4052,12 @@ process_isra_node_results (cgraph_node *node,
{
ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
push_param_adjustments_for_index (ifs, old_adj->base_index, i,
- old_adj, &new_params);
+ old_adj, ipcp_ts, &new_params);
}
}
else
for (unsigned i = 0; i < param_count; i++)
- push_param_adjustments_for_index (ifs, i, i, NULL, &new_params);
+ push_param_adjustments_for_index (ifs, i, i, NULL, ipcp_ts, &new_params);
ipa_param_adjustments *new_adjustments
= (new (ggc_alloc <ipa_param_adjustments> ())
@@ -3783,10 +4094,12 @@ process_isra_node_results (cgraph_node *node,
/* Check which parameters of NODE described by IFS have survived until IPA-SRA
and disable transformations for those which have not or which should not
transformed because the associated debug counter reached its limit. Return
- true if none survived or if there were no candidates to begin with. */
+ true if none survived or if there were no candidates to begin with.
+ Additionally, also adjust parameter descriptions based on debug counters and
+ hints propagated earlier. */
static bool
-disable_unavailable_parameters (cgraph_node *node, isra_func_summary *ifs)
+adjust_parameter_descriptions (cgraph_node *node, isra_func_summary *ifs)
{
bool ret = true;
unsigned len = vec_safe_length (ifs->m_parameters);
@@ -3801,7 +4114,8 @@ disable_unavailable_parameters (cgraph_node *node, isra_func_summary *ifs)
check_surviving = true;
cinfo->param_adjustments->get_surviving_params (&surviving_params);
}
- bool dumped_first = false;
+ auto_vec <unsigned> dump_dead_indices;
+ auto_vec <unsigned> dump_bad_cond_indices;
for (unsigned i = 0; i < len; i++)
{
isra_param_desc *desc = &(*ifs->m_parameters)[i];
@@ -3820,23 +4134,56 @@ disable_unavailable_parameters (cgraph_node *node, isra_func_summary *ifs)
desc->split_candidate = false;
if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_dead_indices.safe_push (i);
+ }
+ else
+ {
+ if (desc->split_candidate && desc->conditionally_dereferenceable)
+ {
+ gcc_assert (desc->safe_size_set);
+ for (param_access *pa : *desc->accesses)
+ if ((pa->unit_offset + pa->unit_size) > desc->safe_size)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_bad_cond_indices.safe_push (i);
+ desc->split_candidate = false;
+ break;
+ }
+ }
+
+ if (desc->split_candidate)
{
- if (!dumped_first)
+ if (desc->by_ref && !desc->not_specially_constructed)
{
- fprintf (dump_file,
- "The following parameters of %s are dead on "
- "arrival:", node->dump_name ());
- dumped_first = true;
+ int extra_factor
+ = opt_for_fn (node->decl,
+ param_ipa_sra_ptrwrap_growth_factor);
+ desc->param_size_limit = extra_factor * desc->param_size_limit;
}
- fprintf (dump_file, " %u", i);
+ if (size_would_violate_limit_p (desc, desc->size_reached))
+ desc->split_candidate = false;
}
+ if (desc->locally_unused || desc->split_candidate)
+ ret = false;
}
- else if (desc->locally_unused || desc->split_candidate)
- ret = false;
}
- if (dumped_first)
- fprintf (dump_file, "\n");
+ if (!dump_dead_indices.is_empty ())
+ {
+ fprintf (dump_file, "The following parameters of %s are dead on arrival:",
+ node->dump_name ());
+ for (unsigned i : dump_dead_indices)
+ fprintf (dump_file, " %u", i);
+ fprintf (dump_file, "\n");
+ }
+ if (!dump_bad_cond_indices.is_empty ())
+ {
+ fprintf (dump_file, "The following parameters of %s are not safe to "
+ "derefernce in all callers:", node->dump_name ());
+ for (unsigned i : dump_bad_cond_indices)
+ fprintf (dump_file, " %u", i);
+ fprintf (dump_file, "\n");
+ }
return ret;
}
@@ -3850,7 +4197,7 @@ ipa_sra_analysis (void)
if (dump_file)
{
fprintf (dump_file, "\n========== IPA-SRA IPA stage ==========\n");
- ipa_sra_dump_all_summaries (dump_file);
+ ipa_sra_dump_all_summaries (dump_file, false);
}
gcc_checking_assert (func_sums);
@@ -3859,28 +4206,92 @@ ipa_sra_analysis (void)
auto_vec <cgraph_node *, 16> stack;
int node_scc_count = ipa_reduced_postorder (order, true, NULL);
- /* One sweep from callees to callers for parameter removal and splitting. */
- for (int i = 0; i < node_scc_count; i++)
+ /* One sweep from callers to callees for return value removal. */
+ for (int i = node_scc_count - 1; i >= 0 ; i--)
{
cgraph_node *scc_rep = order[i];
vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
- unsigned j;
- /* Preliminary IPA function level checks and first step of parameter
- removal. */
- cgraph_node *v;
- FOR_EACH_VEC_ELT (cycle_nodes, j, v)
+ /* Preliminary IPA function level checks. */
+ for (cgraph_node *v : cycle_nodes)
{
isra_func_summary *ifs = func_sums->get (v);
if (!ifs || !ifs->m_candidate)
continue;
if (!ipa_sra_ipa_function_checks (v)
|| check_all_callers_for_issues (v))
- {
- ifs->zap ();
- continue;
- }
- if (disable_unavailable_parameters (v, ifs))
+ ifs->zap ();
+ }
+
+ for (cgraph_node *v : cycle_nodes)
+ {
+ isra_func_summary *ifs = func_sums->get (v);
+ if (!ifs || !ifs->m_candidate)
+ continue;
+ bool return_needed
+ = (ifs->m_returns_value
+ && (!dbg_cnt (ipa_sra_retvalues)
+ || v->call_for_symbol_and_aliases (retval_used_p,
+ NULL, true)));
+ ifs->m_return_ignored = !return_needed;
+ if (return_needed)
+ isra_push_node_to_stack (v, ifs, &stack);
+ }
+
+ while (!stack.is_empty ())
+ {
+ cgraph_node *node = stack.pop ();
+ isra_func_summary *ifs = func_sums->get (node);
+ gcc_checking_assert (ifs && ifs->m_queued);
+ ifs->m_queued = false;
+
+ for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
+ if (ipa_edge_within_scc (cs)
+ && call_sums->get (cs)->m_return_returned)
+ {
+ enum availability av;
+ cgraph_node *callee = cs->callee->function_symbol (&av);
+ isra_func_summary *to_ifs = func_sums->get (callee);
+ if (to_ifs && to_ifs->m_return_ignored)
+ {
+ to_ifs->m_return_ignored = false;
+ isra_push_node_to_stack (callee, to_ifs, &stack);
+ }
+ }
+ }
+
+ /* Parameter hint propagation. */
+ for (cgraph_node *v : cycle_nodes)
+ {
+ isra_func_summary *ifs = func_sums->get (v);
+ propagate_hints_to_all_callees (v, ifs, &stack);
+ }
+
+ while (!stack.is_empty ())
+ {
+ cgraph_node *node = stack.pop ();
+ isra_func_summary *ifs = func_sums->get (node);
+ gcc_checking_assert (ifs && ifs->m_queued);
+ ifs->m_queued = false;
+ propagate_hints_to_all_callees (node, ifs, &stack);
+ }
+
+ cycle_nodes.release ();
+ }
+
+ /* One sweep from callees to callers for parameter removal and splitting. */
+ for (int i = 0; i < node_scc_count; i++)
+ {
+ cgraph_node *scc_rep = order[i];
+ vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
+
+ /* First step of parameter removal. */
+ for (cgraph_node *v : cycle_nodes)
+ {
+ isra_func_summary *ifs = func_sums->get (v);
+ if (!ifs || !ifs->m_candidate)
+ continue;
+ if (adjust_parameter_descriptions (v, ifs))
continue;
for (cgraph_edge *cs = v->indirect_calls; cs; cs = cs->next_callee)
process_edge_to_unknown_caller (cs);
@@ -3892,7 +4303,7 @@ ipa_sra_analysis (void)
/* Look at edges within the current SCC and propagate used-ness across
them, pushing onto the stack all notes which might need to be
revisited. */
- FOR_EACH_VEC_ELT (cycle_nodes, j, v)
+ for (cgraph_node *v : cycle_nodes)
v->call_for_symbol_thunks_and_aliases (propagate_used_to_scc_callers,
&stack, true);
@@ -3913,7 +4324,7 @@ ipa_sra_analysis (void)
do
{
repeat_scc_access_propagation = false;
- FOR_EACH_VEC_ELT (cycle_nodes, j, v)
+ for (cgraph_node *v : cycle_nodes)
{
isra_func_summary *ifs = func_sums->get (v);
if (!ifs
@@ -3928,60 +4339,12 @@ ipa_sra_analysis (void)
while (repeat_scc_access_propagation);
if (flag_checking)
- FOR_EACH_VEC_ELT (cycle_nodes, j, v)
+ for (cgraph_node *v : cycle_nodes)
verify_splitting_accesses (v, true);
cycle_nodes.release ();
}
- /* One sweep from caller to callees for result removal. */
- for (int i = node_scc_count - 1; i >= 0 ; i--)
- {
- cgraph_node *scc_rep = order[i];
- vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
- unsigned j;
-
- cgraph_node *v;
- FOR_EACH_VEC_ELT (cycle_nodes, j, v)
- {
- isra_func_summary *ifs = func_sums->get (v);
- if (!ifs || !ifs->m_candidate)
- continue;
-
- bool return_needed
- = (ifs->m_returns_value
- && (!dbg_cnt (ipa_sra_retvalues)
- || v->call_for_symbol_and_aliases (retval_used_p,
- NULL, true)));
- ifs->m_return_ignored = !return_needed;
- if (return_needed)
- isra_push_node_to_stack (v, ifs, &stack);
- }
-
- while (!stack.is_empty ())
- {
- cgraph_node *node = stack.pop ();
- isra_func_summary *ifs = func_sums->get (node);
- gcc_checking_assert (ifs && ifs->m_queued);
- ifs->m_queued = false;
-
- for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
- if (ipa_edge_within_scc (cs)
- && call_sums->get (cs)->m_return_returned)
- {
- enum availability av;
- cgraph_node *callee = cs->callee->function_symbol (&av);
- isra_func_summary *to_ifs = func_sums->get (callee);
- if (to_ifs && to_ifs->m_return_ignored)
- {
- to_ifs->m_return_ignored = false;
- isra_push_node_to_stack (callee, to_ifs, &stack);
- }
- }
- }
- cycle_nodes.release ();
- }
-
ipa_free_postorder_info ();
free (order);
@@ -3991,7 +4354,7 @@ ipa_sra_analysis (void)
{
fprintf (dump_file, "\n========== IPA-SRA propagation final state "
" ==========\n");
- ipa_sra_dump_all_summaries (dump_file);
+ ipa_sra_dump_all_summaries (dump_file, true);
}
fprintf (dump_file, "\n========== IPA-SRA decisions ==========\n");
}
@@ -4072,48 +4435,57 @@ ipa_sra_summarize_function (cgraph_node *node)
if (dump_file)
fprintf (dump_file, "Creating summary for %s/%i:\n", node->name (),
node->order);
- if (!ipa_sra_preliminary_function_checks (node))
- {
- isra_analyze_all_outgoing_calls (node);
- return;
- }
gcc_obstack_init (&gensum_obstack);
- isra_func_summary *ifs = func_sums->get_create (node);
- ifs->m_candidate = true;
- tree ret = TREE_TYPE (TREE_TYPE (node->decl));
- ifs->m_returns_value = (TREE_CODE (ret) != VOID_TYPE);
+ loaded_decls = new hash_set<tree>;
- decl2desc = new hash_map<tree, gensum_param_desc *>;
+ isra_func_summary *ifs = NULL;
unsigned count = 0;
- for (tree parm = DECL_ARGUMENTS (node->decl); parm; parm = DECL_CHAIN (parm))
- count++;
+ if (ipa_sra_preliminary_function_checks (node))
+ {
+ ifs = func_sums->get_create (node);
+ ifs->m_candidate = true;
+ tree ret = TREE_TYPE (TREE_TYPE (node->decl));
+ ifs->m_returns_value = (TREE_CODE (ret) != VOID_TYPE);
+ for (tree parm = DECL_ARGUMENTS (node->decl);
+ parm;
+ parm = DECL_CHAIN (parm))
+ count++;
+ }
+ auto_vec<gensum_param_desc, 16> param_descriptions (count);
+ struct function *fun = DECL_STRUCT_FUNCTION (node->decl);
+ bool cfun_pushed = false;
if (count > 0)
{
- auto_vec<gensum_param_desc, 16> param_descriptions (count);
+ decl2desc = new hash_map<tree, gensum_param_desc *>;
param_descriptions.reserve_exact (count);
param_descriptions.quick_grow_cleared (count);
- bool cfun_pushed = false;
- struct function *fun = DECL_STRUCT_FUNCTION (node->decl);
if (create_parameter_descriptors (node, &param_descriptions))
{
push_cfun (fun);
cfun_pushed = true;
final_bbs = BITMAP_ALLOC (NULL);
bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
- by_ref_count
+ unsafe_by_ref_count
* last_basic_block_for_fn (fun));
aa_walking_limit = opt_for_fn (node->decl, param_ipa_max_aa_steps);
- scan_function (node, fun);
+ }
+ }
+ /* Scan function is run even when there are no removal or splitting
+ candidates so that we can calculate hints on call edges which can be
+ useful in callees. */
+ scan_function (node, fun);
- if (dump_file)
- {
- dump_gensum_param_descriptors (dump_file, node->decl,
- &param_descriptions);
- fprintf (dump_file, "----------------------------------------\n");
- }
+ if (count > 0)
+ {
+ if (dump_file)
+ {
+ dump_gensum_param_descriptors (dump_file, node->decl,
+ &param_descriptions);
+ fprintf (dump_file, "----------------------------------------\n");
}
+
process_scan_results (node, fun, ifs, &param_descriptions);
if (cfun_pushed)
@@ -4128,8 +4500,13 @@ ipa_sra_summarize_function (cgraph_node *node)
}
isra_analyze_all_outgoing_calls (node);
- delete decl2desc;
- decl2desc = NULL;
+ delete loaded_decls;
+ loaded_decls = NULL;
+ if (decl2desc)
+ {
+ delete decl2desc;
+ decl2desc = NULL;
+ }
obstack_free (&gensum_obstack, NULL);
if (dump_file)
fprintf (dump_file, "\n\n");
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 5d7c717..e1236de 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -806,6 +806,15 @@ public:
void replay_into (replayer *) final override;
+ bool is_same_type_as (type *other) final override
+ {
+ vector_type *other_vec_type = other->dyn_cast_vector_type ();
+ if (other_vec_type == NULL)
+ return false;
+ return get_num_units () == other_vec_type->get_num_units ()
+ && get_element_type () == other_vec_type->get_element_type ();
+ }
+
vector_type *is_vector () final override { return this; }
private:
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 350195d..11079b0 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -797,7 +797,7 @@ add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
{
if (node->clone_of)
add_node_to (encoder, node->clone_of, include_body);
- else if (include_body)
+ if (include_body)
lto_set_symtab_encoder_encode_body (encoder, node);
lto_symtab_encoder_encode (encoder, node);
}
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index 1e38904..08f75b0 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -2752,7 +2752,8 @@ lto_output (void)
continue;
if (cgraph_node *node = dyn_cast <cgraph_node *> (snode))
{
- if (lto_symtab_encoder_encode_body_p (encoder, node))
+ if (lto_symtab_encoder_encode_body_p (encoder, node)
+ && !node->clone_of)
symbols_to_copy.safe_push (node);
}
else if (varpool_node *node = dyn_cast <varpool_node *> (snode))
diff --git a/gcc/params.opt b/gcc/params.opt
index 397ec0b..e0fd05f 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -282,13 +282,21 @@ Maximum number of different predicates used to track properties of loops in IPA
Common Joined UInteger Var(param_ipa_max_switch_predicate_bounds) Init(5) Param Optimization
Maximal number of boundary endpoints of case ranges of switch statement used during IPA function summary generation.
+-param=ipa-sra-deref-prob-threshold=
+Common Joined UInteger Var(param_ipa_sra_deref_prob_threshold) Init(50) IntegerRange(0, 100) Param Optimization
+Minimum probability (in percent) of dereferencing of a function pointer parameter for it to be considered for replacement with simple values.
+
-param=ipa-sra-max-replacements=
Common Joined UInteger Var(param_ipa_sra_max_replacements) Optimization Init(8) IntegerRange(0, 16) Param
Maximum pieces that IPA-SRA tracks per formal parameter, as a consequence, also the maximum number of replacements of a formal parameter.
-param=ipa-sra-ptr-growth-factor=
Common Joined UInteger Var(param_ipa_sra_ptr_growth_factor) Init(2) Param Optimization
-Maximum allowed growth of number and total size of new parameters that ipa-sra replaces a pointer to an aggregate with.
+Maximum allowed growth of total size of new parameters that ipa-sra replaces a pointer to an aggregate with.
+
+-param=ipa-sra-ptrwrap-growth-factor=
+Common Joined UInteger Var(param_ipa_sra_ptrwrap_growth_factor) Init(4) IntegerRange(1, 8) Param Optimization
+Additional maximum allowed growth of total size of new parameters that ipa-sra replaces a pointer to an aggregate with, if it points to a local variable that the caller never writes to.
-param=ira-loop-reserved-regs=
Common Joined UInteger Var(param_ira_loop_reserved_regs) Init(2) Param Optimization
diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog
index 3a4f03c..acd36bf 100644
--- a/gcc/rust/ChangeLog
+++ b/gcc/rust/ChangeLog
@@ -1,3 +1,394 @@
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * CONTRIBUTING.md: New.
+ * README.md: New.
+ * logo.png: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * config-lang.in: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * lang.opt (-frust-incomplete-and-experimental-compiler-do-not-use):
+ New.
+ * rust-session-manager.cc (Session::compile_crate): Check it.
+ * Make-lang.in (RUST_SELFTEST_FLAGS): Add it.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * Make-lang.in: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * lang.opt: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * lang-specs.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * rust-lang.cc: New.
+ * rust-session-manager.cc: New.
+ * rust-session-manager.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * rustspec.cc: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * rust-diagnostics.cc: New.
+ * rust-diagnostics.h: New.
+ * rust-gcc-diagnostics.cc: New.
+ * rust-linemap.cc: New.
+ * rust-linemap.h: New.
+ * rust-location.h: New.
+ * rust-system.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+ David Faust <david.faust@oracle.com>
+ Faisal Abbas <90.abbasfaisal@gmail.com>
+
+ * backend/rust-compile-context.cc: New.
+ * backend/rust-compile-context.h: New.
+ * backend/rust-compile.cc: New.
+ * backend/rust-compile.h: New.
+ * backend/rust-constexpr.cc: New.
+ * backend/rust-constexpr.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+ David Faust <david.faust@oracle.com>
+
+ * backend/rust-compile-block.cc: New.
+ * backend/rust-compile-block.h: New.
+ * backend/rust-compile-expr.cc: New.
+ * backend/rust-compile-expr.h: New.
+ * backend/rust-compile-extern.h: New.
+ * backend/rust-compile-fnparam.cc: New.
+ * backend/rust-compile-fnparam.h: New.
+ * backend/rust-compile-implitem.cc: New.
+ * backend/rust-compile-implitem.h: New.
+ * backend/rust-compile-intrinsic.cc: New.
+ * backend/rust-compile-intrinsic.h: New.
+ * backend/rust-compile-item.cc: New.
+ * backend/rust-compile-item.h: New.
+ * backend/rust-compile-pattern.cc: New.
+ * backend/rust-compile-pattern.h: New.
+ * backend/rust-compile-resolve-path.cc: New.
+ * backend/rust-compile-resolve-path.h: New.
+ * backend/rust-compile-stmt.cc: New.
+ * backend/rust-compile-stmt.h: New.
+ * backend/rust-compile-struct-field-expr.cc: New.
+ * backend/rust-compile-struct-field-expr.h: New.
+ * backend/rust-compile-type.cc: New.
+ * backend/rust-compile-type.h: New.
+ * backend/rust-compile-var-decl.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+ David Faust <david.faust@oracle.com>
+
+ * backend/rust-builtins.h: New.
+ * backend/rust-compile-base.cc: New.
+ * backend/rust-compile-base.h: New.
+ * backend/rust-mangle.cc: New.
+ * backend/rust-mangle.h: New.
+ * backend/rust-tree.cc: New.
+ * backend/rust-tree.h: New.
+ * rust-backend.h: New.
+ * rust-gcc.cc: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * metadata/rust-export-metadata.cc: New.
+ * metadata/rust-export-metadata.h: New.
+ * metadata/rust-extern-crate.cc: New.
+ * metadata/rust-extern-crate.h: New.
+ * metadata/rust-import-archive.cc: New.
+ * metadata/rust-imports.cc: New.
+ * metadata/rust-imports.h: New.
+ * rust-object-export.cc: New.
+ * rust-object-export.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * checks/lints/rust-lint-unused-var.cc: New.
+ * checks/lints/rust-lint-unused-var.h: New.
+
+2022-12-13 Thomas Young <wenzhang5800@gmail.com>
+
+ * checks/lints/rust-lint-marklive-base.h: New.
+ * checks/lints/rust-lint-marklive.cc: New.
+ * checks/lints/rust-lint-marklive.h: New.
+ * checks/lints/rust-lint-scan-deadcode.h: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/errors/privacy/rust-privacy-check.cc: New.
+ * checks/errors/privacy/rust-privacy-check.h: New.
+ * checks/errors/privacy/rust-privacy-common.h: New.
+ * checks/errors/privacy/rust-privacy-ctx.cc: New.
+ * checks/errors/privacy/rust-privacy-ctx.h: New.
+ * checks/errors/privacy/rust-privacy-reporter.cc: New.
+ * checks/errors/privacy/rust-privacy-reporter.h: New.
+ * checks/errors/privacy/rust-pub-restricted-visitor.cc: New.
+ * checks/errors/privacy/rust-pub-restricted-visitor.h: New.
+ * checks/errors/privacy/rust-reachability.cc: New.
+ * checks/errors/privacy/rust-reachability.h: New.
+ * checks/errors/privacy/rust-visibility-resolver.cc: New.
+ * checks/errors/privacy/rust-visibility-resolver.h: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/errors/rust-const-checker.cc: New.
+ * checks/errors/rust-const-checker.h: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * checks/errors/rust-unsafe-checker.cc: New.
+ * checks/errors/rust-unsafe-checker.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * typecheck/rust-autoderef.cc: New.
+ * typecheck/rust-autoderef.h: New.
+ * typecheck/rust-casts.cc: New.
+ * typecheck/rust-casts.h: New.
+ * typecheck/rust-coercion.cc: New.
+ * typecheck/rust-coercion.h: New.
+ * typecheck/rust-hir-dot-operator.cc: New.
+ * typecheck/rust-hir-dot-operator.h: New.
+ * typecheck/rust-hir-inherent-impl-overlap.h: New.
+ * typecheck/rust-hir-path-probe.h: New.
+ * typecheck/rust-hir-trait-ref.h: New.
+ * typecheck/rust-hir-type-bounds.h: New.
+ * typecheck/rust-substitution-mapper.cc: New.
+ * typecheck/rust-substitution-mapper.h: New.
+ * typecheck/rust-tycheck-dump.h: New.
+ * typecheck/rust-tyctx.cc: New.
+ * typecheck/rust-tyty-bounds.cc: New.
+ * typecheck/rust-tyty-call.cc: New.
+ * typecheck/rust-tyty-call.h: New.
+ * typecheck/rust-tyty-cmp.h: New.
+ * typecheck/rust-tyty-rules.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * typecheck/rust-tyty.cc: New.
+ * typecheck/rust-tyty.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * typecheck/rust-hir-trait-resolve.cc: New.
+ * typecheck/rust-hir-trait-resolve.h: New.
+ * typecheck/rust-hir-type-check-base.cc: New.
+ * typecheck/rust-hir-type-check-base.h: New.
+ * typecheck/rust-hir-type-check-enumitem.cc: New.
+ * typecheck/rust-hir-type-check-enumitem.h: New.
+ * typecheck/rust-hir-type-check-expr.cc: New.
+ * typecheck/rust-hir-type-check-expr.h: New.
+ * typecheck/rust-hir-type-check-implitem.cc: New.
+ * typecheck/rust-hir-type-check-implitem.h: New.
+ * typecheck/rust-hir-type-check-item.cc: New.
+ * typecheck/rust-hir-type-check-item.h: New.
+ * typecheck/rust-hir-type-check-path.cc: New.
+ * typecheck/rust-hir-type-check-pattern.cc: New.
+ * typecheck/rust-hir-type-check-pattern.h: New.
+ * typecheck/rust-hir-type-check-stmt.cc: New.
+ * typecheck/rust-hir-type-check-stmt.h: New.
+ * typecheck/rust-hir-type-check-struct-field.h: New.
+ * typecheck/rust-hir-type-check-struct.cc: New.
+ * typecheck/rust-hir-type-check-toplevel.cc: New.
+ * typecheck/rust-hir-type-check-toplevel.h: New.
+ * typecheck/rust-hir-type-check-type.cc: New.
+ * typecheck/rust-hir-type-check-type.h: New.
+ * typecheck/rust-hir-type-check-util.cc: New.
+ * typecheck/rust-hir-type-check-util.h: New.
+ * typecheck/rust-hir-type-check.cc: New.
+ * typecheck/rust-hir-type-check.h: New.
+ * typecheck/rust-tyty-visitor.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * util/rust-canonical-path.h: New.
+ * util/rust-common.h: New.
+ * util/rust-hir-map.cc: New.
+ * util/rust-hir-map.h: New.
+ * util/rust-identifier.h: New.
+ * util/rust-lang-item.h: New.
+ * util/rust-mapping-common.h: New.
+ * util/rust-stacked-contexts.h: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-attributes.cc: New.
+ * util/rust-attributes.h: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-optional-test.cc: New.
+ * util/rust-optional.h: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * util/rust-base62.cc: New.
+ * util/rust-base62.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * util/rust-abi.cc: New.
+ * util/rust-abi.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * util/fnv-hash.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * util/rust-make-unique.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * hir/rust-ast-lower-base.cc: New.
+ * hir/rust-ast-lower-base.h: New.
+ * hir/rust-ast-lower-block.h: New.
+ * hir/rust-ast-lower-enumitem.h: New.
+ * hir/rust-ast-lower-expr.h: New.
+ * hir/rust-ast-lower-extern.h: New.
+ * hir/rust-ast-lower-implitem.h: New.
+ * hir/rust-ast-lower-item.cc: New.
+ * hir/rust-ast-lower-item.h: New.
+ * hir/rust-ast-lower-pattern.cc: New.
+ * hir/rust-ast-lower-pattern.h: New.
+ * hir/rust-ast-lower-stmt.h: New.
+ * hir/rust-ast-lower-struct-field-expr.h: New.
+ * hir/rust-ast-lower-type.h: New.
+ * hir/rust-ast-lower.cc: New.
+ * hir/rust-ast-lower.h: New.
+ * hir/rust-hir-dump.cc: New.
+ * hir/rust-hir-dump.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * hir/tree/rust-hir-full-decls.h: New.
+ * hir/tree/rust-hir-full-test.cc: New.
+ * hir/tree/rust-hir-full.h: New.
+ * hir/tree/rust-hir-visitor.h: New.
+ * hir/tree/rust-hir.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * hir/tree/rust-hir-expr.h: New.
+ * hir/tree/rust-hir-item.h: New.
+ * hir/tree/rust-hir-path.h: New.
+ * hir/tree/rust-hir-pattern.h: New.
+ * hir/tree/rust-hir-stmt.h: New.
+ * hir/tree/rust-hir-type.h: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * resolve/rust-ast-resolve-base.cc: New.
+ * resolve/rust-ast-resolve-base.h: New.
+ * resolve/rust-ast-resolve-expr.cc: New.
+ * resolve/rust-ast-resolve-expr.h: New.
+ * resolve/rust-ast-resolve-implitem.h: New.
+ * resolve/rust-ast-resolve-item.cc: New.
+ * resolve/rust-ast-resolve-item.h: New.
+ * resolve/rust-ast-resolve-path.cc: New.
+ * resolve/rust-ast-resolve-path.h: New.
+ * resolve/rust-ast-resolve-pattern.cc: New.
+ * resolve/rust-ast-resolve-pattern.h: New.
+ * resolve/rust-ast-resolve-stmt.cc: New.
+ * resolve/rust-ast-resolve-stmt.h: New.
+ * resolve/rust-ast-resolve-struct-expr-field.cc: New.
+ * resolve/rust-ast-resolve-struct-expr-field.h: New.
+ * resolve/rust-ast-resolve-toplevel.h: New.
+ * resolve/rust-ast-resolve-type.cc: New.
+ * resolve/rust-ast-resolve-type.h: New.
+ * resolve/rust-ast-resolve.cc: New.
+ * resolve/rust-ast-resolve.h: New.
+ * resolve/rust-ast-verify-assignee.h: New.
+ * resolve/rust-name-resolver.cc: New.
+ * resolve/rust-name-resolver.h: New.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+ Philip Herron <philip.herron@embecosm.com>
+ Joel Phillips <simplytheother@gmail.com>
+
+ * expand/rust-attribute-visitor.cc: New.
+ * expand/rust-attribute-visitor.h: New.
+ * expand/rust-macro-builtins.cc: New.
+ * expand/rust-macro-builtins.h: New.
+ * expand/rust-macro-expand.cc: New.
+ * expand/rust-macro-expand.h: New.
+ * expand/rust-macro-invoc-lexer.cc: New.
+ * expand/rust-macro-invoc-lexer.h: New.
+ * expand/rust-macro-substitute-ctx.cc: New.
+ * expand/rust-macro-substitute-ctx.h: New.
+
+2022-12-13 Joel Phillips <simplytheother@gmail.com>
+ Philip Herron <philip.herron@embecosm.com>
+ Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * parse/rust-parse-impl.h: New, second half.
+
+2022-12-13 Joel Phillips <simplytheother@gmail.com>
+ Philip Herron <philip.herron@embecosm.com>
+ Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * parse/rust-cfg-parser.cc: New.
+ * parse/rust-cfg-parser.h: New.
+ * parse/rust-parse-impl.h: New.
+ * parse/rust-parse.cc: New.
+ * parse/rust-parse.h: New.
+
+2022-12-13 Joel Phillips <simplytheother@gmail.com>
+ Philip Herron <philip.herron@embecosm.com>
+ Arthur Cohen <arthur.cohen@embecosm.com>
+ Mark Wielaard <mark@klomp.org>
+
+ * lex/rust-codepoint.h: New.
+ * lex/rust-lex.cc: New.
+ * lex/rust-lex.h: New.
+ * lex/rust-token.cc: New.
+ * lex/rust-token.h: New.
+ * rust-buffered-queue.h: New.
+
+2022-12-13 Joel Phillips <simplytheother@gmail.com>
+ Philip Herron <philip.herron@embecosm.com>
+ Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-dump.cc: New.
+ * ast/rust-ast-dump.h: New.
+ * ast/rust-ast-visitor.h: New.
+ * ast/rust-cond-compilation.h: New.
+
+2022-12-13 Joel Phillips <simplytheother@gmail.com>
+ Philip Herron <philip.herron@embecosm.com>
+
+ * ast/rust-expr.h: New.
+ * ast/rust-macro.h: New.
+ * ast/rust-path.h: New.
+ * ast/rust-pattern.h: New.
+ * ast/rust-stmt.h: New.
+ * ast/rust-type.h: New.
+
+2022-12-13 Joel Phillips <simplytheother@gmail.com>
+ Philip Herron <philip.herron@embecosm.com>
+
+ * ast/rust-item.h: New.
+
+2022-12-13 Joel Phillips <simplytheother@gmail.com>
+ Philip Herron <philip.herron@embecosm.com>
+ Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * ast/rust-ast-full-decls.h: New.
+ * ast/rust-ast-full-test.cc: New.
+ * ast/rust-ast-full.h: New.
+ * ast/rust-ast.h: New.
+ * operator.h: New.
+
Copyright (C) 2022 Free Software Foundation, Inc.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 643d903..c36a2ae 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,766 @@
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * gcc.dg/ipa/ipa-sra-26.c: New test.
+ * gcc.dg/ipa/ipa-sra-27.c: Likewise.
+ * gcc.dg/ipa/ipa-sra-28.c: Likewise.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * gfortran.dg/pr48636-2.f90: Disable IPA-SRA.
+ * gfortran.dg/ipa-sra-1.f90: New test.
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * gcc.dg/ipa/ipa-sra-25.c: New test
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ * g++.dg/ipa/ipa-sra-5.C: New test
+
+2022-12-13 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/103227
+ PR ipa/107640
+ * gcc.dg/ipa/pr107640-2.c: New test.
+
+2022-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/108044
+ * gcc.target/i386/pr108044-1.c: New test.
+ * gcc.target/i386/pr108044-2.c: New test.
+ * gcc.target/i386/pr108044-3.c: New test.
+ * gcc.target/i386/pr108044-4.c: New test.
+
+2022-12-13 Steve Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/107423
+ * gfortran.dg/pr107423.f90: New test.
+
+2022-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/108064
+ * gcc.c-torture/execute/pr108064.c: New test.
+
+2022-12-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/105801
+ * gcc.dg/tree-ssa/ssa-ccp-43.c: New testcase.
+
+2022-12-13 Arthur Cohen <arthur.cohen@embecosm.com>
+
+ * lib/rust.exp (rust_init): Add
+ '-frust-incomplete-and-experimental-compiler-do-not-use'.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+ Arthur Cohen <arthur.cohen@embecosm.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+ Mark Wielaard <mark@klomp.org>
+ Marc Poulhiès <dkm@kataplop.net>
+
+ * rust/execute/torture/block_expr1.rs: New.
+ * rust/execute/torture/builtin_macro_cfg.rs: New.
+ * rust/execute/torture/builtin_macro_concat.rs: New.
+ * rust/execute/torture/builtin_macro_env.rs: New.
+ * rust/execute/torture/builtin_macro_include_bytes.rs: New.
+ * rust/execute/torture/builtin_macro_include_str.rs: New.
+ * rust/execute/torture/builtin_macro_line.rs: New.
+ * rust/execute/torture/builtin_macros1.rs: New.
+ * rust/execute/torture/builtin_macros3.rs: New.
+ * rust/execute/torture/cfg1.rs: New.
+ * rust/execute/torture/cfg2.rs: New.
+ * rust/execute/torture/cfg3.rs: New.
+ * rust/execute/torture/cfg4.rs: New.
+ * rust/execute/torture/cfg5.rs: New.
+ * rust/execute/torture/coercion1.rs: New.
+ * rust/execute/torture/coercion2.rs: New.
+ * rust/execute/torture/const_fold1.rs: New.
+ * rust/execute/torture/const_fold2.rs: New.
+ * rust/execute/torture/copy_nonoverlapping1.rs: New.
+ * rust/execute/torture/empty_main.rs: New.
+ * rust/execute/torture/execute.exp: New.
+ * rust/execute/torture/exit_error.rs: New.
+ * rust/execute/torture/extern_mod4.rs: New.
+ * rust/execute/torture/func1.rs: New.
+ * rust/execute/torture/helloworld1.rs: New.
+ * rust/execute/torture/helloworld2.rs: New.
+ * rust/execute/torture/include.txt: New.
+ * rust/execute/torture/index1.rs: New.
+ * rust/execute/torture/issue-1120.rs: New.
+ * rust/execute/torture/issue-1133.rs: New.
+ * rust/execute/torture/issue-1198.rs: New.
+ * rust/execute/torture/issue-1231.rs: New.
+ * rust/execute/torture/issue-1232.rs: New.
+ * rust/execute/torture/issue-1249.rs: New.
+ * rust/execute/torture/issue-1436.rs: New.
+ * rust/execute/torture/issue-1496.rs: New.
+ * rust/execute/torture/issue-647.rs: New.
+ * rust/execute/torture/issue-845.rs: New.
+ * rust/execute/torture/issue-851.rs: New.
+ * rust/execute/torture/issue-858.rs: New.
+ * rust/execute/torture/issue-976.rs: New.
+ * rust/execute/torture/issue-995.rs: New.
+ * rust/execute/torture/macros1.rs: New.
+ * rust/execute/torture/macros10.rs: New.
+ * rust/execute/torture/macros11.rs: New.
+ * rust/execute/torture/macros12.rs: New.
+ * rust/execute/torture/macros13.rs: New.
+ * rust/execute/torture/macros14.rs: New.
+ * rust/execute/torture/macros16.rs: New.
+ * rust/execute/torture/macros17.rs: New.
+ * rust/execute/torture/macros18.rs: New.
+ * rust/execute/torture/macros19.rs: New.
+ * rust/execute/torture/macros2.rs: New.
+ * rust/execute/torture/macros20.rs: New.
+ * rust/execute/torture/macros21.rs: New.
+ * rust/execute/torture/macros22.rs: New.
+ * rust/execute/torture/macros23.rs: New.
+ * rust/execute/torture/macros24.rs: New.
+ * rust/execute/torture/macros25.rs: New.
+ * rust/execute/torture/macros26.rs: New.
+ * rust/execute/torture/macros27.rs: New.
+ * rust/execute/torture/macros28.rs: New.
+ * rust/execute/torture/macros29.rs: New.
+ * rust/execute/torture/macros3.rs: New.
+ * rust/execute/torture/macros30.rs: New.
+ * rust/execute/torture/macros31.rs: New.
+ * rust/execute/torture/macros4.rs: New.
+ * rust/execute/torture/macros5.rs: New.
+ * rust/execute/torture/macros6.rs: New.
+ * rust/execute/torture/macros7.rs: New.
+ * rust/execute/torture/macros8.rs: New.
+ * rust/execute/torture/macros9.rs: New.
+ * rust/execute/torture/match1.rs: New.
+ * rust/execute/torture/match2.rs: New.
+ * rust/execute/torture/match3.rs: New.
+ * rust/execute/torture/match_bool1.rs: New.
+ * rust/execute/torture/match_byte1.rs: New.
+ * rust/execute/torture/match_char1.rs: New.
+ * rust/execute/torture/match_int1.rs: New.
+ * rust/execute/torture/match_loop1.rs: New.
+ * rust/execute/torture/match_range1.rs: New.
+ * rust/execute/torture/match_range2.rs: New.
+ * rust/execute/torture/match_tuple1.rs: New.
+ * rust/execute/torture/method1.rs: New.
+ * rust/execute/torture/method2.rs: New.
+ * rust/execute/torture/method3.rs: New.
+ * rust/execute/torture/method4.rs: New.
+ * rust/execute/torture/mod1.rs: New.
+ * rust/execute/torture/modules/mod.rs: New.
+ * rust/execute/torture/operator_overload_1.rs: New.
+ * rust/execute/torture/operator_overload_10.rs: New.
+ * rust/execute/torture/operator_overload_11.rs: New.
+ * rust/execute/torture/operator_overload_12.rs: New.
+ * rust/execute/torture/operator_overload_2.rs: New.
+ * rust/execute/torture/operator_overload_3.rs: New.
+ * rust/execute/torture/operator_overload_4.rs: New.
+ * rust/execute/torture/operator_overload_5.rs: New.
+ * rust/execute/torture/operator_overload_6.rs: New.
+ * rust/execute/torture/operator_overload_7.rs: New.
+ * rust/execute/torture/operator_overload_8.rs: New.
+ * rust/execute/torture/operator_overload_9.rs: New.
+ * rust/execute/torture/slice-magic.rs: New.
+ * rust/execute/torture/slice-magic2.rs: New.
+ * rust/execute/torture/slice1.rs: New.
+ * rust/execute/torture/str-layout1.rs: New.
+ * rust/execute/torture/str-zero.rs: New.
+ * rust/execute/torture/trait1.rs: New.
+ * rust/execute/torture/trait10.rs: New.
+ * rust/execute/torture/trait11.rs: New.
+ * rust/execute/torture/trait12.rs: New.
+ * rust/execute/torture/trait13.rs: New.
+ * rust/execute/torture/trait2.rs: New.
+ * rust/execute/torture/trait3.rs: New.
+ * rust/execute/torture/trait4.rs: New.
+ * rust/execute/torture/trait5.rs: New.
+ * rust/execute/torture/trait6.rs: New.
+ * rust/execute/torture/trait7.rs: New.
+ * rust/execute/torture/trait8.rs: New.
+ * rust/execute/torture/trait9.rs: New.
+ * rust/execute/torture/transmute1.rs: New.
+ * rust/execute/torture/wrapping_op1.rs: New.
+ * rust/execute/torture/wrapping_op2.rs: New.
+ * rust/execute/xfail/macro1.rs: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+ Arthur Cohen <arthur.cohen@embecosm.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+ Mark Wielaard <mark@klomp.org>
+ Marc Poulhiès <dkm@kataplop.net>
+
+ * rust/compile/abi-options1.rs: New.
+ * rust/compile/array3.rs: New.
+ * rust/compile/array_empty_list.rs: New.
+ * rust/compile/arrays1.rs: New.
+ * rust/compile/arrays2.rs: New.
+ * rust/compile/attr-mismatch-crate-name.rs: New.
+ * rust/compile/attr_cold.rs: New.
+ * rust/compile/attr_deprecated.rs: New.
+ * rust/compile/attr_deprecated_2.rs: New.
+ * rust/compile/bad-crate-name.rs: New.
+ * rust/compile/bad=file-name.rs: New.
+ * rust/compile/bad_as_bool_char.rs: New.
+ * rust/compile/bad_file_name.txt.rs: New.
+ * rust/compile/bad_inner_doc.rs: New.
+ * rust/compile/bad_pub_enumitems.rs: New.
+ * rust/compile/bad_stmt_enums.rs: New.
+ * rust/compile/bad_toplevel_enums.rs: New.
+ * rust/compile/bad_tuple_index.rs: New.
+ * rust/compile/bad_type1.rs: New.
+ * rust/compile/bad_type2.rs: New.
+ * rust/compile/break1.rs: New.
+ * rust/compile/break2.rs: New.
+ * rust/compile/builtin_macro_compile_error.rs: New.
+ * rust/compile/builtin_macro_concat.rs: New.
+ * rust/compile/builtin_macro_env.rs: New.
+ * rust/compile/builtin_macro_include_bytes.rs: New.
+ * rust/compile/builtin_macro_include_str.rs: New.
+ * rust/compile/builtin_macro_not_found.rs: New.
+ * rust/compile/bytecharstring.rs: New.
+ * rust/compile/canonical_paths1.rs: New.
+ * rust/compile/cast1.rs: New.
+ * rust/compile/cfg1.rs: New.
+ * rust/compile/cfg2.rs: New.
+ * rust/compile/cfg3.rs: New.
+ * rust/compile/cfg4.rs: New.
+ * rust/compile/cfg5.rs: New.
+ * rust/compile/compile.exp: New.
+ * rust/compile/complex-path1.rs: New.
+ * rust/compile/const-issue1440.rs: New.
+ * rust/compile/const1.rs: New.
+ * rust/compile/const2.rs: New.
+ * rust/compile/const3.rs: New.
+ * rust/compile/const_generics_1.rs: New.
+ * rust/compile/const_generics_2.rs: New.
+ * rust/compile/const_generics_3.rs: New.
+ * rust/compile/const_generics_4.rs: New.
+ * rust/compile/const_generics_5.rs: New.
+ * rust/compile/const_generics_6.rs: New.
+ * rust/compile/continue1.rs: New.
+ * rust/compile/deadcode_err1.rs: New.
+ * rust/compile/deadcode_err2.rs: New.
+ * rust/compile/debug-diagnostics-default.rs: New.
+ * rust/compile/debug-diagnostics-off.rs: New.
+ * rust/compile/debug-diagnostics-on.rs: New.
+ * rust/compile/doc_isolated_cr_block_comment.rs: New.
+ * rust/compile/doc_isolated_cr_inner_block_comment.rs: New.
+ * rust/compile/doc_isolated_cr_inner_line_comment.rs: New.
+ * rust/compile/doc_isolated_cr_line_comment.rs: New.
+ * rust/compile/dup_fields.rs: New.
+ * rust/compile/empty_comment_before_match.rs: New.
+ * rust/compile/expected_type_args2.rs: New.
+ * rust/compile/expected_type_args3.rs: New.
+ * rust/compile/func1.rs: New.
+ * rust/compile/func2.rs: New.
+ * rust/compile/func3.rs: New.
+ * rust/compile/func4.rs: New.
+ * rust/compile/func5.rs: New.
+ * rust/compile/generic-default1.rs: New.
+ * rust/compile/generics1.rs: New.
+ * rust/compile/generics10.rs: New.
+ * rust/compile/generics11.rs: New.
+ * rust/compile/generics12.rs: New.
+ * rust/compile/generics13.rs: New.
+ * rust/compile/generics2.rs: New.
+ * rust/compile/generics3.rs: New.
+ * rust/compile/generics4.rs: New.
+ * rust/compile/generics5.rs: New.
+ * rust/compile/generics6.rs: New.
+ * rust/compile/generics7.rs: New.
+ * rust/compile/generics8.rs: New.
+ * rust/compile/generics9.rs: New.
+ * rust/compile/implicit_returns_err1.rs: New.
+ * rust/compile/implicit_returns_err2.rs: New.
+ * rust/compile/implicit_returns_err3.rs: New.
+ * rust/compile/implicit_returns_err4.rs: New.
+ * rust/compile/infer-crate-name.rs: New.
+ * rust/compile/inline_1.rs: New.
+ * rust/compile/inline_2.rs: New.
+ * rust/compile/issue-1005.rs: New.
+ * rust/compile/issue-1019.rs: New.
+ * rust/compile/issue-1023.rs: New.
+ * rust/compile/issue-1031.rs: New.
+ * rust/compile/issue-1034.rs: New.
+ * rust/compile/issue-1089.rs: New.
+ * rust/compile/issue-1128.rs: New.
+ * rust/compile/issue-1129-1.rs: New.
+ * rust/compile/issue-1129-2.rs: New.
+ * rust/compile/issue-1130.rs: New.
+ * rust/compile/issue-1131.rs: New.
+ * rust/compile/issue-1152.rs: New.
+ * rust/compile/issue-1165.rs: New.
+ * rust/compile/issue-1173.rs: New.
+ * rust/compile/issue-1226.rs: New.
+ * rust/compile/issue-1234.rs: New.
+ * rust/compile/issue-1235.rs: New.
+ * rust/compile/issue-1237.rs: New.
+ * rust/compile/issue-1251.rs: New.
+ * rust/compile/issue-1271.rs: New.
+ * rust/compile/issue-1289.rs: New.
+ * rust/compile/issue-1323-1.rs: New.
+ * rust/compile/issue-1323-2.rs: New.
+ * rust/compile/issue-1383.rs: New.
+ * rust/compile/issue-1393.rs: New.
+ * rust/compile/issue-1447.rs: New.
+ * rust/compile/issue-407-2.rs: New.
+ * rust/compile/issue-407.rs: New.
+ * rust/compile/issue-557.rs: New.
+ * rust/compile/issue-635-1.rs: New.
+ * rust/compile/issue-635-2.rs: New.
+ * rust/compile/lookup_err1.rs: New.
+ * rust/compile/macro-issue1053-2.rs: New.
+ * rust/compile/macro-issue1053.rs: New.
+ * rust/compile/macro-issue1224.rs: New.
+ * rust/compile/macro-issue1233.rs: New.
+ * rust/compile/macro-issue1395-2.rs: New.
+ * rust/compile/macro-issue1395.rs: New.
+ * rust/compile/macro-issue1400-2.rs: New.
+ * rust/compile/macro-issue1400.rs: New.
+ * rust/compile/macro1.rs: New.
+ * rust/compile/macro10.rs: New.
+ * rust/compile/macro11.rs: New.
+ * rust/compile/macro12.rs: New.
+ * rust/compile/macro13.rs: New.
+ * rust/compile/macro14.rs: New.
+ * rust/compile/macro15.rs: New.
+ * rust/compile/macro16.rs: New.
+ * rust/compile/macro17.rs: New.
+ * rust/compile/macro18.rs: New.
+ * rust/compile/macro19.rs: New.
+ * rust/compile/macro2.rs: New.
+ * rust/compile/macro20.rs: New.
+ * rust/compile/macro21.rs: New.
+ * rust/compile/macro22.rs: New.
+ * rust/compile/macro23.rs: New.
+ * rust/compile/macro25.rs: New.
+ * rust/compile/macro26.rs: New.
+ * rust/compile/macro27.rs: New.
+ * rust/compile/macro28.rs: New.
+ * rust/compile/macro29.rs: New.
+ * rust/compile/macro3.rs: New.
+ * rust/compile/macro30.rs: New.
+ * rust/compile/macro31.rs: New.
+ * rust/compile/macro32.rs: New.
+ * rust/compile/macro33.rs: New.
+ * rust/compile/macro34.rs: New.
+ * rust/compile/macro35.rs: New.
+ * rust/compile/macro36.rs: New.
+ * rust/compile/macro37.rs: New.
+ * rust/compile/macro38.rs: New.
+ * rust/compile/macro39.rs: New.
+ * rust/compile/macro4.rs: New.
+ * rust/compile/macro40.rs: New.
+ * rust/compile/macro41.rs: New.
+ * rust/compile/macro42.rs: New.
+ * rust/compile/macro5.rs: New.
+ * rust/compile/macro6.rs: New.
+ * rust/compile/macro7.rs: New.
+ * rust/compile/macro8.rs: New.
+ * rust/compile/macro9.rs: New.
+ * rust/compile/macro_return.rs: New.
+ * rust/compile/match1.rs: New.
+ * rust/compile/match2.rs: New.
+ * rust/compile/match3.rs: New.
+ * rust/compile/match4.rs: New.
+ * rust/compile/match5.rs: New.
+ * rust/compile/match6.rs: New.
+ * rust/compile/match7.rs: New.
+ * rust/compile/method1.rs: New.
+ * rust/compile/method2.rs: New.
+ * rust/compile/mismatch-crate-name.rs: New.
+ * rust/compile/missing_middle/both_path.rs: New.
+ * rust/compile/missing_middle/explicit.not.rs: New.
+ * rust/compile/missing_middle/inner_path.rs: New.
+ * rust/compile/missing_middle/other.rs: New.
+ * rust/compile/missing_middle/outer_path.rs: New.
+ * rust/compile/missing_middle/sub/mod.rs: New.
+ * rust/compile/missing_return1.rs: New.
+ * rust/compile/mod_missing_middle.rs: New.
+ * rust/compile/never_type_err1.rs: New.
+ * rust/compile/privacy1.rs: New.
+ * rust/compile/privacy2.rs: New.
+ * rust/compile/privacy3.rs: New.
+ * rust/compile/privacy4.rs: New.
+ * rust/compile/privacy5.rs: New.
+ * rust/compile/privacy6.rs: New.
+ * rust/compile/pub_restricted_1.rs: New.
+ * rust/compile/pub_restricted_2.rs: New.
+ * rust/compile/pub_restricted_3.rs: New.
+ * rust/compile/raw_identifiers_bad_keywords.rs: New.
+ * rust/compile/raw_identifiers_underscore.rs: New.
+ * rust/compile/redef_error1.rs: New.
+ * rust/compile/redef_error2.rs: New.
+ * rust/compile/redef_error3.rs: New.
+ * rust/compile/redef_error4.rs: New.
+ * rust/compile/redef_error5.rs: New.
+ * rust/compile/redef_error6.rs: New.
+ * rust/compile/reference1.rs: New.
+ * rust/compile/self-path1.rs: New.
+ * rust/compile/self-path2.rs: New.
+ * rust/compile/shadow1.rs: New.
+ * rust/compile/specify-crate-name.rs: New.
+ * rust/compile/static_var1.rs: New.
+ * rust/compile/stmt_with_block_err1.rs: New.
+ * rust/compile/struct_align1.rs: New.
+ * rust/compile/struct_align2.rs: New.
+ * rust/compile/struct_init1.rs: New.
+ * rust/compile/struct_pack1.rs: New.
+ * rust/compile/struct_pack2.rs: New.
+ * rust/compile/syntax-only.rs: New.
+ * rust/compile/test_mod.rs: New.
+ * rust/compile/torture/all_doc_comment_line_blocks.rs: New.
+ * rust/compile/torture/all_doc_comment_line_blocks_crlf.rs: New.
+ * rust/compile/torture/arithmetic_expressions1.rs: New.
+ * rust/compile/torture/array_const_fold_1.rs: New.
+ * rust/compile/torture/array_const_fold_2.rs: New.
+ * rust/compile/torture/array_function.rs: New.
+ * rust/compile/torture/array_type_infer.rs: New.
+ * rust/compile/torture/array_zero_length.rs: New.
+ * rust/compile/torture/arrays1.rs: New.
+ * rust/compile/torture/arrays2.rs: New.
+ * rust/compile/torture/arrays3.rs: New.
+ * rust/compile/torture/arrays4.rs: New.
+ * rust/compile/torture/arrays5.rs: New.
+ * rust/compile/torture/arrays6.rs: New.
+ * rust/compile/torture/arrays_index1.rs: New.
+ * rust/compile/torture/arrays_index2.rs: New.
+ * rust/compile/torture/arrays_index3.rs: New.
+ * rust/compile/torture/as_bool_char.rs: New.
+ * rust/compile/torture/associated_types1.rs: New.
+ * rust/compile/torture/autoderef1.rs: New.
+ * rust/compile/torture/block_expr1.rs: New.
+ * rust/compile/torture/block_expr2.rs: New.
+ * rust/compile/torture/block_expr3.rs: New.
+ * rust/compile/torture/block_expr4.rs: New.
+ * rust/compile/torture/block_expr5.rs: New.
+ * rust/compile/torture/block_expr_parser_bug.rs: New.
+ * rust/compile/torture/bom.rs: New.
+ * rust/compile/torture/bom_comment.rs: New.
+ * rust/compile/torture/bom_shebang.rs: New.
+ * rust/compile/torture/bom_whitespace.rs: New.
+ * rust/compile/torture/bools_eq.rs: New.
+ * rust/compile/torture/borrow1.rs: New.
+ * rust/compile/torture/borrow_function.rs: New.
+ * rust/compile/torture/break_function.rs: New.
+ * rust/compile/torture/byte_char_str.rs: New.
+ * rust/compile/torture/byte_str.rs: New.
+ * rust/compile/torture/cast1.rs: New.
+ * rust/compile/torture/cast2.rs: New.
+ * rust/compile/torture/cast3.rs: New.
+ * rust/compile/torture/cfg_attr.rs: New.
+ * rust/compile/torture/char1.rs: New.
+ * rust/compile/torture/check-doc-attr-string.rs: New.
+ * rust/compile/torture/coercion1.rs: New.
+ * rust/compile/torture/coercion2.rs: New.
+ * rust/compile/torture/comparison_expr1.rs: New.
+ * rust/compile/torture/compile.exp: New.
+ * rust/compile/torture/compound_assignment_expr1.rs: New.
+ * rust/compile/torture/conditional.rs: New.
+ * rust/compile/torture/constant1.rs: New.
+ * rust/compile/torture/constant2.rs: New.
+ * rust/compile/torture/constant3.rs: New.
+ * rust/compile/torture/deadcode1.rs: New.
+ * rust/compile/torture/deadcode2.rs: New.
+ * rust/compile/torture/deref1.rs: New.
+ * rust/compile/torture/deref_function.rs: New.
+ * rust/compile/torture/doc_comment.rs: New.
+ * rust/compile/torture/enum1.rs: New.
+ * rust/compile/torture/extern_mod1.rs: New.
+ * rust/compile/torture/extern_mod2.rs: New.
+ * rust/compile/torture/float1.rs: New.
+ * rust/compile/torture/float_types.rs: New.
+ * rust/compile/torture/forward_decl_1.rs: New.
+ * rust/compile/torture/forward_decl_2.rs: New.
+ * rust/compile/torture/forward_decl_3-unsafe.rs: New.
+ * rust/compile/torture/forward_decl_3.rs: New.
+ * rust/compile/torture/forward_decl_4.rs: New.
+ * rust/compile/torture/forward_decl_5.rs: New.
+ * rust/compile/torture/func1.rs: New.
+ * rust/compile/torture/func2.rs: New.
+ * rust/compile/torture/function_reference1.rs: New.
+ * rust/compile/torture/function_reference2.rs: New.
+ * rust/compile/torture/function_reference3.rs: New.
+ * rust/compile/torture/function_reference4.rs: New.
+ * rust/compile/torture/generics1.rs: New.
+ * rust/compile/torture/generics10.rs: New.
+ * rust/compile/torture/generics11.rs: New.
+ * rust/compile/torture/generics12.rs: New.
+ * rust/compile/torture/generics13.rs: New.
+ * rust/compile/torture/generics14.rs: New.
+ * rust/compile/torture/generics15.rs: New.
+ * rust/compile/torture/generics16.rs: New.
+ * rust/compile/torture/generics17.rs: New.
+ * rust/compile/torture/generics18.rs: New.
+ * rust/compile/torture/generics19.rs: New.
+ * rust/compile/torture/generics2.rs: New.
+ * rust/compile/torture/generics20.rs: New.
+ * rust/compile/torture/generics21.rs: New.
+ * rust/compile/torture/generics22.rs: New.
+ * rust/compile/torture/generics23.rs: New.
+ * rust/compile/torture/generics24.rs: New.
+ * rust/compile/torture/generics25.rs: New.
+ * rust/compile/torture/generics26.rs: New.
+ * rust/compile/torture/generics27.rs: New.
+ * rust/compile/torture/generics28.rs: New.
+ * rust/compile/torture/generics29.rs: New.
+ * rust/compile/torture/generics3.rs: New.
+ * rust/compile/torture/generics30.rs: New.
+ * rust/compile/torture/generics31.rs: New.
+ * rust/compile/torture/generics32.rs: New.
+ * rust/compile/torture/generics4.rs: New.
+ * rust/compile/torture/generics5.rs: New.
+ * rust/compile/torture/generics6.rs: New.
+ * rust/compile/torture/generics7.rs: New.
+ * rust/compile/torture/generics8.rs: New.
+ * rust/compile/torture/generics9.rs: New.
+ * rust/compile/torture/grouped_expr_function.rs: New.
+ * rust/compile/torture/identifier-missing-impl-1.rs: New.
+ * rust/compile/torture/if.rs: New.
+ * rust/compile/torture/if_elif.rs: New.
+ * rust/compile/torture/if_elif_else_expr1.rs: New.
+ * rust/compile/torture/if_else.rs: New.
+ * rust/compile/torture/ifunaryexpr.rs: New.
+ * rust/compile/torture/impl_block1.rs: New.
+ * rust/compile/torture/impl_block2.rs: New.
+ * rust/compile/torture/impl_block3.rs: New.
+ * rust/compile/torture/impl_block_unused.rs: New.
+ * rust/compile/torture/implicit_returns1.rs: New.
+ * rust/compile/torture/infer_type1.rs: New.
+ * rust/compile/torture/inner_attributes.rs: New.
+ * rust/compile/torture/integer_inference_var1.rs: New.
+ * rust/compile/torture/integer_inference_var2.rs: New.
+ * rust/compile/torture/integer_inference_var3.rs: New.
+ * rust/compile/torture/integer_inference_var4.rs: New.
+ * rust/compile/torture/integer_inference_var5.rs: New.
+ * rust/compile/torture/integer_types.rs: New.
+ * rust/compile/torture/intrinsics-1.rs: New.
+ * rust/compile/torture/intrinsics-2.rs: New.
+ * rust/compile/torture/isolated_cr_block_comment.rs: New.
+ * rust/compile/torture/isolated_cr_line_comment.rs: New.
+ * rust/compile/torture/issue-1024.rs: New.
+ * rust/compile/torture/issue-1075.rs: New.
+ * rust/compile/torture/issue-1432.rs: New.
+ * rust/compile/torture/issue-1434.rs: New.
+ * rust/compile/torture/issue-368.rs: New.
+ * rust/compile/torture/issue-808.rs: New.
+ * rust/compile/torture/issue-862.rs: New.
+ * rust/compile/torture/issue-893-2.rs: New.
+ * rust/compile/torture/issue-893.rs: New.
+ * rust/compile/torture/lazybooleanexpr_function.rs: New.
+ * rust/compile/torture/lifetime1.rs: New.
+ * rust/compile/torture/literals1.rs: New.
+ * rust/compile/torture/loop1.rs: New.
+ * rust/compile/torture/loop2.rs: New.
+ * rust/compile/torture/loop3.rs: New.
+ * rust/compile/torture/loop4.rs: New.
+ * rust/compile/torture/loop5.rs: New.
+ * rust/compile/torture/loop6.rs: New.
+ * rust/compile/torture/loop7.rs: New.
+ * rust/compile/torture/macro-issue1403.rs: New.
+ * rust/compile/torture/macro-issue1426.rs: New.
+ * rust/compile/torture/macro_as_expr.rs: New.
+ * rust/compile/torture/match1.rs: New.
+ * rust/compile/torture/methods1.rs: New.
+ * rust/compile/torture/methods2.rs: New.
+ * rust/compile/torture/methods3.rs: New.
+ * rust/compile/torture/mod-nameresolve.rs: New.
+ * rust/compile/torture/mod1.rs: New.
+ * rust/compile/torture/mod2.rs: New.
+ * rust/compile/torture/mod3.rs: New.
+ * rust/compile/torture/modules/mod.rs: New.
+ * rust/compile/torture/modules/valid_path.rs: New.
+ * rust/compile/torture/must_use1.rs: New.
+ * rust/compile/torture/must_use2.rs: New.
+ * rust/compile/torture/name_resolve1.rs: New.
+ * rust/compile/torture/negation_function.rs: New.
+ * rust/compile/torture/nested_fn1.rs: New.
+ * rust/compile/torture/nested_fn2.rs: New.
+ * rust/compile/torture/nested_struct1.rs: New.
+ * rust/compile/torture/never_type1.rs: New.
+ * rust/compile/torture/not_shebang.rs: New.
+ * rust/compile/torture/not_shebang_block_comment.rs: New.
+ * rust/compile/torture/not_shebang_comment.rs: New.
+ * rust/compile/torture/not_shebang_multiline_comment.rs: New.
+ * rust/compile/torture/not_shebang_spaces.rs: New.
+ * rust/compile/torture/parameter_usage1.rs: New.
+ * rust/compile/torture/parens1.rs: New.
+ * rust/compile/torture/pointer1.rs: New.
+ * rust/compile/torture/primconsts.rs: New.
+ * rust/compile/torture/prims_struct_eq.rs: New.
+ * rust/compile/torture/range-lang-item1.rs: New.
+ * rust/compile/torture/raw_identifiers.rs: New.
+ * rust/compile/torture/raw_identifiers_keywords.rs: New.
+ * rust/compile/torture/recursive_fn1.rs: New.
+ * rust/compile/torture/return_function.rs: New.
+ * rust/compile/torture/scoping1.rs: New.
+ * rust/compile/torture/self_type1.rs: New.
+ * rust/compile/torture/shadow1.rs: New.
+ * rust/compile/torture/shadow2.rs: New.
+ * rust/compile/torture/shebang.rs: New.
+ * rust/compile/torture/shebang_plus_attr.rs: New.
+ * rust/compile/torture/shebang_plus_attr2.rs: New.
+ * rust/compile/torture/static_function.rs: New.
+ * rust/compile/torture/static_var1.rs: New.
+ * rust/compile/torture/stmt_with_block1.rs: New.
+ * rust/compile/torture/str1.rs: New.
+ * rust/compile/torture/struct_access1.rs: New.
+ * rust/compile/torture/struct_base_init_1.rs: New.
+ * rust/compile/torture/struct_decl.rs: New.
+ * rust/compile/torture/struct_init.rs: New.
+ * rust/compile/torture/struct_init_10.rs: New.
+ * rust/compile/torture/struct_init_11.rs: New.
+ * rust/compile/torture/struct_init_2.rs: New.
+ * rust/compile/torture/struct_init_3.rs: New.
+ * rust/compile/torture/struct_init_4.rs: New.
+ * rust/compile/torture/struct_init_5.rs: New.
+ * rust/compile/torture/struct_init_6.rs: New.
+ * rust/compile/torture/struct_init_7.rs: New.
+ * rust/compile/torture/struct_init_8.rs: New.
+ * rust/compile/torture/struct_init_9.rs: New.
+ * rust/compile/torture/top_attr.rs: New.
+ * rust/compile/torture/traits1.rs: New.
+ * rust/compile/torture/traits10.rs: New.
+ * rust/compile/torture/traits11.rs: New.
+ * rust/compile/torture/traits12.rs: New.
+ * rust/compile/torture/traits13.rs: New.
+ * rust/compile/torture/traits14.rs: New.
+ * rust/compile/torture/traits15.rs: New.
+ * rust/compile/torture/traits16.rs: New.
+ * rust/compile/torture/traits17.rs: New.
+ * rust/compile/torture/traits18.rs: New.
+ * rust/compile/torture/traits19.rs: New.
+ * rust/compile/torture/traits2.rs: New.
+ * rust/compile/torture/traits3.rs: New.
+ * rust/compile/torture/traits4.rs: New.
+ * rust/compile/torture/traits5.rs: New.
+ * rust/compile/torture/traits6.rs: New.
+ * rust/compile/torture/traits7.rs: New.
+ * rust/compile/torture/traits8.rs: New.
+ * rust/compile/torture/traits9.rs: New.
+ * rust/compile/torture/transmute-size-check-1.rs: New.
+ * rust/compile/torture/transmute1.rs: New.
+ * rust/compile/torture/tuple1.rs: New.
+ * rust/compile/torture/tuple2.rs: New.
+ * rust/compile/torture/tuple3.rs: New.
+ * rust/compile/torture/tuple_enum_variants.rs: New.
+ * rust/compile/torture/tuple_field_access.rs: New.
+ * rust/compile/torture/tuple_function.rs: New.
+ * rust/compile/torture/tuple_index.rs: New.
+ * rust/compile/torture/tuple_struct1.rs: New.
+ * rust/compile/torture/tuple_struct2.rs: New.
+ * rust/compile/torture/tuple_struct_unit.rs: New.
+ * rust/compile/torture/tuple_struct_unused.rs: New.
+ * rust/compile/torture/type-alias1.rs: New.
+ * rust/compile/torture/type-alias2.rs: New.
+ * rust/compile/torture/type_infer1.rs: New.
+ * rust/compile/torture/type_infer2.rs: New.
+ * rust/compile/torture/type_infer3.rs: New.
+ * rust/compile/torture/type_infer4.rs: New.
+ * rust/compile/torture/type_infer5.rs: New.
+ * rust/compile/torture/type_infer6.rs: New.
+ * rust/compile/torture/unary_operators.rs: New.
+ * rust/compile/torture/undended-string-1.rs: New.
+ * rust/compile/torture/undended-string-2.rs: New.
+ * rust/compile/torture/underscore_id.rs: New.
+ * rust/compile/torture/union.rs: New.
+ * rust/compile/torture/union_union.rs: New.
+ * rust/compile/torture/unit_type1.rs: New.
+ * rust/compile/torture/unit_type2.rs: New.
+ * rust/compile/torture/unit_type3.rs: New.
+ * rust/compile/torture/unit_type4.rs: New.
+ * rust/compile/torture/unit_type5.rs: New.
+ * rust/compile/torture/unsafe1.rs: New.
+ * rust/compile/torture/unsafe2.rs: New.
+ * rust/compile/torture/unsafe3.rs: New.
+ * rust/compile/torture/unsafe4.rs: New.
+ * rust/compile/torture/unused.rs: New.
+ * rust/compile/torture/unused1.rs: New.
+ * rust/compile/torture/unused_struct.rs: New.
+ * rust/compile/torture/unused_struct_field.rs: New.
+ * rust/compile/torture/usize1.rs: New.
+ * rust/compile/torture/very-broken-attr-string.rs: New.
+ * rust/compile/torture/while_function.rs: New.
+ * rust/compile/traits1.rs: New.
+ * rust/compile/traits10.rs: New.
+ * rust/compile/traits11.rs: New.
+ * rust/compile/traits12.rs: New.
+ * rust/compile/traits2.rs: New.
+ * rust/compile/traits3.rs: New.
+ * rust/compile/traits4.rs: New.
+ * rust/compile/traits5.rs: New.
+ * rust/compile/traits6.rs: New.
+ * rust/compile/traits7.rs: New.
+ * rust/compile/traits8.rs: New.
+ * rust/compile/traits9.rs: New.
+ * rust/compile/tuple1.rs: New.
+ * rust/compile/tuple_struct1.rs: New.
+ * rust/compile/tuple_struct2.rs: New.
+ * rust/compile/tuple_struct3.rs: New.
+ * rust/compile/type-alias1.rs: New.
+ * rust/compile/type-bindings1.rs: New.
+ * rust/compile/unary_negation.rs: New.
+ * rust/compile/unary_not.rs: New.
+ * rust/compile/unconstrained_type_param.rs: New.
+ * rust/compile/unicode_escape.rs: New.
+ * rust/compile/unsafe1.rs: New.
+ * rust/compile/unsafe10.rs: New.
+ * rust/compile/unsafe2.rs: New.
+ * rust/compile/unsafe3.rs: New.
+ * rust/compile/unsafe4.rs: New.
+ * rust/compile/unsafe5.rs: New.
+ * rust/compile/unsafe6.rs: New.
+ * rust/compile/unsafe7.rs: New.
+ * rust/compile/unsafe8.rs: New.
+ * rust/compile/unsafe9.rs: New.
+ * rust/compile/unterminated_c_comment.rs: New.
+ * rust/compile/use_1.rs: New.
+ * rust/compile/usize1.rs: New.
+ * rust/compile/xfail/lifetime_param.rs: New.
+ * rust/compile/xfail/struct_field_vis.rs: New.
+ * rust/compile/xfail/xfail.exp: New.
+ * rust/compile/rawbytestring.rs: New file.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+
+ * rust/link/generic_function_0.rs: New.
+ * rust/link/generic_function_1.rs: New.
+ * rust/link/link.exp: New.
+ * rust/link/simple_function_0.rs: New.
+ * rust/link/simple_function_1.rs: New.
+ * rust/link/trait_import_0.rs: New.
+ * rust/link/trait_import_1.rs: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+ Tom Tromey <tom@tromey.com>
+ Mark Wielaard <mark@klomp.org>
+ Marc Poulhiès <dkm@kataplop.net>
+
+ * rust/debug/chartype.rs: New.
+ * rust/debug/custom_link_section.rs: New.
+ * rust/debug/debug.exp: New.
+ * rust/debug/i8u8.rs: New.
+ * rust/debug/lang.rs: New.
+ * rust/debug/no_mangle.rs: New.
+ * rust/debug/oldlang.rs: New.
+ * rust/debug/tuple.rs: New.
+ * rust/debug/win64-abi.rs: New.
+
+2022-12-13 Philip Herron <philip.herron@embecosm.com>
+ Marc Poulhiès <dkm@kataplop.net>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * lib/rust-dg.exp: New.
+ * lib/rust.exp: New.
+
+2022-12-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/108076
+ * gcc.dg/torture/pr108076.c: New testcase.
+
+2022-12-13 Haochen Gui <guihaoc@gcc.gnu.org>
+
+ * gcc.target/powerpc/cbranchcc4-1.c: New.
+ * gcc.target/powerpc/cbranchcc4-2.c: New.
+
2022-12-12 Jason Merrill <jason@redhat.com>
Revert:
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-sra-5.C b/gcc/testsuite/g++.dg/ipa/ipa-sra-5.C
new file mode 100644
index 0000000..26a221e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/ipa-sra-5.C
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-sra" } */
+
+volatile int vi;
+
+static void __attribute__((noinline))
+foo (int c, int &r)
+{
+ int i;
+ if (c)
+ i = r;
+ else
+ i = 0;
+ vi = i;
+}
+
+void
+bar (int c, int j)
+{
+ foo (c, j);
+}
+
+/* { dg-final { scan-ipa-dump "Will split parameter" "sra" } } */
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr108064.c b/gcc/testsuite/gcc.c-torture/execute/pr108064.c
new file mode 100644
index 0000000..a7170bc
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr108064.c
@@ -0,0 +1,28 @@
+/* PR tree-optimization/108064 */
+
+static inline short
+foo (short value)
+{
+ return ((value >> 8) & 0xff) | ((value & 0xff) << 8);
+}
+
+__attribute__((noipa))
+void
+bar (short *d, const short *s)
+{
+ for (unsigned long i = 0; i < 4; i++)
+ d[i] = foo (s[i]);
+}
+
+int
+main ()
+{
+ short a[4] __attribute__((aligned (16))) = { 0xff, 0, 0, 0 };
+ short b[4] __attribute__((aligned (16)));
+ short c[4] __attribute__((aligned (16)));
+
+ bar (b, a);
+ bar (c, b);
+ if (a[0] != c[0])
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c
new file mode 100644
index 0000000..46fc1a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wmaybe-uninitialized -Werror" } */
+
+int cbos();
+static int aos() {
+ cbos();
+ return 0;
+}
+int cbos_ptr;
+long cbos_psize;
+int cbos() {
+ if (cbos_ptr)
+ return aos();
+ if (cbos_psize)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-26.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-26.c
new file mode 100644
index 0000000..08a40da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-26.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-sra-details" } */
+
+struct S
+{
+ short a, b, c;
+};
+
+extern int gc;
+extern int *arr;
+
+static void __attribute__((noinline))
+foo (struct S *p)
+{
+ for (int i = 0; i < gc; i++)
+ arr += p->b;
+}
+
+void
+bar (short a, short b, short c)
+{
+ struct S s;
+ s.a = a;
+ s.b = b;
+ s.c = c;
+ foo (&s);
+ return;
+}
+
+/* { dg-final { scan-ipa-dump "Will split parameter" "sra" } } */
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-27.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-27.c
new file mode 100644
index 0000000..b815e8a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-27.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-sra-details" } */
+
+struct S
+{
+ short a, b, c;
+};
+
+extern int gc;
+extern int *arr;
+
+static void __attribute__((noinline))
+foo (struct S *p)
+{
+ for (int i = 0; i < gc; i++)
+ arr += p->b;
+}
+
+static void __attribute__((noinline))
+baz (struct S *p)
+{
+ foo (p);
+ gc = p->a + p->c;
+}
+
+void
+bar (short a, short b, short c)
+{
+ struct S s;
+ s.a = a;
+ s.b = b;
+ s.c = c;
+ foo (&s);
+ return;
+}
+
+void
+bar2 (short a, short b, short c)
+{
+ struct S s;
+ s.a = a;
+ s.b = b;
+ s.c = c;
+ baz (&s);
+ return;
+}
+
+/* { dg-final { scan-ipa-dump-times "Will split parameter" 2 "sra" } } */
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-28.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-28.c
new file mode 100644
index 0000000..d77d33a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-28.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-sra-details" } */
+
+struct S
+{
+ short a, b, c;
+};
+
+volatile int gc;
+volatile int *arr;
+
+static void __attribute__((noinline))
+foo (struct S *p)
+{
+ for (int i = 0; i < gc; i++)
+ arr += p->b;
+}
+
+void
+bar (short a, short b, short c)
+{
+ struct S s;
+ s.a = a;
+ s.b = b;
+ s.c = c;
+ foo (&s);
+ return;
+}
+
+void
+baz (void)
+{
+ foo ((struct S *) 0);
+}
+
+void __attribute__((noipa))
+confuse (void)
+{
+ gc = 0;
+ baz ();
+}
+
+int
+main (int argc, char **argv)
+{
+ confuse ();
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump-not "Will split parameter" "sra" } } */
+
diff --git a/gcc/testsuite/gcc.dg/ipa/pr107640-2.c b/gcc/testsuite/gcc.dg/ipa/pr107640-2.c
new file mode 100644
index 0000000..94cbe02
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr107640-2.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-slim" } */
+
+struct S
+{
+ int a, b, c;
+};
+
+int ellide (int c);
+volatile short gi;
+
+void __attribute__((noipa))
+consume_s (struct S *p)
+{
+ gi = p->a;
+}
+
+static void __attribute__((noinline))
+foo (struct S *p, short *r)
+{
+ gi = *r;
+ if (!__builtin_constant_p (p->b))
+ ellide (1);
+ consume_s (p);
+}
+
+static void __attribute__((noinline))
+bar (short *r, struct S *p)
+{
+ gi = *r;
+ if (!__builtin_constant_p (p->c))
+ ellide (2);
+ consume_s (p);
+}
+
+struct S gs;
+
+int main (int argc, char *argv[])
+{
+ short i = 42;
+ gs.a = 10;
+ gs.b = 20;
+ foo (&gs, &i);
+ gs.b = 30;
+ gs.c = 40;
+ bar (&i, &gs);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "ellide" "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-43.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-43.c
new file mode 100644
index 0000000..3e0a3d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-43.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftrivial-auto-var-init=zero -fdump-tree-ccp1" } */
+
+int foo (int flag)
+{
+ int i;
+ if (flag)
+ i = 1;
+ return i;
+}
+
+/* { dg-final { scan-tree-dump "return 1;" "ccp1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-1.c b/gcc/testsuite/gcc.target/i386/pr108044-1.c
new file mode 100644
index 0000000..3fd32bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-1.c
@@ -0,0 +1,33 @@
+/* PR target/108044 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+static inline unsigned __int128
+foo (unsigned long long x, unsigned long long y)
+{
+ return ((unsigned __int128) x << 64) | y;
+}
+
+void
+bar (unsigned __int128 *p, unsigned long long x)
+{
+ p[0] = foo (x, 0xdeadbeefcafebabeULL);
+}
+
+void
+baz (unsigned __int128 *p, unsigned long long x)
+{
+ p[0] = foo (0xdeadbeefcafebabeULL, x);
+}
+
+void
+qux (unsigned __int128 *p, unsigned long long x)
+{
+ p[0] = foo (x, 0xffffffffcafebabeULL);
+}
+
+void
+corge (unsigned __int128 *p, unsigned long long x)
+{
+ p[0] = foo (0xffffffffcafebabeULL, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-2.c b/gcc/testsuite/gcc.target/i386/pr108044-2.c
new file mode 100644
index 0000000..0adb0dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-2.c
@@ -0,0 +1,21 @@
+/* PR target/108044 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2" } */
+
+static inline unsigned long long
+foo (unsigned int x, unsigned int y)
+{
+ return ((unsigned long long) x << 32) | y;
+}
+
+void
+bar (unsigned long long *p, unsigned int x)
+{
+ p[0] = foo (x, 0xcafebabeU);
+}
+
+void
+baz (unsigned long long *p, unsigned int x)
+{
+ p[0] = foo (0xcafebabeU, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-3.c b/gcc/testsuite/gcc.target/i386/pr108044-3.c
new file mode 100644
index 0000000..70ba9f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-3.c
@@ -0,0 +1,33 @@
+/* PR target/108044 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -fcf-protection=branch" } */
+
+static inline unsigned __int128
+foo (unsigned long long x, unsigned long long y)
+{
+ return ((unsigned __int128) x << 64) | y;
+}
+
+unsigned __int128
+bar (unsigned long long x)
+{
+ return foo (x, 0xfa1e0ff3ULL);
+}
+
+unsigned __int128
+baz (unsigned long long x)
+{
+ return foo (0xfa1e0ff3ULL, x);
+}
+
+unsigned __int128
+qux (unsigned long long x)
+{
+ return foo (x, 0xffbafa1e0ff3abdeULL);
+}
+
+unsigned __int128
+corge (unsigned long long x)
+{
+ return foo (0xffbafa1e0ff3abdeULL, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-4.c b/gcc/testsuite/gcc.target/i386/pr108044-4.c
new file mode 100644
index 0000000..4880e24
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-4.c
@@ -0,0 +1,21 @@
+/* PR target/108044 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -fcf-protection=branch" } */
+
+static inline unsigned long long
+foo (unsigned int x, unsigned int y)
+{
+ return ((unsigned long long) x << 32) | y;
+}
+
+unsigned long long
+bar (unsigned int x)
+{
+ return foo (x, 0xfa1e0ff3U);
+}
+
+unsigned long long
+baz (unsigned int x)
+{
+ return foo (0xfa1e0ff3U, x);
+}
diff --git a/gcc/testsuite/gfortran.dg/ipa-sra-1.f90 b/gcc/testsuite/gfortran.dg/ipa-sra-1.f90
new file mode 100644
index 0000000..0c916c7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ipa-sra-1.f90
@@ -0,0 +1,37 @@
+! { dg-do compile }
+! { dg-options "-O2 -fno-inline -fno-ipa-cp -fwhole-program -fdump-ipa-sra-details" }
+
+module foo
+ implicit none
+contains
+ subroutine bar(a,x)
+ real, dimension(:,:), intent(in) :: a
+ real, intent(out) :: x
+ integer :: i,j
+
+ x = 0
+ do j=1,ubound(a,2)
+ do i=1,ubound(a,1)
+ x = x + a(i,j)**2
+ end do
+ end do
+ end subroutine bar
+end module foo
+
+program main
+ use foo
+ implicit none
+ real, dimension(2,3) :: a
+ real :: x
+ integer :: i
+
+ data a /1.0, 2.0, 3.0, -1.0, -2.0, -3.0/
+
+ do i=1,2000000
+ call bar(a,x)
+ end do
+ print *,x
+end program main
+
+! { dg-final { scan-ipa-dump "Created new node.*bar\\.isra" "sra" } }
+! { dg-final { scan-ipa-dump-times "IPA_PARAM_OP_SPLIT" 7 "sra" } }
diff --git a/gcc/testsuite/gfortran.dg/pr107423.f90 b/gcc/testsuite/gfortran.dg/pr107423.f90
new file mode 100644
index 0000000..9ae64c9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr107423.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-std=f95" }
+! PR fortran/107423 - ICE in parse_spec
+! Contributed by G.Steinmetz
+
+program p
+ type t(k)
+ integer, kind :: k ! { dg-error "Fortran 2003" }
+ integer :: a
+ end type
+contains
+ function f()
+ type(t(4)), allocatable :: x ! { dg-error "Invalid character" }
+ allocate (t(4) :: x) ! { dg-error "cannot be used" }
+ end ! { dg-error "END" }
+end ! { dg-error "END" }
+
+! { dg-prune-output "Unexpected end of file" }
diff --git a/gcc/testsuite/gfortran.dg/pr48636-2.f90 b/gcc/testsuite/gfortran.dg/pr48636-2.f90
index 30a7e75..4d2bd69 100644
--- a/gcc/testsuite/gfortran.dg/pr48636-2.f90
+++ b/gcc/testsuite/gfortran.dg/pr48636-2.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-O3 -fdump-ipa-cp-details -fno-inline" }
+! { dg-options "-O3 -fdump-ipa-cp-details -fno-inline -fno-ipa-sra" }
module foo
implicit none
diff --git a/gcc/testsuite/jit.dg/test-vector-types.cc b/gcc/testsuite/jit.dg/test-vector-types.cc
index 1f49be6..5661d1b 100644
--- a/gcc/testsuite/jit.dg/test-vector-types.cc
+++ b/gcc/testsuite/jit.dg/test-vector-types.cc
@@ -105,6 +105,19 @@ create_code (gcc_jit_context *ctxt, void *user_data)
v4f_type, GCC_JIT_BINARY_OP_MULT);
create_vec_fn (ctxt, "jit_v4f_div",
v4f_type, GCC_JIT_BINARY_OP_DIVIDE);
+
+ // Checking compatibility between types.
+ CHECK_VALUE(gcc_jit_compatible_types(v4si_type, v4ui_type), 0);
+ CHECK_VALUE(gcc_jit_compatible_types(v4si_type, v4f_type), 0);
+ CHECK_VALUE(gcc_jit_compatible_types(v4ui_type, v4f_type), 0);
+
+ gcc_jit_type *v4si_type2 = gcc_jit_type_get_vector (int_type, 4);
+ gcc_jit_type *v4ui_type2 = gcc_jit_type_get_vector (unsigned_type, 4);
+ gcc_jit_type *v4f_type2 = gcc_jit_type_get_vector (float_type, 4);
+
+ CHECK_VALUE(gcc_jit_compatible_types(v4si_type, v4si_type2), 1);
+ CHECK_VALUE(gcc_jit_compatible_types(v4ui_type, v4ui_type2), 1);
+ CHECK_VALUE(gcc_jit_compatible_types(v4f_type, v4f_type2), 1);
}
template <typename T>
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 8091ba8..15a1a38 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -6377,6 +6377,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
bb = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
while (init_stmts.length ())
insert_init_stmt (&id, bb, init_stmts.pop ());
+ if (param_body_adjs)
+ param_body_adjs->append_init_stmts (bb);
update_clone_info (&id);
/* Remap the nonlocal_goto_save_area, if any. */
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 68e69bf..0d47289 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -722,6 +722,10 @@ likely_value (gimple *stmt)
if (gimple_has_volatile_ops (stmt))
return VARYING;
+ /* .DEFERRED_INIT produces undefined. */
+ if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
+ return UNDEFINED;
+
/* Arrive here for more complex cases. */
has_constant_operand = false;
has_undefined_operand = false;
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index b9f289b..fa2f65d 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2090,7 +2090,7 @@ vn_walk_cb_data::push_partial_def (pd_data pd,
len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
memset (this_buffer, 0, len);
}
- else
+ else if (pd.rhs_off >= 0)
{
len = native_encode_expr (pd.rhs, this_buffer, bufsize,
(MAX (0, -pd.offset)
@@ -2105,6 +2105,24 @@ vn_walk_cb_data::push_partial_def (pd_data pd,
return (void *)-1;
}
}
+ else /* negative pd.rhs_off indicates we want to chop off first bits */
+ {
+ if (-pd.rhs_off >= bufsize)
+ return (void *)-1;
+ len = native_encode_expr (pd.rhs,
+ this_buffer + -pd.rhs_off / BITS_PER_UNIT,
+ bufsize - -pd.rhs_off / BITS_PER_UNIT,
+ MAX (0, -pd.offset) / BITS_PER_UNIT);
+ if (len <= 0
+ || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
+ - MAX (0, -pd.offset) / BITS_PER_UNIT))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Failed to encode %u "
+ "partial definitions\n", ndefs);
+ return (void *)-1;
+ }
+ }
unsigned char *p = buffer;
HOST_WIDE_INT size = pd.size;
@@ -3349,10 +3367,13 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
}
else if (fn == IFN_LEN_STORE)
{
- pd.rhs_off = 0;
pd.offset = offset2i;
pd.size = (tree_to_uhwi (len)
+ -tree_to_shwi (bias)) * BITS_PER_UNIT;
+ if (BYTES_BIG_ENDIAN)
+ pd.rhs_off = pd.size - tree_to_uhwi (TYPE_SIZE (vectype));
+ else
+ pd.rhs_off = 0;
if (ranges_known_overlap_p (offset, maxsize,
pd.offset, pd.size))
return data->push_partial_def (pd, set, set,
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index d9fdb24..32f95a7 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -3113,7 +3113,7 @@ vect_recog_rotate_pattern (vec_info *vinfo,
{
def = vect_recog_temp_ssa_var (utype, NULL);
def_stmt = gimple_build_assign (def, NOP_EXPR, oprnd0);
- append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt);
+ append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt, uvectype);
oprnd0 = def;
}
@@ -3137,7 +3137,7 @@ vect_recog_rotate_pattern (vec_info *vinfo,
{
def = vect_recog_temp_ssa_var (utype, NULL);
def_stmt = gimple_build_assign (def, NOP_EXPR, oprnd1);
- append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt);
+ append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt, uvectype);
}
stype = TREE_TYPE (def);
@@ -3185,13 +3185,13 @@ vect_recog_rotate_pattern (vec_info *vinfo,
def_stmt = gimple_build_assign (var1, rhs_code == LROTATE_EXPR
? LSHIFT_EXPR : RSHIFT_EXPR,
oprnd0, def);
- append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt);
+ append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt, uvectype);
var2 = vect_recog_temp_ssa_var (utype, NULL);
def_stmt = gimple_build_assign (var2, rhs_code == LROTATE_EXPR
? RSHIFT_EXPR : LSHIFT_EXPR,
oprnd0, def2);
- append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt);
+ append_pattern_def_seq (vinfo, stmt_vinfo, def_stmt, uvectype);
/* Pattern detected. */
vect_pattern_detected ("vect_recog_rotate_pattern", last_stmt);
@@ -3202,7 +3202,7 @@ vect_recog_rotate_pattern (vec_info *vinfo,
if (!useless_type_conversion_p (type, utype))
{
- append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt);
+ append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, uvectype);
tree result = vect_recog_temp_ssa_var (type, NULL);
pattern_stmt = gimple_build_assign (result, NOP_EXPR, var);
}