Commit 5a316806 authored by Matthias Braun's avatar Matthias Braun
Browse files

replace fp_model stuff with allow_imprecise_float_transforms flag

Most aspects of the fp_model flag would need to be enforced by
constructing the firm graph in a certain way. Setting it as a flag won't
help. Apart from that nearly nothing of the stuff was implemented
anyway.
parent 8fda947f
......@@ -464,12 +464,6 @@ FIRM_API void *get_irg_loc_description(ir_graph *irg, int n);
/** Returns the last irn index for this graph. */
FIRM_API unsigned get_irg_last_idx(const ir_graph *irg);
/** Returns the floating point model of this graph. */
FIRM_API unsigned get_irg_fp_model(const ir_graph *irg);
/** Sets a floating point model for this graph. */
FIRM_API void set_irg_fp_model(ir_graph *irg, unsigned model);
/**
* Ensures that a graph fulfills all properties stated in @p state.
* Performs graph transformations if necessary.
......
......@@ -20,53 +20,6 @@
* @{
*/
/**
* The Floating point model.
*
* Several basic properties are defined:
* - fp_explicit_rounding
* - fp_strict_algebraic
* - fp_contradictions
* - fp_strict_eval_order
* - fp_exceptions
* - fp_environment_access
*
* From those basic properties three general models are defined,
* compatible to the VC8 compiler:
* - fp_model_precise:
* Default mode. Associative and distributive law forbidden unless a transformation
* is guaranteed to produce the same result.
* No FPU environment access. No FP exception semantics.
* - fp_model_strict:
* Slowest mode. Additionally to fp_model_precise allows correct handling of
* FP exceptions and FPU environment access.
* - fp_model_fast:
* Fastest mode. Associative and distributive law allowed at the expense
* of floating point accuracy and correctness. Explicit rounding is disabled.
*/
typedef enum fp_model_t {
fp_explicit_rounding = (1u << 0), /**< Explicit rounding at assignments, typecasts, return
and function calls. Conv nodes may NOT be removed, even
if they look useless. */
fp_strict_algebraic = (1u << 1), /**< Strict adherence to non-associative and non-distributive
algebra unless the same result is guaranteed. */
fp_contradictions = (1u << 2), /**< FP contradictions are enabled. Only for backend. */
fp_strict_eval_order = (1u << 3), /**< FP instructions must be strict evaluated in given order. */
fp_exceptions = (1u << 4), /**< FP exceptions are supported. No reordering that changes
the exception flow are allowed. Backends must generate
synchronized exception code. */
fp_environment_access = (1u << 5), /**< FPU environment can be accessed. Even Constant folding
cannot be done. */
/** Precise floating point model. Default. */
fp_model_precise = fp_explicit_rounding|fp_strict_algebraic|fp_contradictions,
/** Strict floating point model. */
fp_model_strict = fp_explicit_rounding|fp_strict_algebraic|fp_strict_eval_order|
fp_exceptions|fp_environment_access,
/** Fast floating point model. */
fp_model_fast = fp_contradictions
} fp_model_t;
/** If the expression referenced can be evaluated statically
* computed_value returns a tarval representing the result.
* Else returns tarval_bad. */
......@@ -94,6 +47,16 @@ FIRM_API int ir_is_negated_value(const ir_node *a, const ir_node *b);
FIRM_API ir_relation ir_get_possible_cmp_relations(const ir_node *left,
const ir_node *right);
/**
* enable/disable imprecise floatingpoint optimizations. These include rules
* like (a - x) + x = a, or a-0=a. They are wrong in several corner cases but
* may still be fine for some applications.
*/
FIRM_API void ir_allow_imprecise_float_transforms(int enable);
/** return 1 if imprecise float transformations are allowed. */
FIRM_API int ir_imprecise_float_transforms_allowed(void);
/** @} */
#include "end.h"
......
......@@ -123,7 +123,6 @@ ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc)
res->typeinfo_state = ir_typeinfo_none;
set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
res->callee_info_state = irg_callee_info_none;
res->fp_model = fp_model_precise;
res->mem_disambig_opt = aa_opt_inherited;
/*-- Type information for the procedure of the graph --*/
......@@ -194,7 +193,6 @@ ir_graph *new_const_code_irg(void)
res->n_loc = 1; /* Only the memory. */
res->irg_pinned_state = op_pin_state_pinned;
res->fp_model = fp_model_precise;
add_irg_constraints(res, IR_GRAPH_CONSTRAINT_CONSTRUCTION);
......@@ -285,7 +283,6 @@ ir_graph *create_irg_copy(ir_graph *irg)
res = alloc_graph();
res->irg_pinned_state = irg->irg_pinned_state;
res->fp_model = irg->fp_model;
/* clone the frame type here for safety */
irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK);
......@@ -574,16 +571,6 @@ void (inc_irg_block_visited)(ir_graph *irg)
inc_irg_block_visited_(irg);
}
unsigned (get_irg_fp_model)(const ir_graph *irg)
{
return get_irg_fp_model_(irg);
}
void set_irg_fp_model(ir_graph *irg, unsigned model)
{
irg->fp_model = model;
}
void set_irg_loc_description(ir_graph *irg, int n, void *description)
{
assert(0 <= n && n < irg->n_loc);
......
......@@ -58,7 +58,6 @@
#define set_irg_block_visited(irg, v) set_irg_block_visited_(irg, v)
#define inc_irg_block_visited(irg) inc_irg_block_visited_(irg)
#define dec_irg_block_visited(irg) dec_irg_block_visited_(irg)
#define get_irg_fp_model(irg) get_irg_fp_model_(irg)
#define get_idx_irn(irg, idx) get_idx_irn_(irg, idx)
#define irg_is_constrained(irg, constraints) irg_is_constrained_(irg, constraints)
#define add_irg_properties(irg, props) add_irg_properties_(irg, props)
......@@ -304,12 +303,6 @@ static inline void dec_irg_block_visited_(ir_graph *irg)
--irg->block_visited;
}
/* Return the floating point model of this graph. */
static inline unsigned get_irg_fp_model_(const ir_graph *irg)
{
return irg->fp_model;
}
static inline int irg_is_constrained_(const ir_graph *irg,
ir_graph_constraints_t constraints)
{
......
......@@ -40,6 +40,18 @@
#include "entity_t.h"
static int imprecise_float_transforms_allowed;
void ir_allow_imprecise_float_transforms(int enable)
{
imprecise_float_transforms_allowed = enable;
}
int ir_imprecise_float_transforms_allowed(void)
{
return imprecise_float_transforms_allowed;
}
static bool is_Or_Eor_Add(const ir_node *node)
{
if (is_Or(node) || is_Eor(node) || is_Add(node)) {
......@@ -794,12 +806,9 @@ static ir_node *equivalent_node_Add(ir_node *n)
if (n != oldn)
return n;
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode)) {
ir_graph *irg = get_irn_irg(n);
if (get_irg_fp_model(irg) & fp_strict_algebraic)
return n;
}
/* these optimizations are imprecise for floatingpoint ops */
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return n;
left = get_Add_left(n);
right = get_Add_right(n);
......@@ -865,12 +874,9 @@ static ir_node *equivalent_node_Sub(ir_node *n)
ir_mode *mode = get_irn_mode(n);
ir_tarval *tb;
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode)) {
ir_graph *irg = get_irn_irg(n);
if (get_irg_fp_model(irg) & fp_strict_algebraic)
return n;
}
/* these optimizations are imprecise for floatingpoint ops */
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return n;
b = get_Sub_right(n);
tb = value_of(b);
......@@ -2456,13 +2462,9 @@ static ir_node *transform_node_Add(ir_node *n)
ir_node *c;
HANDLE_BINOP_PHI((eval_func) tarval_add, a, b, c, mode);
/* for FP the following optimizations are only allowed if
* fp_strict_algebraic is disabled */
if (mode_is_float(mode)) {
ir_graph *irg = get_irn_irg(n);
if (get_irg_fp_model(irg) & fp_strict_algebraic)
return n;
}
/* these optimizations are imprecise for floatingpoint ops */
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return n;
if (mode_is_num(mode)) {
ir_graph *irg = get_irn_irg(n);
......@@ -2588,12 +2590,9 @@ static ir_node *transform_node_Sub(ir_node *n)
restart:
HANDLE_BINOP_PHI((eval_func) tarval_sub, a, b, c, mode);
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode)) {
ir_graph *irg = get_irn_irg(n);
if (get_irg_fp_model(irg) & fp_strict_algebraic)
return n;
}
/* these optimizations are improcise for floatingpoint ops */
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return n;
if (is_Const(b) && !mode_is_reference(get_irn_mode(b))) {
/* a - C -> a + (-C) */
......@@ -3095,7 +3094,8 @@ static ir_node *transform_node_Div(ir_node *n)
/* Do the transformation if the result is either exact or we are
not using strict rules. */
if (tv != tarval_bad &&
(tarval_ieee754_get_exact() || (get_irg_fp_model(get_irn_irg(n)) & fp_strict_algebraic) == 0)) {
(tarval_ieee754_get_exact()
|| ir_imprecise_float_transforms_allowed())) {
ir_node *block = get_nodes_block(n);
ir_graph *irg = get_irn_irg(block);
ir_node *c = new_r_Const(irg, tv);
......
......@@ -513,7 +513,6 @@ struct ir_graph {
ir_typeinfo_state typeinfo_state; /**< Validity of type information. */
irg_callee_info_state callee_info_state; /**< Validity of callee information. */
unsigned mem_disambig_opt; /**< Options for the memory disambiguator. */
unsigned fp_model; /**< floating point model of the graph. */
/* -- Fields for construction -- */
int n_loc; /**< Number of local variables in this
......
......@@ -2563,7 +2563,7 @@ static node_t *identity_comm_zero_binop(node_t *node)
ir_tarval *zero;
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return node;
/* node: no input should be tarval_top, else the binop would be also
......@@ -2606,7 +2606,7 @@ static node_t *identity_Mul(node_t *node)
ir_tarval *one;
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return node;
/* node: no input should be tarval_top, else the binop would be also
......@@ -2629,7 +2629,7 @@ static node_t *identity_Sub(node_t *node)
ir_mode *mode = get_irn_mode(sub);
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return node;
/* node: no input should be tarval_top, else the binop would be also
......
......@@ -463,8 +463,8 @@ static void do_reassociation(waitq *const wq)
res = 0;
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode) && get_irg_fp_model(get_irn_irg(n)) & fp_strict_algebraic)
/* reassociating floatingpoint ops is imprecise */
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
break;
if (op->ops.reassociate) {
......@@ -740,8 +740,8 @@ static void reverse_rules(ir_node *node, void *env)
ir_mode *mode = get_irn_mode(node);
int res;
/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
if (mode_is_float(mode) && get_irg_fp_model(irg) & fp_strict_algebraic)
/* reassociating floatingpoint ops is imprecise */
if (mode_is_float(mode) && !ir_imprecise_float_transforms_allowed())
return;
do {
......
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