aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.h
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2024-12-12 11:43:03 -0300
committerAlexandre Oliva <oliva@gnu.org>2024-12-12 11:43:03 -0300
commite8febb641415fd80eabce1c4fdf2d4a4b411213b (patch)
treefa0348850f86ba612b15272e14ddda8854e79098 /gcc/fold-const.h
parentbc565843ea20a616dd376226416777a4ea1959d6 (diff)
downloadgcc-e8febb641415fd80eabce1c4fdf2d4a4b411213b.zip
gcc-e8febb641415fd80eabce1c4fdf2d4a4b411213b.tar.gz
gcc-e8febb641415fd80eabce1c4fdf2d4a4b411213b.tar.bz2
fold fold_truth_andor field merging into ifcombine
This patch introduces various improvements to the logic that merges field compares, while moving it into ifcombine. Before the patch, we could merge: (a.x1 EQNE b.x1) ANDOR (a.y1 EQNE b.y1) into something like: (((type *)&a)[Na] & MASK) EQNE (((type *)&b)[Nb] & MASK) if both of A's fields live within the same alignment boundaries, and so do B's, at the same relative positions. Constants may be used instead of the object B. The initial goal of this patch was to enable such combinations when a field crossed alignment boundaries, e.g. for packed types. We can't generally access such fields with a single memory access, so when we come across such a compare, we will attempt to combine each access separately. Some merging opportunities were missed because of right-shifts, compares expressed as e.g. ((a.x1 ^ b.x1) & MASK) EQNE 0, and narrowing conversions, especially after earlier merges. This patch introduces handlers for several cases involving these. The merging of multiple field accesses into wider bitfield-like accesses is undesirable to do too early in compilation, so we move it from folding to ifcombine, and guard its warnings with -Wtautological-compare, turned into a common flag. When the second of a noncontiguous pair of compares is the first that accesses a word, we may merge the first compare with part of the second compare that refers to the same word, keeping the compare of the remaining bits at the spot where the second compare used to be. Handling compares with non-constant fields was somewhat generalized from what fold used to do, now handling non-adjacent fields, even if a field of one object crosses an alignment boundary but the other doesn't. for gcc/ChangeLog * fold-const.cc (make_bit_field): Export. (unextend, all_ones_mask_p): Drop. (decode_field_reference, fold_truth_andor_1): Move field compare merging logic... * gimple-fold.cc: (fold_truth_andor_for_ifcombine) ... here, with -Wtautological-compare warning guards, and... (decode_field_reference): ... here. Rework for gimple. (gimple_convert_def_p, gimple_binop_def_p): New. (compute_split_boundary_from_align): New. (make_bit_field_load, build_split_load): New. (reuse_split_load): New. * fold-const.h: (make_bit_field_ref): Declare (fold_truth_andor_for_ifcombine): Declare. * tree-ssa-ifcombine.cc (ifcombine_ifandif): Try fold_truth_andor_for_ifcombine. * common.opt (Wtautological-compare): Move here. for gcc/c-family/ChangeLog * c.opt (Wtautological-compare): Move to ../common.opt. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-1.c: New. * gcc.dg/field-merge-2.c: New. * gcc.dg/field-merge-3.c: New. * gcc.dg/field-merge-4.c: New. * gcc.dg/field-merge-5.c: New. * gcc.dg/field-merge-6.c: New. * gcc.dg/field-merge-7.c: New. * gcc.dg/field-merge-8.c: New. * gcc.dg/field-merge-9.c: New. * gcc.dg/field-merge-10.c: New. * gcc.dg/field-merge-11.c: New. * gcc.dg/field-merge-12.c: New. * gcc.target/aarch64/long_branch_1.c: Disable ifcombine.
Diffstat (limited to 'gcc/fold-const.h')
-rw-r--r--gcc/fold-const.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 48f0648..04a9457 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -253,11 +253,21 @@ extern tree fold_build_pointer_plus_hwi_loc (location_t loc, tree ptr, HOST_WIDE
extern tree_code minmax_from_comparison (tree_code, tree, tree,
tree, tree);
+extern tree make_bit_field_ref (location_t, tree, tree, tree,
+ HOST_WIDE_INT, poly_int64, int, int);
+
/* In gimple-fold.cc. */
extern void clear_type_padding_in_mask (tree, unsigned char *);
extern bool clear_padding_type_may_have_padding_p (tree);
extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree,
const_tree);
+extern tree fold_truth_andor_for_ifcombine (enum tree_code, tree,
+ location_t, enum tree_code,
+ tree, tree,
+ location_t, enum tree_code,
+ tree, tree,
+ tree *);
+
/* Class used to compare gimple operands. */