Skip to content

Commit 40c5ba4

Browse files
Expand directly for single bit test
Instead of using creating trees to the expansion, just expand directly which makes the code a little simplier but also reduces how much GC memory will be used during the expansion. gcc/ChangeLog: * expr.cc (fold_single_bit_test): Rename to ... (expand_single_bit_test): This and expand directly. (do_store_flag): Update for the rename function.
1 parent c5df248 commit 40c5ba4

File tree

1 file changed

+28
-35
lines changed

1 file changed

+28
-35
lines changed

gcc/expr.cc

+28-35
Original file line numberDiff line numberDiff line change
@@ -12899,23 +12899,21 @@ maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
1289912899
}
1290012900

1290112901

12902-
/* If CODE with arguments INNER & (1<<BITNUM) and 0 represents a single bit
12903-
equality/inequality test, then return a simplified form of
12904-
the test using shifts and logical operations. Otherwise return
12905-
NULL. TYPE is the desired result type. */
12902+
/* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
12903+
a single bit equality/inequality test, returns where the result is located. */
1290612904

12907-
static tree
12908-
fold_single_bit_test (location_t loc, enum tree_code code,
12909-
tree inner, int bitnum,
12910-
tree result_type)
12905+
static rtx
12906+
expand_single_bit_test (location_t loc, enum tree_code code,
12907+
tree inner, int bitnum,
12908+
tree result_type, rtx target,
12909+
machine_mode mode)
1291112910
{
1291212911
gcc_assert (code == NE_EXPR || code == EQ_EXPR);
1291312912

1291412913
tree type = TREE_TYPE (inner);
1291512914
scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
1291612915
int ops_unsigned;
1291712916
tree signed_type, unsigned_type, intermediate_type;
12918-
tree one;
1291912917
gimple *inner_def;
1292012918

1292112919
/* First, see if we can fold the single bit test into a sign-bit
@@ -12924,10 +12922,11 @@ fold_single_bit_test (location_t loc, enum tree_code code,
1292412922
&& type_has_mode_precision_p (type))
1292512923
{
1292612924
tree stype = signed_type_for (type);
12927-
return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
12928-
result_type,
12929-
fold_convert_loc (loc, stype, inner),
12930-
build_int_cst (stype, 0));
12925+
tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
12926+
result_type,
12927+
fold_convert_loc (loc, stype, inner),
12928+
build_int_cst (stype, 0));
12929+
return expand_expr (tmp, target, VOIDmode, EXPAND_NORMAL);
1293112930
}
1293212931

1293312932
/* Otherwise we have (A & C) != 0 where C is a single bit,
@@ -12957,21 +12956,21 @@ fold_single_bit_test (location_t loc, enum tree_code code,
1295712956
intermediate_type = ops_unsigned ? unsigned_type : signed_type;
1295812957
inner = fold_convert_loc (loc, intermediate_type, inner);
1295912958

12960-
tree bftype = build_nonstandard_integer_type (1, 1);
12961-
int bitpos = bitnum;
12962-
12963-
if (BYTES_BIG_ENDIAN)
12964-
bitpos = GET_MODE_BITSIZE (operand_mode) - 1 - bitpos;
12959+
rtx inner0 = expand_expr (inner, target, VOIDmode, EXPAND_NORMAL);
1296512960

12966-
inner = build3_loc (loc, BIT_FIELD_REF, bftype, inner,
12967-
bitsize_int (1), bitsize_int (bitpos));
12968-
12969-
one = build_int_cst (bftype, 1);
12961+
inner0 = extract_bit_field (inner0, 1, bitnum, 1, target,
12962+
operand_mode, mode, 0, NULL);
1297012963

1297112964
if (code == EQ_EXPR)
12972-
inner = fold_build2_loc (loc, BIT_XOR_EXPR, bftype, inner, one);
12973-
12974-
return fold_convert_loc (loc, result_type, inner);
12965+
inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
12966+
NULL_RTX, 1, OPTAB_LIB_WIDEN);
12967+
if (GET_MODE (inner0) != mode)
12968+
{
12969+
rtx t = gen_reg_rtx (mode);
12970+
convert_move (t, inner0, 0);
12971+
return t;
12972+
}
12973+
return inner0;
1297512974
}
1297612975

1297712976
/* Generate code to calculate OPS, and exploded expression
@@ -13150,10 +13149,7 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
1315013149
do this by shifting the bit being tested to the low-order bit and
1315113150
masking the result with the constant 1. If the condition was EQ,
1315213151
we xor it with 1. This does not require an scc insn and is faster
13153-
than an scc insn even if we have it.
13154-
13155-
The code to make this transformation was moved into fold_single_bit_test,
13156-
so we just call into the folder and expand its result. */
13152+
than an scc insn even if we have it. */
1315713153

1315813154
if ((code == NE || code == EQ)
1315913155
&& integer_zerop (arg1)
@@ -13163,16 +13159,13 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
1316313159
if (srcstmt
1316413160
&& integer_pow2p (gimple_assign_rhs2 (srcstmt)))
1316513161
{
13166-
tree temp;
1316713162
enum tree_code tcode = code == NE ? NE_EXPR : EQ_EXPR;
1316813163
int bitnum = tree_log2 (gimple_assign_rhs2 (srcstmt));
1316913164

1317013165
type = lang_hooks.types.type_for_mode (mode, unsignedp);
13171-
temp = fold_single_bit_test (loc, tcode,
13172-
gimple_assign_rhs1 (srcstmt),
13173-
bitnum, type);
13174-
if (temp)
13175-
return expand_expr (temp, target, VOIDmode, EXPAND_NORMAL);
13166+
return expand_single_bit_test (loc, tcode,
13167+
gimple_assign_rhs1 (srcstmt),
13168+
bitnum, type, target, mode);
1317613169
}
1317713170
}
1317813171

0 commit comments

Comments
 (0)