Commit a7374702 authored by Michael Beck's avatar Michael Beck
Browse files

New optimization flag handling, get_opt functions are always inlined now

[r2561]
parent 0e9850ed
......@@ -16,6 +16,9 @@
* Call-Operationen aufrufbaren Methoden bestimmt.
*
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include "cgana.h"
......@@ -29,7 +32,7 @@
#include "ircons.h"
#include "irgmod.h"
#include "irnode.h"
#include "irflag.h"
#include "irflag_t.h"
#include "dbginfo_t.h"
......@@ -206,7 +209,7 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
} else if (get_irn_op(node) == op_Sel &&
is_method_type(get_entity_type(get_Sel_entity(node)))) {
entity * ent = get_Sel_entity(node);
if (get_optimize() && get_opt_dyn_meth_dispatch() &&
if (get_opt_optimize() && get_opt_dyn_meth_dispatch() &&
(get_irn_op(skip_Proj(get_Sel_ptr(node))) == op_Alloc)) {
ir_node *new_node;
entity *called_ent;
......@@ -264,7 +267,7 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
printf("\n");
#endif
if (get_optimize() && get_opt_dyn_meth_dispatch() &&
if (get_opt_optimize() && get_opt_dyn_meth_dispatch() &&
(ARR_LEN(arr) == 1 && arr[0] != NULL)) {
ir_node *new_node;
/* Die Sel-Operation kann immer nur einen Wert auf eine
......
......@@ -24,8 +24,8 @@ SOURCES = $(INSTALL_HEADERS)
SOURCES += Makefile.in \
ircons.c irgmod.c irgraph_t.h irnode.c iropt.c irvrfy.c \
irgwalk.c irdump.c irgopt.c irnode_t.h iropt_t.h \
irmode.c irop.c irprog.c irflag.c irgraph.c irmode_t.h \
irop_t.h irprog_t.h ircgcons.c ircgopt.c
irmode.c irop.c irprog.c irflag.c irflag_t.h irgraph.c \
irmode_t.h irop_t.h irprog_t.h ircgcons.c ircgopt.c
include $(topdir)/MakeRules
......
......@@ -10,7 +10,9 @@
* Copyright: (c) 2002-2003 Universitt Karlsruhe
* Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#include <stdbool.h>
......@@ -21,7 +23,7 @@
#include "ircons.h"
#include "irgmod.h"
#include "irgwalk.h"
#include "irflag.h"
#include "irflag_t.h"
/* Datenstruktur fr jede Methode */
......@@ -156,7 +158,7 @@ static ir_node * exchange_proj(ir_node * proj) {
/* Echt neue Block-Operation erzeugen. CSE abschalten! */
static ir_node * create_Block(int n, ir_node ** in) {
/* Turn off optimizations so that blocks are not merged again. */
int rem_opt = get_optimize();
int rem_opt = get_opt_optimize();
ir_node * block;
set_optimize(0);
block = new_Block(n, in);
......
......@@ -15,7 +15,9 @@
* der nicht erreichbaren Methoden wird aus der Abschtzung der
* Aufrufrelation bestimmt.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ircgopt.h"
......
......@@ -11,7 +11,6 @@
* Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
......@@ -29,6 +28,7 @@
/* memset belongs to string.h */
# include "string.h"
# include "irbackedge_t.h"
# include "irflag_t.h"
#if USE_EXPLICIT_PHI_IN_STACK
/* A stack needed for the automatic Phi node construction in constructor
......@@ -1521,7 +1521,7 @@ static INLINE ir_node ** new_frag_arr (ir_node *n)
sizeof(ir_node *)*current_ir_graph->n_loc);
/* turn off optimization before allocating Proj nodes, as res isn't
finished yet. */
opt = get_optimize(); set_optimize(0);
opt = get_opt_optimize(); set_optimize(0);
/* Here we rely on the fact that all frag ops have Memory as first result! */
if (get_irn_op(n) == op_Call)
arr[0] = new_Proj(n, mode_M, 3);
......
......@@ -10,87 +10,70 @@
* Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "irflag.h"
#include "firm_common.h"
/* 0 - don't do this optimization
1 - lets see, if there is a better graph */
int optimized = 1; /* Turn off all optimizations. */
int opt_cse = 1; /* Hash the nodes. */
int opt_global_cse = 0; /* Don't use block predecessor for comparison.
Default must be zero as code placement must
be run right after a local optimize walk with
opt_global_cse on. */
int opt_constant_folding = 1; /* Evaluate operations. */
int opt_unreachable_code = 1; /* Bad node propagation. */
int opt_control_flow_straightening = 1; /* */
int opt_control_flow_weak_simplification = 1; /* */
int opt_control_flow_strong_simplification = 1; /* */
int opt_critical_edges = 1;
int opt_dead_node_elimination = 1; /* Reclaim memory. */
int opt_reassociation = 1; /* Reassociate nodes. */
int opt_inline = 1; /* Do inlining transformation. */
int opt_dyn_meth_dispatch = 1; /* Remove dynamic method dispatch. */
int opt_normalize = 1; /* Transformations that normalize the firm representation
as removing Ids and Tuples, useless Phis, SymConst(id) ->
Const(entity) ... */
#include "irflag_t.h"
/* DISABLE - don't do this optimization
ENABLE - lets see, if there is a better graph */
#define ENABLE(a) a
#define DISABLE(a) 0
optimization_state_t libFIRM_opt =
ENABLE(OPT_OPTIMIZED) |
ENABLE(OPT_CSE) |
DISABLE(OPT_GLOBAL_CSE) |
ENABLE(OPT_UNREACHABLE_CODE) |
ENABLE(OPT_CONTROL_FLOW_STRAIGHTENING) |
ENABLE(OPT_CONTROL_FLOW_WEAK_SIMPLIFICATION) |
ENABLE(OPT_CONTROL_FLOW_STRONG_SIMPLIFICATION) |
ENABLE(OPT_CRITICAL_EDGES) |
ENABLE(OPT_DEAD_NODE_ELIMINATION) |
ENABLE(OPT_REASSOCIATION) |
ENABLE(OPT_INLINE) |
ENABLE(OPT_DYN_METH_DISPATCH) |
ENABLE(OPT_NORMALIZE);
/* set the flags with set_flagname, get the flag with get_flagname */
INLINE void
set_opt_cse (int value)
{
opt_cse = value;
}
INLINE int
get_opt_cse (void)
void set_opt_cse (int value)
{
return opt_cse;
if (value)
libFIRM_opt |= OPT_CSE;
else
libFIRM_opt &= ~OPT_CSE;
}
void set_opt_global_cse (int value)
void set_opt_global_cse(int value)
{
opt_global_cse = value;
if (value)
libFIRM_opt |= OPT_GLOBAL_CSE;
else
libFIRM_opt &= ~OPT_GLOBAL_CSE;
}
int get_opt_global_cse (void)
void
set_opt_constant_folding(int value)
{
return opt_global_cse;
if (value)
libFIRM_opt |= OPT_CONSTANT_FOLDING;
else
libFIRM_opt &= ~OPT_CONSTANT_FOLDING;
}
INLINE void
set_opt_constant_folding (int value)
{
opt_constant_folding=value;
}
INLINE int
get_opt_constant_folding (void)
{
return opt_constant_folding;
}
INLINE void
void
set_opt_unreachable_code(int value)
{
opt_unreachable_code = value;
if (value)
libFIRM_opt |= OPT_UNREACHABLE_CODE;
else
libFIRM_opt &= ~OPT_UNREACHABLE_CODE;
}
INLINE int
get_opt_unreachable_code(void)
void set_opt_control_flow(int value)
{
return opt_unreachable_code;
}
INLINE void set_opt_control_flow(int value) {
set_opt_control_flow_straightening(value);
set_opt_control_flow_weak_simplification(value);
set_opt_control_flow_strong_simplification(value);
......@@ -98,78 +81,75 @@ INLINE void set_opt_control_flow(int value) {
}
/* Performs Straightening */
void set_opt_control_flow_straightening(int value) {
opt_control_flow_straightening = value;
}
int get_opt_control_flow_straightening(void) {
return opt_control_flow_straightening;
}
/* Performs if simplifications in local optimizations. */
void set_opt_control_flow_weak_simplification(int value) {
opt_control_flow_weak_simplification = value;
}
int get_opt_control_flow_weak_simplification(void) {
return opt_control_flow_weak_simplification;
}
/* Performs strong if and loop simplification (in optimize_cf). */
void set_opt_control_flow_strong_simplification(int value) {
opt_control_flow_strong_simplification = value;
}
int get_opt_control_flow_strong_simplification(void) {
return opt_control_flow_strong_simplification;
}
void set_opt_critical_edges(int value) {
opt_critical_edges = value;
}
int get_opt_critical_edges(void) {
return opt_critical_edges;
void set_opt_control_flow_straightening(int value)
{
if (value)
libFIRM_opt |= OPT_CONTROL_FLOW_STRAIGHTENING;
else
libFIRM_opt &= ~OPT_CONTROL_FLOW_STRAIGHTENING;
}
INLINE void
set_opt_reassociation(int value)
/* Performs if simplifications in local optimizations. */
void set_opt_control_flow_weak_simplification(int value)
{
opt_reassociation = value;
if (value)
libFIRM_opt |= OPT_CONTROL_FLOW_WEAK_SIMPLIFICATION;
else
libFIRM_opt &= ~OPT_CONTROL_FLOW_WEAK_SIMPLIFICATION;
}
INLINE int
get_opt_reassociation(void)
/* Performs strong if and loop simplification (in optimize_cf). */
void set_opt_control_flow_strong_simplification(int value)
{
return opt_reassociation;
if (value)
libFIRM_opt |= OPT_CONTROL_FLOW_STRONG_SIMPLIFICATION;
else
libFIRM_opt &= ~OPT_CONTROL_FLOW_STRONG_SIMPLIFICATION;
}
INLINE void
set_opt_dead_node_elimination (int value)
void set_opt_critical_edges(int value)
{
opt_dead_node_elimination = value;
if (value)
libFIRM_opt |= OPT_CRITICAL_EDGES;
else
libFIRM_opt &= ~OPT_CRITICAL_EDGES;
}
INLINE int
get_opt_dead_node_elimination (void)
void set_opt_reassociation(int value)
{
return opt_dead_node_elimination;
if (value)
libFIRM_opt |= OPT_REASSOCIATION;
else
libFIRM_opt &= ~OPT_REASSOCIATION;
}
INLINE void
set_optimize (int value)
void set_opt_dead_node_elimination(int value)
{
optimized = value;
if (value)
libFIRM_opt |= OPT_DEAD_NODE_ELIMINATION;
else
libFIRM_opt &= ~OPT_DEAD_NODE_ELIMINATION;
}
INLINE int
get_optimize (void)
void set_optimize(int value)
{
return optimized;
if (value)
libFIRM_opt |= OPT_OPTIMIZED;
else
libFIRM_opt &= ~OPT_OPTIMIZED;
}
INLINE void set_opt_inline (int value) {
opt_inline = value;
int get_optimize(void)
{
return get_opt_optimize();
}
INLINE int get_opt_inline (void) {
return opt_inline;
void set_opt_inline(int value)
{
if (value)
libFIRM_opt |= OPT_INLINE;
else
libFIRM_opt &= ~OPT_INLINE;
}
/** Enable/Disable optimization of dynamic method dispatch
......@@ -178,19 +158,30 @@ INLINE int get_opt_inline (void) {
* If the flag is turned on Sel nodes can be replaced by Const nodes representing
* the address of a function.
*/
void set_opt_dyn_meth_dispatch (int value) {
opt_dyn_meth_dispatch = value;
}
int get_opt_dyn_meth_dispatch (void) {
return opt_dyn_meth_dispatch;
void set_opt_dyn_meth_dispatch (int value)
{
if (value)
libFIRM_opt |= OPT_DYN_METH_DISPATCH;
else
libFIRM_opt &= ~OPT_DYN_METH_DISPATCH;
}
void set_opt_normalize(int value)
{
if (value)
libFIRM_opt |= OPT_NORMALIZE;
else
libFIRM_opt &= ~OPT_NORMALIZE;
}
INLINE void set_opt_normalize (int value) {
opt_normalize = value;
/* Save the current optimization state. */
void save_optimization_state(optimization_state_t *state)
{
*state = libFIRM_opt;
}
INLINE int get_opt_normalize (void) {
return opt_normalize;
/* Restore the current optimization state. */
void restore_optimization_state(const optimization_state_t *state)
{
libFIRM_opt = *state;
}
......@@ -21,6 +21,11 @@
#ifndef _IRFLAG_H_
#define _IRFLAG_H_
/**
* A container type to load/restore all optimizations
*/
typedef unsigned optimization_state_t;
/**
* This function enables/disables optimizations globally.
*
......@@ -28,8 +33,7 @@
* Default: optimize == 1.
*/
void set_optimize (int value);
/** Returns global optimization setting */
int get_optimize (void);
int get_optimize(void);
/** Enables/Disables constant folding optimization.
*
......@@ -42,8 +46,6 @@ int get_optimize (void);
* Default: opt_constant_folding == 1.
*/
void set_opt_constant_folding (int value);
/** Returns constant folding optimization setting. */
int get_opt_constant_folding (void);
/** Enables/Disables constant subexpression elimination.
*
......@@ -51,8 +53,6 @@ int get_opt_constant_folding (void);
* Default: opt_cse == 1.
*/
void set_opt_cse (int value);
/** Returns constant subexpression elimination setting. */
int get_opt_cse (void);
/** Enables/Disables global constant subexpression elimination.
*
......@@ -64,18 +64,14 @@ int get_opt_cse (void);
* Default: opt_global_cse == 0.
*/
void set_opt_global_cse (int value);
/** Returns global constant subexpression elimination setting. */
int get_opt_global_cse (void);
/** Enables/Disables unreachble code elimination.
/** Enables/Disables unreachable code elimination.
*
* If opt_unreachable_code == 1 replace nodes (except Block,
* Phi and Tuple) with a Bad predecessor by the Bad node.
* Default: opt_unreachable_code == 1.
*/
void set_opt_unreachable_code(int value);
/** Returns unreachble code elimination setting. */
int get_opt_unreachable_code(void);
/** Enables/Disables control flow optimizations.
*
......@@ -87,23 +83,15 @@ void set_opt_control_flow(int value);
/** Enables/Disables Straightening. */
void set_opt_control_flow_straightening(int value);
/** Returns Straightening setting. */
int get_opt_control_flow_straightening(void);
/** Enables/Disables if simplifications in local optimizations. */
void set_opt_control_flow_weak_simplification(int value);
/** Returns if simplifications in local optimizations setting. */
int get_opt_control_flow_weak_simplification(void);
/** Enables/Disables strong if and loop simplification (in optimize_cf). */
void set_opt_control_flow_strong_simplification(int value);
/** Returns strong if and loop simplification setting */
int get_opt_control_flow_strong_simplification(void);
/** Enables/Disables removal of critical control flow edges. */
void set_opt_critical_edges(int value);
/** Returns whether critical edges are removed */
int get_opt_critical_edges(void);
/** Enables/Disables reassociation.
*
......@@ -111,8 +99,6 @@ int get_opt_critical_edges(void);
* Default: opt_reassociation == 1.
*/
void set_opt_reassociation(int value);
/** Returns reassociation setting. */
int get_opt_reassociation(void);
/** Enables/Disables dead node elimination.
*
......@@ -120,16 +106,12 @@ int get_opt_reassociation(void);
* by copying the firm graph.
* Default: opt_dead_node_elimination == 1. */
void set_opt_dead_node_elimination (int value);
/** Returns dead node elimination setting. */
int get_opt_dead_node_elimination (void);
/** Enable/Disables inlining.
*
* If opt_inline == 1 the inlining transformation is performed.
*/
void set_opt_inline (int value);
/** Returns inlining setting. */
int get_opt_inline (void);
/** Enable/Disable optimization of dynamic method dispatch
*
......@@ -138,7 +120,6 @@ int get_opt_inline (void);
* the address of a function.
*/
void set_opt_dyn_meth_dispatch (int value);
int get_opt_dyn_meth_dispatch (void);
/** Enable/Disable normalizations of the firm representation.
*
......@@ -153,7 +134,15 @@ int get_opt_dyn_meth_dispatch (void);
* @@@ ATTENTION: not all such transformations are guarded by a flag.
*/
void set_opt_normalize (int value);
int get_opt_normalize (void);
/**
* Save the current optimization state.
*/
void save_optimization_state(optimization_state_t *state);
/**
* Restore the current optimization state.
*/
void restore_optimization_state(const optimization_state_t *state);
#endif
......@@ -15,7 +15,7 @@
#endif
# include "irvrfy.h"
# include "irflag.h"
# include "irflag_t.h"
# include "irgwalk.h"
# include "irnode_t.h"
# include "irgraph_t.h"
......@@ -138,7 +138,7 @@ void part_block(ir_node *node) {
ir_node *phi;
/* Turn off optimizations so that blocks are not merged again. */
int rem_opt = get_optimize();
int rem_opt = get_opt_optimize();
set_optimize(0);
/* Transform the control flow */
......
......@@ -33,6 +33,7 @@
# include "irouts.h"
# include "irloop.h"
# include "irbackedge_t.h"
# include "irflag_t.h"
/* Defined in iropt.c */
pset *new_identities (void);
......@@ -418,7 +419,7 @@ dead_node_elimination(ir_graph *irg) {
/* @@@ so far we loose loops when copying */
set_irg_loop(current_ir_graph, NULL);
if (get_optimize() && get_opt_dead_node_elimination()) {
if (get_opt_optimize() && get_opt_dead_node_elimination()) {
/* A quiet place, where the old obstack can rest in peace,
until it will be cremated. */
......@@ -576,9 +577,9 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
int exc_handling; ir_node *proj;
type *called_frame;
if (!get_optimize() || !get_opt_inline()) return;
if (!get_opt_optimize() || !get_opt_inline()) return;
/* -- Turn off optimizations, this can cause problems when allocating new nodes. -- */
rem_opt = get_optimize();
rem_opt = get_opt_optimize();
set_optimize(0);
/* Handle graph state */
......@@ -972,7 +973,7 @@ void inline_small_irgs(ir_graph *irg, int size) {
ir_node *calls[MAX_INLINE];
ir_graph *rem = current_ir_graph;
if (!(get_optimize() && get_opt_inline())) return;
if (!(get_opt_optimize() && get_opt_inline())) return;
current_ir_graph = irg;
/* Handle graph state */
......@@ -1081,7 +1082,7 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
ir_graph *rem = current_ir_graph;
int did_inline = 1;
if (!(get_optimize() && get_opt_inline())) return;
if (!(get_opt_optimize() && get_opt_inline())) return;
/* extend all irgs by a temporary data structure for inlineing. */
for (i = 0; i < n_irgs; ++i)
......@@ -1451,7 +1452,7 @@ void place_code(ir_graph *irg) {
current_ir_graph = irg;
if (!(get_optimize() && get_opt_global_cse())) return;
if (!(get_opt_optimize() && get_opt_global_cse())) return;
/* Handle graph state */
assert(get_irg_phase_state(irg) != phase_building);
......@@ -1500,7 +1501,7 @@ static void merge_blocks(ir_node *n, void *env) {
A different order of optimizations might cause problems. */
if (get_opt_normalize())
set_Block_cfgpred(n, i, skip_Tuple(get_Block_cfgpred(n, i)));
} else if (get_optimize() && (get_irn_mode(n) == mode_X)) {
} else if (get_opt_optimize() && (get_irn_mode(n) == mode_X)) {
/* We will soon visit a block. Optimize it before visiting! */
ir_node *b = get_nodes_Block(n);
ir_node *new_node = equivalent_node(b);
......@@ -1555,7 +1556,7 @@ static int test_whether_dispensable(ir_node *b, int pos) {
if (get_Block_block_visited(pred) + 1
< get_irg_block_visited(current_ir_graph)) {
if (!get_optimize() || !get_opt_control_flow_strong_simplification()) {
if (!get_opt_optimize() || !get_opt_control_flow_strong_simplification()) {
/* Mark block so that is will not be removed. */
set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
return 1;
......
......@@ -11,12 +11,12 @@
*/
/**
* @file irgraph_t.h
*
* ir graph construction.
*
* @author Martin Trapp, Christian Schaefer
*/
* @file irgraph_t.h
*
* ir graph construction.
*
* @author Martin Trapp, Christian Schaefer