Commit 11fe225a by Zack Weinberg

optimize.c: Include hashtab.h.

	* cp/optimize.c: Include hashtab.h.
	(struct inline_data): Add tree_pruner.
	(expand_call_inline, expand_calls_inline): Use it when calling
	walk_tree.
	(optimize_function): Initialize and free tree_pruner.

	* g++.old-deja/g++.other/perf1.C: New test.

From-SVN: r41525
parent 5ec89e89
2001-04-24 Zack Weinberg <zackw@stanford.edu>
* cp/optimize.c: Include hashtab.h.
(struct inline_data): Add tree_pruner.
(expand_call_inline, expand_calls_inline): Use it when calling
walk_tree.
(optimize_function): Initialize and free tree_pruner.
2001-04-24 Nathan Sidwell <nathan@codesourcery.com> 2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
Lazy __FUNCTION__ generation. Lazy __FUNCTION__ generation.
......
...@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "varray.h" #include "varray.h"
#include "ggc.h" #include "ggc.h"
#include "params.h" #include "params.h"
#include "hashtab.h"
/* To Do: /* To Do:
...@@ -80,6 +81,9 @@ typedef struct inline_data ...@@ -80,6 +81,9 @@ typedef struct inline_data
distinguish between those two situations. This flag is true nif distinguish between those two situations. This flag is true nif
we are cloning, rather than inlining. */ we are cloning, rather than inlining. */
bool cloning_p; bool cloning_p;
/* Hash table used to prevent walk_tree from visiting the same node
umpteen million times. */
htab_t tree_pruner;
} inline_data; } inline_data;
/* Prototypes. */ /* Prototypes. */
...@@ -706,7 +710,7 @@ expand_call_inline (tp, walk_subtrees, data) ...@@ -706,7 +710,7 @@ expand_call_inline (tp, walk_subtrees, data)
if (i == 2) if (i == 2)
++id->in_target_cleanup_p; ++id->in_target_cleanup_p;
walk_tree (&TREE_OPERAND (*tp, i), expand_call_inline, data, walk_tree (&TREE_OPERAND (*tp, i), expand_call_inline, data,
NULL); id->tree_pruner);
if (i == 2) if (i == 2)
--id->in_target_cleanup_p; --id->in_target_cleanup_p;
} }
...@@ -889,8 +893,12 @@ expand_calls_inline (tp, id) ...@@ -889,8 +893,12 @@ expand_calls_inline (tp, id)
inline_data *id; inline_data *id;
{ {
/* Search through *TP, replacing all calls to inline functions by /* Search through *TP, replacing all calls to inline functions by
appropriate equivalents. */ appropriate equivalents. Use walk_tree in no-duplicates mode
walk_tree (tp, expand_call_inline, id, NULL); to avoid exponential time complexity. (We can't just use
walk_tree_without_duplicates, because of the special TARGET_EXPR
handling in expand_calls. The hash table is set up in
optimize_function. */
walk_tree (tp, expand_call_inline, id, id->tree_pruner);
} }
/* Optimize the body of FN. */ /* Optimize the body of FN. */
...@@ -949,9 +957,12 @@ optimize_function (fn) ...@@ -949,9 +957,12 @@ optimize_function (fn)
/* Replace all calls to inline functions with the bodies of those /* Replace all calls to inline functions with the bodies of those
functions. */ functions. */
id.tree_pruner = htab_create (37, htab_hash_pointer,
htab_eq_pointer, NULL);
expand_calls_inline (&DECL_SAVED_TREE (fn), &id); expand_calls_inline (&DECL_SAVED_TREE (fn), &id);
/* Clean up. */ /* Clean up. */
htab_delete (id.tree_pruner);
VARRAY_FREE (id.fns); VARRAY_FREE (id.fns);
VARRAY_FREE (id.target_exprs); VARRAY_FREE (id.target_exprs);
if (DECL_LANG_SPECIFIC (fn)) if (DECL_LANG_SPECIFIC (fn))
......
2001-04-24 Zack Weinberg <zackw@stanford.edu>
* g++.old-deja/g++.other/perf1.C: New test.
2001-04-24 Nathan Sidwell <nathan@codesourcery.com> 2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
* gcc.dg/c99-func-2.c: Remove xfail. * gcc.dg/c99-func-2.c: Remove xfail.
......
// Build don't link:
// Test of severe performance regression from 2.95. This code generates
// a heavily self-referential tree which caused the inliner to take
// O(3**N) time to scan it for function calls.
// Reported by Kelley Cook <kelley.cook@home.com>. PR c++/1687.
bool in0 ;
bool in1 ;
bool in2 ;
bool in3 ;
bool in4 ;
bool in5 ;
bool in6 ;
bool in7 ;
bool in8 ;
bool in9 ;
bool in10;
bool in11;
bool in12;
bool in13;
bool in14;
bool in15;
bool in16;
bool in17;
bool in18;
bool in19;
bool in20;
bool in21;
bool in22;
bool in23;
bool in24;
bool in25;
bool in26;
bool in27;
bool in28;
bool in29;
bool in30;
bool in31;
unsigned long output;
void mux(void)
{
output =
(in0 ? 0x00000001 : 0) |
(in1 ? 0x00000002 : 0) |
(in2 ? 0x00000004 : 0) |
(in3 ? 0x00000008 : 0) |
(in4 ? 0x00000010 : 0) |
(in5 ? 0x00000020 : 0) |
(in6 ? 0x00000040 : 0) |
(in7 ? 0x00000080 : 0) |
(in8 ? 0x00000100 : 0) |
(in9 ? 0x00000200 : 0) |
(in10 ? 0x00000400 : 0) |
(in11 ? 0x00000800 : 0) |
(in12 ? 0x00001000 : 0) |
(in13 ? 0x00002000 : 0) |
(in14 ? 0x00004000 : 0) |
(in15 ? 0x00008000 : 0) |
(in16 ? 0x00010000 : 0) |
(in17 ? 0x00020000 : 0) |
(in18 ? 0x00040000 : 0) |
(in19 ? 0x00080000 : 0) |
(in20 ? 0x00100000 : 0) |
(in21 ? 0x00200000 : 0) |
(in22 ? 0x00400000 : 0) |
(in23 ? 0x00800000 : 0) |
(in24 ? 0x01000000 : 0) |
(in25 ? 0x02000000 : 0) |
(in26 ? 0x04000000 : 0) |
(in27 ? 0x08000000 : 0) |
(in28 ? 0x10000000 : 0) |
(in29 ? 0x20000000 : 0) |
(in30 ? 0x40000000 : 0) |
(in31 ? 0x80000000 : 0) ;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment