This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
genattrtab speedup/memory reduction
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com
- Subject: genattrtab speedup/memory reduction
- From: Jan Hubicka <jh at suse dot cz>
- Date: Wed, 16 May 2001 20:39:26 +0200
Hi
This is an old patch slightly updated for new tree. I've found myself
to install it to my tree over and over as it cuts down the memory
usage to half and the runtime to one third by avoiding unnecesary
copying.
Since we've decided to use long longs as HOST_WIDE_INT, the x86_64 build
is incredibly slow w/o it.
I would like to ask you to re-consider this patch for review.
As I've mentioned earlier, the files don't byte-compare, but semantically
they are the same, as the order of simplification performed has changed
by the last hunk.
Sun Dec 17 19:14:32 CET 2000 Jan Hubicka <jh@suse.cz>
* genattrtab.c (simplify_test_exp_in_temp): New function.
(simplify_test_exp): Avoid explicit use of temporary obstack.
(simplify_cond, insert_right_side, evaluate_eq_attr,
simplify_and_tree, simplify_or_tree, eliminate_known_true):
Use simplify_test_exp_in_temp.
(optimize_attrs): Iterate until expression stabilizes.
*** genattrtab.c.old Sun Dec 17 18:46:34 2000
--- genattrtab.c Sun Dec 17 19:11:57 2000
*************** static rtx evaluate_eq_attr PARAMS ((rtx
*** 417,422 ****
--- 417,423 ----
static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
static rtx simplify_test_exp PARAMS ((rtx, int, int));
+ static rtx simplify_test_exp_in_temp PARAMS ((rtx, int, int));
static void optimize_attrs PARAMS ((void));
static int count_alternatives PARAMS ((rtx));
*************** simplify_cond (exp, insn_code, insn_inde
*** 2591,2597 ****
rtx newtest, newval;
/* Simplify this test. */
! newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index);
tests[i] = newtest;
newval = tests[i + 1];
--- 2592,2598 ----
rtx newtest, newval;
/* Simplify this test. */
! newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
tests[i] = newtest;
newval = tests[i + 1];
*************** insert_right_side (code, exp, term, insn
*** 2777,2783 ****
newexp = attr_rtx (code, exp, term);
}
! return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
}
/* If we have an expression which AND's a bunch of
--- 2778,2784 ----
newexp = attr_rtx (code, exp, term);
}
! return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
/* If we have an expression which AND's a bunch of
*************** evaluate_eq_attr (exp, value, insn_code,
*** 2903,2910 ****
for (i = 0; i < XVECLEN (value, 0); i += 2)
{
! rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
! insn_code, insn_index);
SIMPLIFY_ALTERNATIVE (this);
--- 2904,2911 ----
for (i = 0; i < XVECLEN (value, 0); i += 2)
{
! rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
! insn_code, insn_index);
SIMPLIFY_ALTERNATIVE (this);
*************** simplify_and_tree (exp, pterm, insn_code
*** 2985,2991 ****
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
}
}
--- 2986,2992 ----
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
}
*************** simplify_and_tree (exp, pterm, insn_code
*** 3008,3014 ****
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
}
}
--- 3009,3015 ----
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
}
*************** simplify_or_tree (exp, pterm, insn_code,
*** 3104,3110 ****
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
}
}
--- 3105,3111 ----
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
}
*************** simplify_or_tree (exp, pterm, insn_code,
*** 3127,3133 ****
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
}
}
--- 3128,3134 ----
{
newexp = attr_rtx (GET_CODE (exp), left, right);
! exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
}
*************** attr_rtx_cost (x)
*** 3200,3205 ****
--- 3201,3229 ----
return cost;
}
+
+ /* Simplify test expression and use temporary obstack in order to avoid
+ memory bloat. Use RTX_UNCHANGING_P to avoid unnecesary simplifications
+ and avoid unnecesary copying if possible. */
+
+ static rtx
+ simplify_test_exp_in_temp (exp, insn_code, insn_index)
+ rtx exp;
+ int insn_code, insn_index;
+ {
+ rtx x;
+ struct obstack *old;
+ if (RTX_UNCHANGING_P (exp))
+ return exp;
+ old = rtl_obstack;
+ rtl_obstack = temp_obstack;
+ x = simplify_test_exp (exp, insn_code, insn_index);
+ rtl_obstack = old;
+ if (x == exp || rtl_obstack == temp_obstack)
+ return x;
+ return attr_copy_rtx (x);
+ }
+
/* Given an expression, see if it can be simplified for a particular insn
code based on the values of other attributes being tested. This can
eliminate nested get_attr_... calls.
*************** simplify_test_exp (exp, insn_code, insn_
*** 3457,3469 ****
if (ie->insn_code == insn_code)
{
rtx x;
- struct obstack *old = rtl_obstack;
- rtl_obstack = temp_obstack;
x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
- rtl_obstack = old;
if (attr_rtx_cost(x) < 20)
! return attr_copy_rtx (x);
}
break;
--- 3481,3490 ----
if (ie->insn_code == insn_code)
{
rtx x;
x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
if (attr_rtx_cost(x) < 20)
! return x;
}
break;
*************** optimize_attrs ()
*** 3553,3593 ****
clear_struct_flag (iv->av->value);
/* Loop until nothing changes for one iteration. */
! something_changed = 1;
! while (something_changed)
{
! something_changed = 0;
! for (iv = insn_code_values[i]; iv; iv = iv->next)
! {
! struct obstack *old = rtl_obstack;
! attr = iv->attr;
! av = iv->av;
! ie = iv->ie;
! if (GET_CODE (av->value) != COND)
! continue;
! rtl_obstack = temp_obstack;
#if 0 /* This was intended as a speed up, but it was slower. */
! if (insn_n_alternatives[ie->insn_code] > 6
! && count_sub_rtxs (av->value, 200) >= 200)
! newexp = simplify_by_alternatives (av->value, ie->insn_code,
! ie->insn_index);
! else
#endif
! newexp = simplify_cond (av->value, ie->insn_code,
! ie->insn_index);
! rtl_obstack = old;
! if (newexp != av->value)
! {
! newexp = attr_copy_rtx (newexp);
! remove_insn_ent (av, ie);
! av = get_attr_value (newexp, attr, ie->insn_code);
! iv->av = av;
! insert_insn_ent (av, ie);
! something_changed = 1;
! }
}
}
}
--- 3574,3616 ----
clear_struct_flag (iv->av->value);
/* Loop until nothing changes for one iteration. */
! for (iv = insn_code_values[i]; iv; iv = iv->next)
{
! struct obstack *old = rtl_obstack;
! attr = iv->attr;
! av = iv->av;
! ie = iv->ie;
! if (GET_CODE (av->value) != COND)
! continue;
! rtl_obstack = temp_obstack;
#if 0 /* This was intended as a speed up, but it was slower. */
! if (insn_n_alternatives[ie->insn_code] > 6
! && count_sub_rtxs (av->value, 200) >= 200)
! newexp = simplify_by_alternatives (av->value, ie->insn_code,
! ie->insn_index);
! else
#endif
! newexp = av->value;
! while (GET_CODE (newexp) == COND)
! {
! rtx newexp2 = simplify_cond (newexp, ie->insn_code,
! ie->insn_index);
! if (newexp2 == newexp)
! break;
! newexp = newexp2;
! }
! rtl_obstack = old;
! if (newexp != av->value)
! {
! newexp = attr_copy_rtx (newexp);
! remove_insn_ent (av, ie);
! av = get_attr_value (newexp, attr, ie->insn_code);
! iv->av = av;
! insert_insn_ent (av, ie);
! something_changed = 1;
}
}
}
*************** eliminate_known_true (known_true, exp, i
*** 5047,5053 ****
{
rtx term;
! known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
if (GET_CODE (known_true) == AND)
{
--- 5070,5076 ----
{
rtx term;
! known_true = simplify_test_exp_in_temp (known_true, insn_code, insn_index);
if (GET_CODE (known_true) == AND)
{