started adding a relation to the Cmp node
authorMatthias Braun <matze@braunis.de>
Mon, 31 Jan 2011 00:02:17 +0000 (01:02 +0100)
committerMatthias Braun <matze@braunis.de>
Mon, 28 Feb 2011 10:30:49 +0000 (11:30 +0100)
55 files changed:
include/libfirm/firm_types.h
include/libfirm/irnode.h
include/libfirm/iroptimize.h
include/libfirm/tv.h
include/libfirm/vrp.h
ir/ana/irconsconfirm.c
ir/ana/irmemory.c
ir/ana/vrp.c
ir/be/amd64/amd64_emitter.c
ir/be/amd64/amd64_new_nodes.c
ir/be/amd64/amd64_nodes_attr.h
ir/be/amd64/amd64_spec.pl
ir/be/amd64/amd64_transform.c
ir/be/arm/arm_emitter.c
ir/be/arm/arm_new_nodes.c
ir/be/arm/arm_new_nodes.h
ir/be/arm/arm_nodes_attr.h
ir/be/arm/arm_spec.pl
ir/be/arm/arm_transform.c
ir/be/beemitter.c
ir/be/betranshlp.c
ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_intrinsics.c
ir/be/ia32/ia32_transform.c
ir/be/sparc/bearch_sparc.c
ir/be/sparc/sparc_emitter.c
ir/be/sparc/sparc_new_nodes.c
ir/be/sparc/sparc_nodes_attr.h
ir/be/sparc/sparc_spec.pl
ir/be/sparc/sparc_transform.c
ir/ir/irarch.c
ir/ir/irargs.c
ir/ir/irdump.c
ir/ir/irdumptxt.c
ir/ir/irnode.c
ir/ir/irnode_t.h
ir/ir/iropt.c
ir/ir/irtypes.h
ir/ir/irverify.c
ir/lower/lower_dw.c
ir/lower/lower_intrinsics.c
ir/lower/lower_mode_b.c
ir/lower/lower_switch.c
ir/opt/boolopt.c
ir/opt/combo.c
ir/opt/fp-vrp.c
ir/opt/iropt_dbg.h
ir/opt/jumpthreading.c
ir/opt/ldstopt.c
ir/opt/loop.c
ir/opt/opt_confirms.c
ir/opt/opt_ldst.c
ir/tv/tv.c
scripts/gen_ir_io.py
scripts/ir_spec.py

index c3ec20e..30b87d7 100644 (file)
@@ -117,6 +117,29 @@ typedef ir_node *uninitialized_local_variable_func_t(ir_graph *irg, ir_mode *mod
 # define ENUM_COUNTABLE(type)
 #endif
 
+/**
+ * Relations for comparing numbers
+ */
+typedef enum ir_relation {
+       ir_relation_false              = 0,       /**< always false */
+       ir_relation_equal              = 1u << 0, /**< equal */
+       ir_relation_less               = 1u << 1, /**< less */
+       ir_relation_greater            = 1u << 2, /**< greater */
+       ir_relation_unordered          = 1u << 3, /**< unordered */
+       ir_relation_less_equal         = ir_relation_equal|ir_relation_less,    /**< less or equal */
+       ir_relation_greater_equal      = ir_relation_equal|ir_relation_greater, /**< greater or equal */
+       ir_relation_less_greater       = ir_relation_less|ir_relation_greater,  /** less or greater ('not equal' for integer numbers) */
+       ir_relation_less_equal_greater = ir_relation_equal|ir_relation_less|ir_relation_greater, /**< less equal or greater ('not unordered') */
+       ir_relation_unordered_equal    = ir_relation_unordered|ir_relation_equal, /**< unordered or equal */
+       ir_relation_unordered_less     = ir_relation_unordered|ir_relation_less,  /**< unorderedor less */
+       ir_relation_unordered_less_equal = ir_relation_unordered|ir_relation_less|ir_relation_equal, /**< unordered, less or equal */
+       ir_relation_unordered_greater    = ir_relation_unordered|ir_relation_greater, /**< unordered or greater */
+       ir_relation_unordered_greater_equal = ir_relation_unordered|ir_relation_greater|ir_relation_equal, /**< unordered, greater or equal */
+       ir_relation_unordered_less_greater  = ir_relation_unordered|ir_relation_less|ir_relation_greater, /**< unordered, less or greater ('not equal' for floatingpoint numbers) */
+       ir_relation_true                    = ir_relation_equal|ir_relation_less|ir_relation_greater|ir_relation_unordered, /**< always true */
+} ir_relation;
+ENUM_BITSET(ir_relation)
+
 /**
  * constrained flags for memory operations.
  */
index 764acb2..fab6d2f 100644 (file)
@@ -493,17 +493,14 @@ FIRM_API void     set_binop_left(ir_node *node, ir_node *left);
 FIRM_API ir_node *get_binop_right(const ir_node *node);
 FIRM_API void     set_binop_right(ir_node *node, ir_node *right);
 
-/** returns the pnc name from an pnc constant */
-FIRM_API const char *get_pnc_string(int pnc);
+/** returns the name of an ir_relation */
+FIRM_API const char *get_relation_string(ir_relation relation);
 
-/** Calculates the negated (Complement(R)) pnc condition. */
-FIRM_API pn_Cmp      get_negated_pnc(long pnc, ir_mode *mode);
+/** Calculates the negated (Complement(R)) relation, i.e. "<" --> ">=" */
+FIRM_API ir_relation get_negated_relation(ir_relation relation);
 
-/** Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
-FIRM_API pn_Cmp      get_inversed_pnc(long pnc);
-
-/** An alternative name for get_inversed_pnc() that can be better memorized. */
-#define get_mirrored_pnc(pnc)  get_inversed_pnc(pnc)
+/** Calculates the inversed (R^-1) relation, i.e., "<" --> ">" */
+FIRM_API ir_relation get_inversed_relation(ir_relation relation);
 
 /** Checks for upcast.
  *
@@ -569,7 +566,6 @@ FIRM_API void      add_Sync_pred(ir_node *node, ir_node *pred);
 /** Return the projection number of a Proj node. */
 FIRM_API long      get_Proj_proj(const ir_node *node);
 FIRM_API void      set_Proj_proj(ir_node *node, long proj);
-FIRM_API pn_Cmp    get_Proj_pn_cmp(const ir_node*);
 
 /**
  * Returns non-zero if a node is a routine parameter.
index 6122326..221366c 100644 (file)
@@ -1097,13 +1097,13 @@ FIRM_API ir_value_classify_sign classify_value_sign(ir_node *n);
  * Return the value of a Cmp if one or both predecessors
  * are Confirm nodes.
  *
- * @param cmp    the compare node that will be evaluated
- * @param left   the left operand of the Cmp
- * @param right  the right operand of the Cmp
- * @param pnc    the compare relation
+ * @param cmp       the compare node that will be evaluated
+ * @param left      the left operand of the Cmp
+ * @param right     the right operand of the Cmp
+ * @param relation  the compare relation
  */
 FIRM_API ir_tarval *computed_value_Cmp_Confirm(
-       ir_node *cmp, ir_node *left, ir_node *right, pn_Cmp pnc);
+       const ir_node *cmp, ir_node *left, ir_node *right, ir_relation relation);
 
 #include "end.h"
 
index 37487c8..078174e 100644 (file)
  * @sa
  *    Techreport 1999-14
  *    irmode.h for the modes definitions
- *    irnode.h for the pn_Cmp table
  */
 #ifndef FIRM_TV_TV_H
 #define FIRM_TV_TV_H
 
+#include <stddef.h>
 #include "firm_types.h"
-#include "irnode.h"
 
 #include "begin.h"
 
@@ -406,23 +405,15 @@ FIRM_API tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void);
 /**
  * Compares two tarvals
  *
- * Compare a with b and return a pn_Cmp describing the relation
- * between a and b.  This is either pn_Cmp_Uo, pn_Cmp_Lt, pn_Cmp_Eq, pn_Cmp_Gt,
- * or pn_Cmp_False if a or b are symbolic pointers which can not be compared at all.
+ * Compare a with b and return their relation.
+ * This is either ir_rel_unordered, ir_rel_less, ir_rel_greater, ir_rel_equal
+ * or ir_rel_false if a or b are symbolic pointers which can not be compared at
+ * all.
  *
  * @param a   the first tarval to be compared
  * @param b   the second tarval to be compared
- *
- * @return
- *   The pn_Cmp best describing the relation between a and b is returned.
- *   This means the mode with the least bits set is returned, e.g. if the
- *   tarvals are equal the pn_Cmp 'pn_Cmp_Eq' is returned, not 'pn_Cmp_Ge' which
- *   indicates 'greater or equal'
- *
- * @sa
- *    irnode.h for the definition of pn_Cmp
  */
-FIRM_API pn_Cmp tarval_cmp(ir_tarval *a, ir_tarval *b);
+FIRM_API ir_relation tarval_cmp(ir_tarval *a, ir_tarval *b);
 
 /**
  * Converts a tarval to another mode.
index 48478ea..9a58bae 100644 (file)
@@ -61,10 +61,9 @@ FIRM_API void set_vrp_data(ir_graph *irg);
  *
  * @param left: the left node
  * @param right: the right node
- *
- * @return the pn_Cmp, if one can be derived
+ * @return all possible relations
  */
-FIRM_API pn_Cmp vrp_cmp(const ir_node *left, const ir_node *right);
+FIRM_API ir_relation vrp_cmp(const ir_node *left, const ir_node *right);
 
 /*
  * Return the vrp data for this node
index 9d2d50e..fd70021 100644 (file)
@@ -245,10 +245,10 @@ static void handle_modeb(ir_node *block, ir_node *selector, pn_Cond pnc, env_t *
  *
  * @param block   the block which is entered by the branch
  * @param cmp     the Cmp node expressing the branch condition
- * @param pnc     the Compare relation for taking this branch
+ * @param rel     the Compare relation for taking this branch
  * @param env     statistical environment
  */
-static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
+static void handle_if(ir_node *block, ir_node *cmp, ir_relation rel, env_t *env)
 {
        ir_node *left  = get_Cmp_left(cmp);
        ir_node *right = get_Cmp_right(cmp);
@@ -274,14 +274,14 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
                left  = right;
                right = t;
 
-               pnc = get_inversed_pnc(pnc);
+               rel = get_inversed_relation(rel);
        }
 
        /*
         * First case: both values are identical.
         * replace the left one by the right (potentially const) one.
         */
-       if (pnc == pn_Cmp_Eq) {
+       if (rel == ir_relation_equal) {
                cond_block = get_Block_cfgpred_block(block, 0);
                for (edge = get_irn_out_edge_first(left); edge; edge = next) {
                        ir_node *user = get_edge_src_irn(edge);
@@ -339,7 +339,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
                                }
                        }
                }
-       } else { /* not pn_Cmp_Eq cases */
+       } else { /* not ir_relation_equal cases */
                ir_node *c = NULL;
 
                foreach_out_edge_safe(left, edge, next) {
@@ -354,7 +354,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
                                 * We can replace the input with a Confirm(left, pnc, right).
                                 */
                                if (! c)
-                                       c = new_r_Confirm(block, left, right, pnc);
+                                       c = new_r_Confirm(block, left, right, rel);
 
                                pos = get_edge_src_pos(edge);
                                set_irn_n(succ, pos, c);
@@ -368,7 +368,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
                        /* also construct inverse Confirms */
                        ir_node *rc = NULL;
 
-                       pnc = get_inversed_pnc(pnc);
+                       rel = get_inversed_relation(rel);
                        foreach_out_edge_safe(right, edge, next) {
                                ir_node *succ = get_edge_src_irn(edge);
                                int     pos;
@@ -384,10 +384,10 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
                                        /*
                                         * Ok, we found a usage of right in a block
                                         * dominated by the branch block.
-                                        * We can replace the input with a Confirm(right, pnc^-1, left).
+                                        * We can replace the input with a Confirm(right, rel^-1, left).
                                         */
                                        if (! rc)
-                                               rc = new_r_Confirm(block, right, left, pnc);
+                                               rc = new_r_Confirm(block, right, left, rel);
 
                                        pos = get_edge_src_pos(edge);
                                        set_irn_n(succ, pos, rc);
@@ -429,7 +429,7 @@ static void insert_Confirm_in_block(ir_node *block, void *data)
 
        if (mode == mode_b) {
                ir_node *cmp;
-               pn_Cmp pnc;
+               ir_relation rel;
 
                handle_modeb(block, selector, (pn_Cond) get_Proj_proj(proj), env);
 
@@ -441,16 +441,16 @@ static void insert_Confirm_in_block(ir_node *block, void *data)
                if (! is_Cmp(cmp))
                        return;
 
-               pnc = (pn_Cmp) get_Proj_proj(selector);
+               rel = get_Cmp_relation(cmp);
 
                if (get_Proj_proj(proj) != pn_Cond_true) {
                        /* it's the false branch */
                        mode = get_irn_mode(get_Cmp_left(cmp));
-                       pnc = get_negated_pnc(pnc, mode);
+                       rel = get_negated_relation(rel);
                }
-               DB((dbg, LEVEL_2, "At %+F using %+F Confirm %=\n", block, cmp, pnc));
+               DB((dbg, LEVEL_2, "At %+F using %+F Confirm %=\n", block, cmp, rel));
 
-               handle_if(block, cmp, pnc, env);
+               handle_if(block, cmp, rel, env);
        } else if (mode_is_int(mode)) {
                long proj_nr = get_Proj_proj(proj);
 
@@ -470,7 +470,7 @@ static int is_non_null_Confirm(const ir_node *ptr)
        for (;;) {
                if (! is_Confirm(ptr))
                        break;
-               if (get_Confirm_cmp(ptr) == pn_Cmp_Lg) {
+               if (get_Confirm_relation(ptr) == ir_relation_less_greater) {
                        ir_node *bound = get_Confirm_bound(ptr);
 
                        if (is_Const(bound) && is_Const_null(bound))
@@ -523,7 +523,7 @@ static void insert_non_null(ir_node *ptr, ir_node *block, env_t *env)
                                ir_mode  *mode = get_irn_mode(ptr);
                                ir_graph *irg  = get_irn_irg(block);
                                c = new_r_Const(irg, get_mode_null(mode));
-                               c = new_r_Confirm(block, ptr, c, pn_Cmp_Lg);
+                               c = new_r_Confirm(block, ptr, c, ir_relation_less_greater);
                        }
 
                        set_irn_n(succ, pos, c);
index e400a2e..6888f42 100644 (file)
@@ -133,7 +133,7 @@ static ir_alias_relation check_const(const ir_node *cns, int size)
        if (size == 0)
                return tarval_is_null(tv) ? ir_may_alias : ir_no_alias;
        tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
-       return tarval_cmp(tv_size, tv) & (pn_Cmp_Eq|pn_Cmp_Lt) ? ir_no_alias : ir_may_alias;
+       return tarval_cmp(tv_size, tv) & (ir_relation_less_equal) ? ir_no_alias : ir_may_alias;
 }  /* check_const */
 
 /**
@@ -201,7 +201,7 @@ static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx
                                } else {
                                        tv_size = new_tarval_from_long(size, m2);
 
-                                       if (tarval_cmp(tv2, tv_size) & (pn_Cmp_Eq|pn_Cmp_Gt)) {
+                                       if (tarval_cmp(tv2, tv_size) & (ir_relation_greater_equal)) {
                                                /* tv1 is negative and tv2 >= tv_size, so the difference is bigger than size */
                                                return ir_no_alias;
                                        }
@@ -215,11 +215,11 @@ static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx
                                        tv1 = tarval_convert_to(tv1, m2);
 
                                        /* now we can compare without overflow */
-                                       return tarval_cmp(tv1, tv2) & (pn_Cmp_Eq|pn_Cmp_Gt) ? ir_no_alias : ir_may_alias;
+                                       return tarval_cmp(tv1, tv2) & (ir_relation_greater_equal) ? ir_no_alias : ir_may_alias;
                                }
                        }
                }
-               if (tarval_cmp(tv1, tv2) == pn_Cmp_Gt) {
+               if (tarval_cmp(tv1, tv2) == ir_relation_greater) {
                        ir_tarval *t = tv1;
                        tv1 = tv2;
                        tv2 = t;
@@ -227,7 +227,7 @@ static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx
                /* tv1 is now the "smaller" one */
                tv      = tarval_sub(tv2, tv1, NULL);
                tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
-               return tarval_cmp(tv_size, tv) & (pn_Cmp_Eq|pn_Cmp_Lt) ? ir_no_alias : ir_may_alias;
+               return tarval_cmp(tv_size, tv) & (ir_relation_less_equal) ? ir_no_alias : ir_may_alias;
        }
 
        /* Note: we rely here on the fact that normalization puts constants on the RIGHT side */
index b86ebe6..66cefa3 100644 (file)
@@ -283,29 +283,31 @@ static int vrp_update_node(ir_node *node)
                new_bits_set = tarval_and(
                                new_bits_not_set, tarval_convert_to(vrp_pred->bits_set, new_mode));
 
-               if (tarval_cmp(vrp_pred->range_top, get_mode_max(new_mode)) == pn_Cmp_Le) {
+               /* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_less_equal */
+               if (tarval_cmp(vrp_pred->range_top, get_mode_max(new_mode)) == ir_relation_less_equal) {
                        vrp->range_top = vrp_pred->range_top;
                }
 
-               if (tarval_cmp(vrp_pred->range_bottom, get_mode_min(new_mode)) == pn_Cmp_Ge) {
+               /* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_greater_equal */
+               if (tarval_cmp(vrp_pred->range_bottom, get_mode_min(new_mode)) == ir_relation_greater_equal) {
                        vrp->range_bottom = vrp_pred->range_bottom;
                }
                break;
        }
 
        case iro_Confirm: {
-               const pn_Cmp cmp = get_Confirm_cmp(node);
-               const ir_node *bound = get_Confirm_bound(node);
+               const ir_relation relation = get_Confirm_relation(node);
+               const ir_node    *bound    = get_Confirm_bound(node);
 
 
-               if (cmp == pn_Cmp_Lg) {
+               if (relation == ir_relation_less_greater) {
                        /** @todo: Handle non-Const bounds */
                        if (is_Const(bound)) {
                                new_range_type = VRP_ANTIRANGE;
                                new_range_top = get_Const_tarval(bound);
                                new_range_bottom = get_Const_tarval(bound);
                        }
-               } else if (cmp == pn_Cmp_Le) {
+               } else if (relation == ir_relation_less_equal) {
                        if (is_Const(bound)) {
                                new_range_type = VRP_RANGE;
                                new_range_top = get_Const_tarval(bound);
@@ -319,7 +321,7 @@ static int vrp_update_node(ir_node *node)
                /* combine all ranges*/
 
                int num = get_Phi_n_preds(node);
-               pn_Cmp cmp;
+               ir_relation relation;
                int i;
 
                const ir_node *pred = get_Phi_pred(node,0);
@@ -337,12 +339,12 @@ static int vrp_update_node(ir_node *node)
                        vrp_pred = get_vrp_attr(pred);
                        if (new_range_type == VRP_RANGE && vrp_pred->range_type ==
                                        VRP_RANGE) {
-                               cmp = tarval_cmp(new_range_top, vrp_pred->range_top);
-                               if (cmp == pn_Cmp_Lt) {
+                               relation = tarval_cmp(new_range_top, vrp_pred->range_top);
+                               if (relation == ir_relation_less) {
                                        new_range_top = vrp_pred->range_top;
                                }
-                               cmp = tarval_cmp(new_range_bottom, vrp_pred->range_bottom);
-                               if (cmp == pn_Cmp_Gt) {
+                               relation = tarval_cmp(new_range_bottom, vrp_pred->range_bottom);
+                               if (relation == ir_relation_greater) {
                                        new_range_bottom = vrp_pred->range_bottom;
                                }
                        } else {
@@ -395,7 +397,7 @@ static int vrp_update_node(ir_node *node)
        /* Merge the newly calculated values with those that might already exist*/
        if (new_bits_set != tarval_bad) {
                new_bits_set = tarval_or(new_bits_set, vrp->bits_set);
-               if (tarval_cmp(new_bits_set, vrp->bits_set) != pn_Cmp_Eq) {
+               if (tarval_cmp(new_bits_set, vrp->bits_set) != ir_relation_equal) {
                        something_changed = 1;
                        vrp->bits_set = new_bits_set;
                }
@@ -403,7 +405,7 @@ static int vrp_update_node(ir_node *node)
        if (new_bits_not_set != tarval_bad) {
                new_bits_not_set = tarval_and(new_bits_not_set, vrp->bits_not_set);
 
-               if (tarval_cmp(new_bits_not_set, vrp->bits_not_set) != pn_Cmp_Eq) {
+               if (tarval_cmp(new_bits_not_set, vrp->bits_not_set) != ir_relation_equal) {
                        something_changed = 1;
                        vrp->bits_not_set = new_bits_not_set;
                }
@@ -418,11 +420,11 @@ static int vrp_update_node(ir_node *node)
 
        } else if (vrp->range_type == VRP_RANGE) {
                if (new_range_type == VRP_RANGE) {
-                       if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Lt) {
+                       if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_less) {
                                something_changed = 1;
                                vrp->range_bottom = new_range_bottom;
                        }
-                       if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Gt) {
+                       if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_greater) {
                                something_changed = 1;
                                vrp->range_top = new_range_top;
                        }
@@ -431,13 +433,13 @@ static int vrp_update_node(ir_node *node)
                if (new_range_type == VRP_ANTIRANGE) {
                        /* if they are overlapping, cut the range.*/
                        /* TODO: Maybe we can preserve more information here*/
-                       if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt &&
-                                       tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) {
+                       if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater &&
+                                       tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
                                something_changed = 1;
                                vrp->range_bottom = new_range_top;
 
-                       } else if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Gt &&
-                                       tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) {
+                       } else if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_greater &&
+                                       tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
                                something_changed = 1;
                                vrp->range_top = new_range_bottom;
                        }
@@ -448,22 +450,22 @@ static int vrp_update_node(ir_node *node)
                }
        } else if (vrp->range_type == VRP_ANTIRANGE) {
                if (new_range_type == VRP_ANTIRANGE) {
-                       if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) {
+                       if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
                                something_changed = 1;
                                vrp->range_bottom = new_range_bottom;
                        }
-                       if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) {
+                       if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
                                something_changed = 1;
                                vrp->range_top = new_range_top;
                        }
                }
 
                if (new_range_type == VRP_RANGE) {
-                       if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt) {
+                       if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater) {
                                something_changed = 1;
                                vrp->range_bottom = new_range_top;
                        }
-                       if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Lt) {
+                       if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_less) {
                                something_changed = 1;
                                vrp->range_top = new_range_bottom;
                        }
@@ -586,33 +588,32 @@ ir_graph_pass_t *set_vrp_pass(const char *name)
        return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
 }
 
-pn_Cmp vrp_cmp(const ir_node *left, const ir_node *right)
+ir_relation vrp_cmp(const ir_node *left, const ir_node *right)
 {
        vrp_attr *vrp_left, *vrp_right;
 
        vrp_left = vrp_get_info(left);
        vrp_right = vrp_get_info(right);
 
-       if (!vrp_left || !vrp_right) {
-               return pn_Cmp_False;
-       }
+       if (!vrp_left || !vrp_right)
+               return ir_relation_true;
 
        if (vrp_left->range_type == VRP_RANGE && vrp_right->range_type == VRP_RANGE) {
-               if (tarval_cmp(vrp_left->range_top, vrp_right->range_bottom) == pn_Cmp_Lt) {
-                       return pn_Cmp_Lt;
+               if (tarval_cmp(vrp_left->range_top, vrp_right->range_bottom) == ir_relation_less) {
+                       return ir_relation_less;
                }
-               if (tarval_cmp(vrp_left->range_bottom, vrp_right->range_top) == pn_Cmp_Gt) {
-                       return pn_Cmp_Gt;
+               if (tarval_cmp(vrp_left->range_bottom, vrp_right->range_top) == ir_relation_greater) {
+                       return ir_relation_greater;
                }
        }
 
        if (!tarval_is_null(tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set))) ||
                        !tarval_is_null(tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set))) {
-               return pn_Cmp_Lg;
+               return ir_relation_less_greater;
        }
-       /* TODO: We can get way more information here*/
 
-       return pn_Cmp_False;
+       /* TODO: We can get way more information here*/
+       return ir_relation_true;
 }
 
 vrp_attr *vrp_get_info(const ir_node *node)
index 7f38b80..0f01520 100644 (file)
@@ -278,7 +278,7 @@ static void emit_amd64_Jcc(const ir_node *irn)
        const ir_node        *next_block;
        const char           *suffix;
        const amd64_attr_t   *attr      = get_amd64_attr_const(irn);
-       int                   proj_num  = attr->ext.pnc;
+       ir_relation           relation  = attr->ext.relation;
        ir_node              *op1       = get_irn_n(irn, 0);
        const amd64_attr_t   *cmp_attr  = get_amd64_attr_const(op1);
        bool                  is_signed = !cmp_attr->data.cmp_unsigned;
@@ -296,7 +296,7 @@ static void emit_amd64_Jcc(const ir_node *irn)
        }
 
        if (cmp_attr->data.ins_permuted) {
-               proj_num = get_mirrored_pnc(proj_num);
+               relation = get_inversed_relation(relation);
        }
 
        /* for now, the code works for scheduled and non-schedules blocks */
@@ -305,8 +305,8 @@ static void emit_amd64_Jcc(const ir_node *irn)
        /* we have a block schedule */
        next_block = sched_next_block(block);
 
-       assert(proj_num != pn_Cmp_False);
-       assert(proj_num != pn_Cmp_True);
+       assert(relation != ir_relation_false);
+       assert(relation != ir_relation_true);
 
        if (get_cfop_target_block(proj_true) == next_block) {
                /* exchange both proj's so the second one can be omitted */
@@ -314,17 +314,17 @@ static void emit_amd64_Jcc(const ir_node *irn)
 
                proj_true  = proj_false;
                proj_false = t;
-               proj_num   = get_negated_pnc(proj_num, mode_Lu);
+               relation   = get_negated_relation(relation);
        }
 
-       switch (proj_num) {
-               case pn_Cmp_Eq:  suffix = "e"; break;
-               case pn_Cmp_Lt:  suffix = is_signed ? "l"  : "b"; break;
-               case pn_Cmp_Le:  suffix = is_signed ? "le" : "be"; break;
-               case pn_Cmp_Gt:  suffix = is_signed ? "g"  : "a"; break;
-               case pn_Cmp_Ge:  suffix = is_signed ? "ge" : "ae"; break;
-               case pn_Cmp_Lg:  suffix = "ne"; break;
-               case pn_Cmp_Leg: suffix = "mp"; break;
+       switch (relation) {
+               case ir_relation_equal:              suffix = "e"; break;
+               case ir_relation_less:               suffix = is_signed ? "l"  : "b"; break;
+               case ir_relation_less_equal:         suffix = is_signed ? "le" : "be"; break;
+               case ir_relation_greater:            suffix = is_signed ? "g"  : "a"; break;
+               case ir_relation_greater_equal:      suffix = is_signed ? "ge" : "ae"; break;
+               case ir_relation_less_greater:       suffix = "ne"; break;
+               case ir_relation_less_equal_greater: suffix = "mp"; break;
                default: panic("Cmp has unsupported pnc");
        }
 
index 551b7e6..2eff121 100644 (file)
@@ -138,7 +138,7 @@ static void init_amd64_attributes(ir_node *node, arch_irn_flags_t flags,
 
        attr->data.ins_permuted = 0;
        attr->data.cmp_unsigned = 0;
-       attr->ext.pnc           = (pn_Cmp)0;
+       attr->ext.relation      = ir_relation_false;
        attr->ext.imm_value     = 0;
 }
 
index 9d69260..b909a29 100644 (file)
@@ -40,8 +40,8 @@ struct amd64_attr_t
                unsigned cmp_unsigned : 1;      /**< compare should be unsigned */
        } data;
        struct amd64_attr_extended {
-               pn_Cmp   pnc;                   /**< type of compare operation >*/
-               unsigned imm_value;             /**< immediate value to use >*/
+               ir_relation relation;           /**< type of compare operation >*/
+               unsigned    imm_value;          /**< immediate value to use >*/
        } ext;
 };
 
index c61424d..6413609 100644 (file)
@@ -267,8 +267,8 @@ Jcc => {
        reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
        ins       => [ "eflags" ],
        outs      => [ "false", "true" ],
-       attr      => "pn_Cmp pnc",
-       init_attr => "attr->ext.pnc = pnc;",
+       attr      => "ir_relation relation",
+       init_attr => "attr->ext.relation = relation;",
        mode      => "mode_T",
 },
 Load => {
index b4593a1..0d623d6 100644 (file)
@@ -224,23 +224,25 @@ static ir_node *gen_Cmp(ir_node *node)
  */
 static ir_node *gen_Cond(ir_node *node)
 {
-       ir_node  *selector = get_Cond_selector(node);
-       ir_mode  *mode     = get_irn_mode(selector);
-       ir_node  *block;
-       ir_node  *flag_node;
-       dbg_info *dbgi;
+       ir_node    *selector = get_Cond_selector(node);
+       ir_mode    *mode     = get_irn_mode(selector);
+       ir_node    *block;
+       ir_node    *flag_node;
+       ir_relation relation;
+       dbg_info   *dbgi;
 
        if (mode != mode_b) {
                panic ("create_Switch not implemented yet!");
                // return gen_SwitchJmp(node);
        }
-       assert(is_Proj(selector));
+       assert(is_Cmp(selector));
 
        block     = be_transform_node(get_nodes_block(node));
        dbgi      = get_irn_dbg_info(node);
-       flag_node = be_transform_node(get_Proj_pred(selector));
+       flag_node = be_transform_node(selector);
+       relation  = get_Cmp_relation(selector);
 
-       return new_bd_amd64_Jcc(dbgi, block, flag_node, get_Proj_pn_cmp(selector));
+       return new_bd_amd64_Jcc(dbgi, block, flag_node, relation);
 }
 
 #if 0
index c50f1f7..0744d62 100644 (file)
@@ -426,7 +426,7 @@ static void emit_arm_B(const ir_node *irn)
        const ir_node *next_block;
        ir_node *op1 = get_irn_n(irn, 0);
        const char *suffix;
-       pn_Cmp pnc = get_arm_CondJmp_pnc(irn);
+       ir_relation relation = get_arm_CondJmp_relation(irn);
        const arm_cmp_attr_t *cmp_attr = get_arm_cmp_attr_const(op1);
        bool is_signed = !cmp_attr->is_unsigned;
 
@@ -443,7 +443,7 @@ static void emit_arm_B(const ir_node *irn)
        }
 
        if (cmp_attr->ins_permuted) {
-               pnc = get_mirrored_pnc(pnc);
+               relation = get_inversed_relation(relation);
        }
 
        /* for now, the code works for scheduled and non-schedules blocks */
@@ -452,8 +452,8 @@ static void emit_arm_B(const ir_node *irn)
        /* we have a block schedule */
        next_block = sched_next_block(block);
 
-       assert(pnc != pn_Cmp_False);
-       assert(pnc != pn_Cmp_True);
+       assert(relation != ir_relation_false);
+       assert(relation != ir_relation_true);
 
        if (get_cfop_target_block(proj_true) == next_block) {
                /* exchange both proj's so the second one can be omitted */
@@ -461,18 +461,18 @@ static void emit_arm_B(const ir_node *irn)
 
                proj_true  = proj_false;
                proj_false = t;
-               pnc        = get_negated_pnc(pnc, mode_Iu);
+               relation   = get_negated_relation(relation);
        }
 
-       switch (pnc) {
-               case pn_Cmp_Eq:  suffix = "eq"; break;
-               case pn_Cmp_Lt:  suffix = is_signed ? "lt" : "lo"; break;
-               case pn_Cmp_Le:  suffix = is_signed ? "le" : "ls"; break;
-               case pn_Cmp_Gt:  suffix = is_signed ? "gt" : "hi"; break;
-               case pn_Cmp_Ge:  suffix = is_signed ? "ge" : "hs"; break;
-               case pn_Cmp_Lg:  suffix = "ne"; break;
-               case pn_Cmp_Leg: suffix = "al"; break;
-               default: panic("Cmp has unsupported pnc");
+       switch (relation & (ir_relation_less_equal_greater)) {
+               case ir_relation_equal:         suffix = "eq"; break;
+               case ir_relation_less:          suffix = is_signed ? "lt" : "lo"; break;
+               case ir_relation_less_equal:    suffix = is_signed ? "le" : "ls"; break;
+               case ir_relation_greater:       suffix = is_signed ? "gt" : "hi"; break;
+               case ir_relation_greater_equal: suffix = is_signed ? "ge" : "hs"; break;
+               case ir_relation_less_greater:  suffix = "ne"; break;
+               case ir_relation_less_equal_greater: suffix = "al"; break;
+               default: panic("Cmp has unsupported relation");
        }
 
        /* emit the true proj */
index 6792eb0..400df4a 100644 (file)
@@ -312,16 +312,16 @@ void set_fConst_value(ir_node *node, ir_tarval *tv)
        attr->tv = tv;
 }
 
-pn_Cmp get_arm_CondJmp_pnc(const ir_node *node)
+ir_relation get_arm_CondJmp_relation(const ir_node *node)
 {
        const arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr_const(node);
-       return attr->pnc;
+       return attr->relation;
 }
 
-void set_arm_CondJmp_pnc(ir_node *node, pn_Cmp pnc)
+void set_arm_CondJmp_relation(ir_node *node, ir_relation relation)
 {
        arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr(node);
-       attr->pnc = pnc;
+       attr->relation = relation;
 }
 
 int get_arm_SwitchJmp_n_projs(const ir_node *node)
index 14ca0b0..fd9c083 100644 (file)
@@ -81,12 +81,12 @@ void set_fConst_value(ir_node *node, ir_tarval *tv);
 /**
  * Returns the compare kind
  */
-pn_Cmp get_arm_CondJmp_pnc(const ir_node *node);
+ir_relation get_arm_CondJmp_relation(const ir_node *node);
 
 /**
  * Set compare type
  */
-void set_arm_CondJmp_pnc(ir_node *node, pn_Cmp pnc);
+void set_arm_CondJmp_relation(ir_node *node, ir_relation relation);
 
 ir_node *new_r_arm_StoreStackMInc(ir_graph *irg, ir_node *block, ir_node *mem, ir_node *sp,
                                                              int n_regs, ir_node **regs, ir_mode *mode);
index 40bd15d..dfe8e54 100644 (file)
@@ -107,7 +107,7 @@ typedef struct arm_SymConst_attr_t {
 /** Attributes for a CondJmp */
 typedef struct arm_CondJmp_attr_t {
        arm_attr_t  base;
-       pn_Cmp      pnc;
+       ir_relation relation;
 } arm_CondJmp_attr_t;
 
 /** Attributes for a SwitchJmp */
index f4746d4..471f7d3 100644 (file)
@@ -399,9 +399,9 @@ B => {
        state     => "pinned",
        mode      => "mode_T",
        reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
-       attr      => "pn_Cmp pnc",
+       attr      => "ir_relation relation",
        attr_type => "arm_CondJmp_attr_t",
-       init_attr => "\tset_arm_CondJmp_pnc(res, pnc);",
+       init_attr => "\tset_arm_CondJmp_relation(res, relation);",
 },
 
 Jmp => {
index c357f5b..ca0e967 100644 (file)
@@ -1058,22 +1058,24 @@ static ir_node *gen_Cmp(ir_node *node)
 
 static ir_node *gen_Cond(ir_node *node)
 {
-       ir_node  *selector = get_Cond_selector(node);
-       ir_mode  *mode     = get_irn_mode(selector);
-       ir_node  *block;
-       ir_node  *flag_node;
-       dbg_info *dbgi;
+       ir_node    *selector = get_Cond_selector(node);
+       ir_mode    *mode     = get_irn_mode(selector);
+       ir_relation relation;
+       ir_node    *block;
+       ir_node    *flag_node;
+       dbg_info   *dbgi;
 
        if (mode != mode_b) {
                return gen_SwitchJmp(node);
        }
-       assert(is_Proj(selector));
+       assert(is_Cmp(selector));
 
        block     = be_transform_node(get_nodes_block(node));
        dbgi      = get_irn_dbg_info(node);
-       flag_node = be_transform_node(get_Proj_pred(selector));
+       flag_node = be_transform_node(selector);
+       relation  = get_Cmp_relation(selector);
 
-       return new_bd_arm_B(dbgi, block, flag_node, get_Proj_pn_cmp(selector));
+       return new_bd_arm_B(dbgi, block, flag_node, relation);
 }
 
 enum fpa_imm_mode {
index 42fd04b..c02a1e4 100644 (file)
@@ -27,6 +27,7 @@
 #include "config.h"
 
 #include "beemitter.h"
+#include "irnode_t.h"
 #include "irprintf.h"
 #include "ident.h"
 #include "tv.h"
index 0c098b5..c095e94 100644 (file)
@@ -470,16 +470,12 @@ void be_transform_graph(ir_graph *irg, arch_pretrans_nodes *func)
 
 int be_mux_is_abs(ir_node *sel, ir_node *mux_true, ir_node *mux_false)
 {
-       ir_node *cmp_left;
-       ir_node *cmp_right;
-       ir_node *cmp;
-       ir_mode *mode;
-       pn_Cmp   pnc;
+       ir_node    *cmp_left;
+       ir_node    *cmp_right;
+       ir_mode    *mode;
+       ir_relation relation;
 
-       if (!is_Proj(sel))
-               return 0;
-       cmp = get_Proj_pred(sel);
-       if (!is_Cmp(cmp))
+       if (!is_Cmp(sel))
                return 0;
 
        /**
@@ -493,42 +489,31 @@ int be_mux_is_abs(ir_node *sel, ir_node *mux_true, ir_node *mux_false)
                return 0;
 
        /* must be <, <=, >=, > */
-       pnc = get_Proj_pn_cmp(sel);
-       switch (pnc) {
-       case pn_Cmp_Ge:
-       case pn_Cmp_Gt:
-       case pn_Cmp_Le:
-       case pn_Cmp_Lt:
-       case pn_Cmp_Uge:
-       case pn_Cmp_Ug:
-       case pn_Cmp_Ul:
-       case pn_Cmp_Ule:
-               break;
-       default:
+       relation = get_Cmp_relation(sel);
+       if ((relation & ir_relation_less_greater) == 0)
                return 0;
-       }
 
        if (!is_negated_value(mux_true, mux_false))
                return 0;
 
        /* must be x cmp 0 */
-       cmp_right = get_Cmp_right(cmp);
+       cmp_right = get_Cmp_right(sel);
        if (!is_Const(cmp_right) || !is_Const_null(cmp_right))
                return 0;
 
-       cmp_left = get_Cmp_left(cmp);
+       cmp_left = get_Cmp_left(sel);
        if (cmp_left == mux_false) {
-               if (pnc & pn_Cmp_Lt) {
+               if (relation & ir_relation_less) {
                        return 1;
                } else {
-                       assert(pnc & pn_Cmp_Gt);
+                       assert(relation & ir_relation_greater);
                        return -1;
                }
        } else if (cmp_left == mux_true) {
-               if (pnc & pn_Cmp_Lt) {
+               if (relation & ir_relation_less) {
                        return -1;
                } else {
-                       assert(pnc & pn_Cmp_Gt);
+                       assert(relation & ir_relation_greater);
                        return 1;
                }
        }
@@ -538,7 +523,6 @@ int be_mux_is_abs(ir_node *sel, ir_node *mux_true, ir_node *mux_false)
 
 ir_node *be_get_abs_op(ir_node *sel)
 {
-       ir_node *cmp      = get_Proj_pred(sel);
-       ir_node *cmp_left = get_Cmp_left(cmp);
+       ir_node *cmp_left = get_Cmp_left(sel);
        return cmp_left;
 }
index 4a70e2c..577ad89 100644 (file)
@@ -1819,19 +1819,15 @@ static void ia32_mark_remat(ir_node *node)
 static bool mux_is_float_min_max(ir_node *sel, ir_node *mux_true,
                                  ir_node *mux_false)
 {
-       ir_node *cmp_l;
-       ir_node *cmp_r;
-       ir_node *cmp;
-       pn_Cmp  pnc;
+       ir_node    *cmp_l;
+       ir_node    *cmp_r;
+       ir_relation relation;
 
-       if (!is_Proj(sel))
-               return false;
-       cmp = get_Proj_pred(sel);
-       if (!is_Cmp(cmp))
+       if (!is_Cmp(sel))
                return false;
 
-       cmp_l = get_Cmp_left(cmp);
-       cmp_r = get_Cmp_right(cmp);
+       cmp_l = get_Cmp_left(sel);
+       cmp_r = get_Cmp_right(sel);
        if (!mode_is_float(get_irn_mode(cmp_l)))
                return false;
 
@@ -1842,28 +1838,28 @@ static bool mux_is_float_min_max(ir_node *sel, ir_node *mux_true,
         *  or max(a, b) = a >= b ? a : b
         * (Note we only handle float min/max here)
         */
-       pnc = get_Proj_pn_cmp(sel);
-       switch (pnc) {
-       case pn_Cmp_Ge:
-       case pn_Cmp_Gt:
+       relation = get_Cmp_relation(sel);
+       switch (relation) {
+       case ir_relation_greater_equal:
+       case ir_relation_greater:
                /* this is a max */
                if (cmp_l == mux_true && cmp_r == mux_false)
                        return true;
                break;
-       case pn_Cmp_Le:
-       case pn_Cmp_Lt:
+       case ir_relation_less_equal:
+       case ir_relation_less:
                /* this is a min */
                if (cmp_l == mux_true && cmp_r == mux_false)
                        return true;
                break;
-       case pn_Cmp_Uge:
-       case pn_Cmp_Ug:
+       case ir_relation_unordered_greater_equal:
+       case ir_relation_unordered_greater:
                /* this is a min */
                if (cmp_l == mux_false && cmp_r == mux_true)
                        return true;
                break;
-       case pn_Cmp_Ule:
-       case pn_Cmp_Ul:
+       case ir_relation_unordered_less_equal:
+       case ir_relation_unordered_less:
                /* this is a max */
                if (cmp_l == mux_false && cmp_r == mux_true)
                        return true;
@@ -1886,7 +1882,8 @@ static bool mux_is_set(ir_node *sel, ir_node *mux_true, ir_node *mux_false)
                return false;
 
        if (is_Const(mux_true) && is_Const(mux_false)) {
-               /* we can create a set plus up two 3 instructions for any combination of constants */
+               /* we can create a set plus up two 3 instructions for any combination
+                * of constants */
                return true;
        }
 
@@ -1906,35 +1903,30 @@ static bool mux_is_float_const_const(ir_node *sel, ir_node *mux_true,
 
 static bool mux_is_doz(ir_node *sel, ir_node *mux_true, ir_node *mux_false)
 {
-       ir_node *cmp;
-       ir_node *cmp_left;
-       ir_node *cmp_right;
-       ir_node *sub_left;
-       ir_node *sub_right;
-       ir_mode *mode;
-       long     pn;
-
-       if (!is_Proj(sel))
-               return false;
+       ir_node    *cmp_left;
+       ir_node    *cmp_right;
+       ir_node    *sub_left;
+       ir_node    *sub_right;
+       ir_mode    *mode;
+       ir_relation relation;
 
-       cmp = get_Proj_pred(sel);
-       if (!is_Cmp(cmp))
+       if (!is_Cmp(sel))
                return false;
 
        mode = get_irn_mode(mux_true);
        if (mode_is_signed(mode) || mode_is_float(mode))
                return false;
 
-       pn        = get_Proj_proj(sel);
-       cmp_left  = get_Cmp_left(cmp);
-       cmp_right = get_Cmp_right(cmp);
+       relation  = get_Cmp_relation(sel);
+       cmp_left  = get_Cmp_left(sel);
+       cmp_right = get_Cmp_right(sel);
 
        /* "move" zero constant to false input */
        if (is_Const(mux_true) && is_Const_null(mux_true)) {
                ir_node *tmp = mux_false;
                mux_false = mux_true;
                mux_true  = tmp;
-               pn = get_negated_pnc(pn, mode);
+               relation = get_negated_relation(relation);
        }
        if (!is_Const(mux_false) || !is_Const_null(mux_false))
                return false;
@@ -1944,11 +1936,11 @@ static bool mux_is_doz(ir_node *sel, ir_node *mux_true, ir_node *mux_false)
        sub_right = get_Sub_right(mux_true);
 
        /* Mux(a >=u b, 0, a-b) */
-       if ((pn == pn_Cmp_Gt || pn == pn_Cmp_Ge)
+       if ((relation & ir_relation_greater)
                        && sub_left == cmp_left && sub_right == cmp_right)
                return true;
        /* Mux(a <=u b, 0, b-a) */
-       if ((pn == pn_Cmp_Lt || pn == pn_Cmp_Le)
+       if ((relation & ir_relation_less)
                        && sub_left == cmp_right && sub_right == cmp_left)
                return true;
 
index f3472c0..2a522d7 100644 (file)
@@ -269,7 +269,8 @@ static int map_Shl(ir_node *call, void *ctx)
                /* the shift count is a const, create better code */
                ir_tarval *tv = get_Const_tarval(cnt);
 
-               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
+               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode))
+                               & (ir_relation_greater_equal)) {
                        /* simplest case: shift only the lower bits. Note that there is no
                           need to reduce the constant here, this is done by the hardware.  */
                        ir_node *conv = new_rd_Conv(dbg, block, a_l, h_mode);
@@ -300,8 +301,7 @@ static int map_Shl(ir_node *call, void *ctx)
        c_mode = get_irn_mode(cnt);
        irn    = new_r_Const_long(irg, c_mode, 32);
        irn    = new_rd_And(dbg, upper, cnt, irn, c_mode);
-       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)));
-       irn    = new_r_Proj(irn, mode_b, pn_Cmp_Eq);
+       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)), ir_relation_equal);
        cond   = new_rd_Cond(dbg, upper, irn);
 
        in[0]  = new_r_Proj(cond, mode_X, pn_Cond_true);
@@ -360,7 +360,7 @@ static int map_Shr(ir_node *call, void *ctx)
                /* the shift count is a const, create better code */
                ir_tarval *tv = get_Const_tarval(cnt);
 
-               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
+               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (ir_relation_greater_equal)) {
                        /* simplest case: shift only the higher bits. Note that there is no
                           need to reduce the constant here, this is done by the hardware.  */
                        ir_node *conv = new_rd_Conv(dbg, block, a_h, l_mode);
@@ -389,8 +389,7 @@ static int map_Shr(ir_node *call, void *ctx)
        c_mode = get_irn_mode(cnt);
        irn    = new_r_Const_long(irg, c_mode, 32);
        irn    = new_rd_And(dbg, upper, cnt, irn, c_mode);
-       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)));
-       irn    = new_r_Proj(irn, mode_b, pn_Cmp_Eq);
+       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)), ir_relation_equal);
        cond   = new_rd_Cond(dbg, upper, irn);
 
        in[0]  = new_r_Proj(cond, mode_X, pn_Cond_true);
@@ -449,7 +448,7 @@ static int map_Shrs(ir_node *call, void *ctx)
                /* the shift count is a const, create better code */
                ir_tarval *tv = get_Const_tarval(cnt);
 
-               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
+               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (ir_relation_greater_equal)) {
                        /* simplest case: shift only the higher bits. Note that there is no
                           need to reduce the constant here, this is done by the hardware.  */
                        ir_node *conv    = new_rd_Conv(dbg, block, a_h, l_mode);
@@ -480,8 +479,7 @@ static int map_Shrs(ir_node *call, void *ctx)
        c_mode = get_irn_mode(cnt);
        irn    = new_r_Const_long(irg, c_mode, 32);
        irn    = new_rd_And(dbg, upper, cnt, irn, c_mode);
-       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)));
-       irn    = new_r_Proj(irn, mode_b, pn_Cmp_Eq);
+       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)), ir_relation_equal);
        cond   = new_rd_Cond(dbg, upper, irn);
 
        in[0]  = new_r_Proj(cond, mode_X, pn_Cond_true);
@@ -822,9 +820,8 @@ static int map_Conv(ir_node *call, void *ctx)
                        part_block(call);
                        upper_blk = get_nodes_block(call);
 
-                       cmp   = new_rd_Cmp(dbg, upper_blk, a_f, flt_corr);
-                       proj  = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
-                       cond  = new_rd_Cond(dbg, upper_blk, proj);
+                       cmp   = new_rd_Cmp(dbg, upper_blk, a_f, flt_corr, ir_relation_less);
+                       cond  = new_rd_Cond(dbg, upper_blk, cmp);
                        in[0] = new_r_Proj(cond, mode_X, pn_Cond_true);
                        in[1] = new_r_Proj(cond, mode_X, pn_Cond_false);
                        blk   = new_r_Block(irg, 1, &in[1]);
index b9d93b7..ba5c056 100644 (file)
@@ -1916,73 +1916,75 @@ static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
        return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
 }
 
-static ia32_condition_code_t pnc_to_condition_code(pn_Cmp pnc, ir_mode *mode)
+static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
+                                                        ir_mode *mode)
 {
        if (mode_is_float(mode)) {
-               switch (pnc) {
-               case pn_Cmp_Eq:  return ia32_cc_float_equal;
-               case pn_Cmp_Lt:  return ia32_cc_float_below;
-               case pn_Cmp_Le:  return ia32_cc_float_below_equal;
-               case pn_Cmp_Gt:  return ia32_cc_float_above;
-               case pn_Cmp_Ge:  return ia32_cc_float_above_equal;
-               case pn_Cmp_Lg:  return ia32_cc_not_equal;
-               case pn_Cmp_Leg: return ia32_cc_not_parity;
-               case pn_Cmp_Uo:  return ia32_cc_parity;
-               case pn_Cmp_Ue:  return ia32_cc_equal;
-               case pn_Cmp_Ul:  return ia32_cc_float_unordered_below;
-               case pn_Cmp_Ule: return ia32_cc_float_unordered_below_equal;
-               case pn_Cmp_Ug:  return ia32_cc_float_unordered_above;
-               case pn_Cmp_Uge: return ia32_cc_float_unordered_above_equal;
-               case pn_Cmp_Ne:  return ia32_cc_float_not_equal;
-               case pn_Cmp_False:
-               case pn_Cmp_True:
-               case pn_Cmp_max:
+               switch (relation) {
+               case ir_relation_equal:              return ia32_cc_float_equal;
+               case ir_relation_less:               return ia32_cc_float_below;
+               case ir_relation_less_equal:         return ia32_cc_float_below_equal;
+               case ir_relation_greater:            return ia32_cc_float_above;
+               case ir_relation_greater_equal:      return ia32_cc_float_above_equal;
+               case ir_relation_less_greater:       return ia32_cc_not_equal;
+               case ir_relation_less_equal_greater: return ia32_cc_not_parity;
+               case ir_relation_unordered:          return ia32_cc_parity;
+               case ir_relation_unordered_equal:    return ia32_cc_equal;
+               case ir_relation_unordered_less:   return ia32_cc_float_unordered_below;
+               case ir_relation_unordered_less_equal:
+                                            return ia32_cc_float_unordered_below_equal;
+               case ir_relation_unordered_greater:
+                                            return ia32_cc_float_unordered_above;
+               case ir_relation_unordered_greater_equal:
+                                            return ia32_cc_float_unordered_above_equal;
+               case ir_relation_unordered_less_greater:
+                                            return ia32_cc_float_not_equal;
+               case ir_relation_false:
+               case ir_relation_true:
                        /* should we introduce a jump always/jump never? */
                        break;
                }
                panic("Unexpected float pnc");
        } else if (mode_is_signed(mode)) {
-               switch (pnc) {
-               case pn_Cmp_Ue:
-               case pn_Cmp_Eq:  return ia32_cc_equal;
-               case pn_Cmp_Ul:
-               case pn_Cmp_Lt:  return ia32_cc_less;
-               case pn_Cmp_Ule:
-               case pn_Cmp_Le:  return ia32_cc_less_equal;
-               case pn_Cmp_Ug:
-               case pn_Cmp_Gt:  return ia32_cc_greater;
-               case pn_Cmp_Uge:
-               case pn_Cmp_Ge:  return ia32_cc_greater_equal;
-               case pn_Cmp_Lg:
-               case pn_Cmp_Ne:  return ia32_cc_not_equal;
-               case pn_Cmp_Leg:
-               case pn_Cmp_Uo:
-               case pn_Cmp_False:
-               case pn_Cmp_True:
-               case pn_Cmp_max:
+               switch (relation) {
+               case ir_relation_unordered_equal:
+               case ir_relation_equal:                return ia32_cc_equal;
+               case ir_relation_unordered_less:
+               case ir_relation_less:                 return ia32_cc_less;
+               case ir_relation_unordered_less_equal:
+               case ir_relation_less_equal:           return ia32_cc_less_equal;
+               case ir_relation_unordered_greater:
+               case ir_relation_greater:              return ia32_cc_greater;
+               case ir_relation_unordered_greater_equal:
+               case ir_relation_greater_equal:        return ia32_cc_greater_equal;
+               case ir_relation_unordered_less_greater:
+               case ir_relation_less_greater:         return ia32_cc_not_equal;
+               case ir_relation_less_equal_greater:
+               case ir_relation_unordered:
+               case ir_relation_false:
+               case ir_relation_true:
                        /* introduce jump always/jump never? */
                        break;
                }
                panic("Unexpected pnc");
        } else {
-               switch (pnc) {
-               case pn_Cmp_Ue:
-               case pn_Cmp_Eq:  return ia32_cc_equal;
-               case pn_Cmp_Ul:
-               case pn_Cmp_Lt:  return ia32_cc_below;
-               case pn_Cmp_Ule:
-               case pn_Cmp_Le:  return ia32_cc_below_equal;
-               case pn_Cmp_Ug:
-               case pn_Cmp_Gt:  return ia32_cc_above;
-               case pn_Cmp_Uge:
-               case pn_Cmp_Ge:  return ia32_cc_above_equal;
-               case pn_Cmp_Lg:
-               case pn_Cmp_Ne:  return ia32_cc_not_equal;
-               case pn_Cmp_Leg:
-               case pn_Cmp_Uo:
-               case pn_Cmp_False:
-               case pn_Cmp_True:
-               case pn_Cmp_max:
+               switch (relation) {
+               case ir_relation_unordered_equal:
+               case ir_relation_equal:         return ia32_cc_equal;
+               case ir_relation_unordered_less:
+               case ir_relation_less:          return ia32_cc_below;
+               case ir_relation_unordered_less_equal:
+               case ir_relation_less_equal:    return ia32_cc_below_equal;
+               case ir_relation_unordered_greater:
+               case ir_relation_greater:       return ia32_cc_above;
+               case ir_relation_unordered_greater_equal:
+               case ir_relation_greater_equal: return ia32_cc_above_equal;
+               case ir_relation_unordered_less_greater:
+               case ir_relation_less_greater:  return ia32_cc_not_equal;
+               case ir_relation_less_equal_greater:
+               case ir_relation_unordered:
+               case ir_relation_false:
+               case ir_relation_true:
                        /* introduce jump always/jump never? */
                        break;
                }
@@ -2001,20 +2003,18 @@ static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
        return flags;
 }
 
-static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out)
+static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
 {
-       /* must have a Proj(Cmp) as input */
-       ir_node  *cmp  = get_Proj_pred(node);
-       int       pnc  = get_Proj_pn_cmp(node);
-       ir_node  *l    = get_Cmp_left(cmp);
-       ir_mode  *mode = get_irn_mode(l);
-       ir_node  *flags;
+       /* must have a Cmp as input */
+       ir_relation relation = get_Cmp_relation(cmp);
+       ir_node    *l        = get_Cmp_left(cmp);
+       ir_mode    *mode     = get_irn_mode(l);
+       ir_node    *flags;
 
        /* check for bit-test */
-       if (ia32_cg_config.use_bt
-                       && (pnc == pn_Cmp_Eq
-                           || (mode_is_signed(mode) && pnc == pn_Cmp_Lg)
-                               || (!mode_is_signed(mode) && (pnc & pn_Cmp_Ge) == pn_Cmp_Gt))) {
+       if (ia32_cg_config.use_bt && (relation == ir_relation_equal
+                       || (mode_is_signed(mode) && relation == ir_relation_less_greater)
+                       || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))) {
                ir_node *l = get_Cmp_left(cmp);
                ir_node *r = get_Cmp_right(cmp);
                if (is_And(l)) {
@@ -2032,7 +2032,7 @@ static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out)
                                        ir_node *n = get_Shl_right(la);
                                        flags    = gen_bt(cmp, ra, n);
                                        /* the bit is copied into the CF flag */
-                                       if (pnc & pn_Cmp_Eq)
+                                       if (relation & ir_relation_equal)
                                                *cc_out = ia32_cc_above_equal; /* test for CF=0 */
                                        else
                                                *cc_out = ia32_cc_below;       /* test for CF=1 */
@@ -2043,7 +2043,7 @@ static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out)
        }
 
        /* just do a normal transformation of the Cmp */
-       *cc_out = pnc_to_condition_code(pnc, mode);
+       *cc_out = relation_to_condition_code(relation, mode);
        flags   = be_transform_node(cmp);
        return flags;
 }
@@ -2056,7 +2056,7 @@ static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out)
  */
 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
 {
-       if (is_Proj(node) && is_Cmp(get_Proj_pred(node)))
+       if (is_Cmp(node))
                return get_flags_node_cmp(node, cc_out);
        assert(get_irn_mode(node) == mode_b);
        return get_flags_mode_b(node, cc_out);
@@ -2070,14 +2070,14 @@ static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
 static ir_node *gen_Load(ir_node *node)
 {
        ir_node  *old_block = get_nodes_block(node);
-       ir_node  *block   = be_transform_node(old_block);
-       ir_node  *ptr     = get_Load_ptr(node);
-       ir_node  *mem     = get_Load_mem(node);
-       ir_node  *new_mem = be_transform_node(mem);
+       ir_node  *block     = be_transform_node(old_block);
+       ir_node  *ptr       = get_Load_ptr(node);
+       ir_node  *mem       = get_Load_mem(node);
+       ir_node  *new_mem   = be_transform_node(mem);
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_mode  *mode      = get_Load_mode(node);
        ir_node  *base;
        ir_node  *index;
-       dbg_info *dbgi    = get_irn_dbg_info(node);
-       ir_mode  *mode    = get_Load_mode(node);
        ir_node  *new_node;
        ia32_address_t addr;
 
@@ -2847,25 +2847,6 @@ static ir_node *create_Ucomi(ir_node *node)
        return new_node;
 }
 
-/**
- * helper function: checks whether all Cmp projs are Lg or Eq which is needed
- * to fold an and into a test node
- */
-static bool can_fold_test_and(ir_node *node)
-{
-       const ir_edge_t *edge;
-
-       /** we can only have eq and lg projs */
-       foreach_out_edge(node, edge) {
-               ir_node *proj = get_edge_src_irn(edge);
-               pn_Cmp   pnc  = get_Proj_pn_cmp(proj);
-               if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
-                       return false;
-       }
-
-       return true;
-}
-
 /**
  * returns true if it is assured, that the upper bits of a node are "clean"
  * which means for a 16 or 8 bit value, that the upper bits in the register
@@ -2974,8 +2955,7 @@ static ir_node *gen_Cmp(ir_node *node)
        /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
        if (is_Const_0(right)          &&
            is_And(left)               &&
-           get_irn_n_edges(left) == 1 &&
-           can_fold_test_and(node)) {
+           get_irn_n_edges(left) == 1) {
                /* Test(and_left, and_right) */
                ir_node *and_left  = get_And_left(left);
                ir_node *and_right = get_And_right(left);
@@ -3115,12 +3095,12 @@ static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
 
        if (is_Proj(new_node)) {
                sub = get_Proj_pred(new_node);
-               assert(is_ia32_Sub(sub));
        } else {
                sub = new_node;
                set_irn_mode(sub, mode_T);
                new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
        }
+       assert(is_ia32_Sub(sub));
        eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
 
        dbgi = get_irn_dbg_info(psi);
@@ -3235,7 +3215,7 @@ static void find_const_transform(ia32_condition_code_t cc,
                t = f;
                f = tmp;
                cc = ia32_negate_condition_code(cc);
-       } else if (tarval_cmp(t, f) == pn_Cmp_Lt) {
+       } else if (tarval_cmp(t, f) == ir_relation_less) {
                // now, t is the bigger one
                ir_tarval *tmp = t;
                t = f;
@@ -3352,29 +3332,28 @@ static ir_node *gen_Mux(ir_node *node)
        ir_node              *new_block = be_transform_node(block);
        ir_node              *mux_true  = get_Mux_true(node);
        ir_node              *mux_false = get_Mux_false(node);
-       ir_node              *cond      = get_Mux_sel(node);
+       ir_node              *sel       = get_Mux_sel(node);
        ir_mode              *mode      = get_irn_mode(node);
        ir_node              *flags;
        ir_node              *new_node;
        int                   is_abs;
        ia32_condition_code_t cc;
 
-       assert(get_irn_mode(cond) == mode_b);
+       assert(get_irn_mode(sel) == mode_b);
 
-       is_abs = be_mux_is_abs(cond, mux_true, mux_false);
+       is_abs = be_mux_is_abs(sel, mux_true, mux_false);
        if (is_abs != 0) {
-               return create_abs(dbgi, block, be_get_abs_op(cond), is_abs < 0, node);
+               return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node);
        }
 
        /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
        if (mode_is_float(mode)) {
-               ir_node  *cmp         = get_Proj_pred(cond);
-               ir_node  *cmp_left    = get_Cmp_left(cmp);
-               ir_node  *cmp_right   = get_Cmp_right(cmp);
-               int       pnc         = get_Proj_proj(cond);
+               ir_node    *cmp_left  = get_Cmp_left(sel);
+               ir_node    *cmp_right = get_Cmp_right(sel);
+               ir_relation relation  = get_Cmp_relation(sel);
 
                if (ia32_cg_config.use_sse2) {
-                       if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
+                       if (relation == ir_relation_less || relation == ir_relation_less_equal) {
                                if (cmp_left == mux_true && cmp_right == mux_false) {
                                        /* Mux(a <= b, a, b) => MIN */
                                        return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
@@ -3384,7 +3363,7 @@ static ir_node *gen_Mux(ir_node *node)
                                        return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
                                         match_commutative | match_am | match_two_users);
                                }
-                       } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
+                       } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
                                if (cmp_left == mux_true && cmp_right == mux_false) {
                                        /* Mux(a >= b, a, b) => MAX */
                                        return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
@@ -3403,7 +3382,7 @@ static ir_node *gen_Mux(ir_node *node)
                        ir_mode             *new_mode;
                        unsigned            scale;
 
-                       flags    = get_flags_node(cond, &cc);
+                       flags    = get_flags_node(sel, &cc);
                        new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
 
                        if (ia32_cg_config.use_sse2) {
@@ -3474,37 +3453,34 @@ static ir_node *gen_Mux(ir_node *node)
        } else {
                assert(ia32_mode_needs_gp_reg(mode));
 
-               if (is_Proj(cond)) {
-                       ir_node *cmp = get_Proj_pred(cond);
-                       if (is_Cmp(cmp)) {
-                               ir_node  *cmp_left  = get_Cmp_left(cmp);
-                               ir_node  *cmp_right = get_Cmp_right(cmp);
-                               ir_node  *val_true  = mux_true;
-                               ir_node  *val_false = mux_false;
-                               int       pnc       = get_Proj_proj(cond);
-
-                               if (is_Const(val_true) && is_Const_null(val_true)) {
-                                       ir_node *tmp = val_false;
-                                       val_false = val_true;
-                                       val_true  = tmp;
-                                       pnc       = get_negated_pnc(pnc, get_irn_mode(cmp_left));
+               if (is_Cmp(sel)) {
+                       ir_node    *cmp_left  = get_Cmp_left(sel);
+                       ir_node    *cmp_right = get_Cmp_right(sel);
+                       ir_relation relation  = get_Cmp_relation(sel);
+                       ir_node    *val_true  = mux_true;
+                       ir_node    *val_false = mux_false;
+
+                       if (is_Const(val_true) && is_Const_null(val_true)) {
+                               ir_node *tmp = val_false;
+                               val_false = val_true;
+                               val_true  = tmp;
+                               relation  = get_negated_relation(relation);
+                       }
+                       if (is_Const_0(val_false) && is_Sub(val_true)) {
+                               if ((relation & ir_relation_greater)
+                                       && get_Sub_left(val_true) == cmp_left
+                                       && get_Sub_right(val_true) == cmp_right) {
+                                       return create_doz(node, cmp_left, cmp_right);
                                }
-                               if (is_Const_0(val_false) && is_Sub(val_true)) {
-                                       if ((pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge)
-                                               && get_Sub_left(val_true) == cmp_left
-                                               && get_Sub_right(val_true) == cmp_right) {
-                                               return create_doz(node, cmp_left, cmp_right);
-                                       }
-                                       if ((pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le)
-                                               && get_Sub_left(val_true) == cmp_right
-                                               && get_Sub_right(val_true) == cmp_left) {
-                                               return create_doz(node, cmp_right, cmp_left);
-                                       }
+                               if ((relation & ir_relation_less)
+                                       && get_Sub_left(val_true) == cmp_right
+                                       && get_Sub_right(val_true) == cmp_left) {
+                                       return create_doz(node, cmp_right, cmp_left);
                                }
                        }
                }
 
-               flags = get_flags_node(cond, &cc);
+               flags = get_flags_node(sel, &cc);
 
                if (is_Const(mux_true) && is_Const(mux_false)) {
                        /* both are const, good */
@@ -3561,7 +3537,7 @@ static ir_node *gen_Mux(ir_node *node)
                                }
                        }
                } else {
-                       new_node = create_CMov(node, cond, flags, cc);
+                       new_node = create_CMov(node, sel, flags, cc);
                }
                return new_node;
        }
index a953b04..ed89cfd 100644 (file)
@@ -343,9 +343,9 @@ static void rewrite_unsigned_float_Conv(ir_node *node)
                ir_node   *signed_x    = new_rd_Conv(dbgi, block, unsigned_x, mode_s);
                ir_node   *res         = new_rd_Conv(dbgi, block, signed_x, mode_d);
                ir_node   *zero        = new_r_Const(irg, get_mode_null(mode_s));
-               ir_node   *cmp         = new_rd_Cmp(dbgi, block, signed_x, zero);
-               ir_node   *proj_lt     = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
-               ir_node   *cond        = new_rd_Cond(dbgi, block, proj_lt);
+               ir_node   *cmp         = new_rd_Cmp(dbgi, block, signed_x, zero,
+                                                   ir_relation_less);
+               ir_node   *cond        = new_rd_Cond(dbgi, block, cmp);
                ir_node   *proj_true   = new_r_Proj(cond, mode_X, pn_Cond_true);
                ir_node   *proj_false  = new_r_Proj(cond, mode_X, pn_Cond_false);
                ir_node   *in_true[1]  = { proj_true };
index 3b0d59f..a59027e 100644 (file)
@@ -720,67 +720,65 @@ static void emit_sparc_FrameAddr(const ir_node *node)
        be_emit_finish_line_gas(node);
 }
 
-static const char *get_icc_unsigned(pn_Cmp pnc)
+static const char *get_icc_unsigned(ir_relation relation)
 {
-       switch (pnc) {
-       case pn_Cmp_False: return "bn";
-       case pn_Cmp_Eq:    return "be";
-       case pn_Cmp_Lt:    return "blu";
-       case pn_Cmp_Le:    return "bleu";
-       case pn_Cmp_Gt:    return "bgu";
-       case pn_Cmp_Ge:    return "bgeu";
-       case pn_Cmp_Lg:    return "bne";
-       case pn_Cmp_Leg:   return "ba";
-       default: panic("Cmp has unsupported pnc");
+       switch (relation & (ir_relation_less_equal_greater)) {
+       case ir_relation_false:              return "bn";
+       case ir_relation_equal:              return "be";
+       case ir_relation_less:               return "blu";
+       case ir_relation_less_equal:         return "bleu";
+       case ir_relation_greater:            return "bgu";
+       case ir_relation_greater_equal:      return "bgeu";
+       case ir_relation_less_greater:       return "bne";
+       case ir_relation_less_equal_greater: return "ba";
+       default: panic("Cmp has unsupported relation");
        }
 }
 
-static const char *get_icc_signed(pn_Cmp pnc)
+static const char *get_icc_signed(ir_relation relation)
 {
-       switch (pnc) {
-       case pn_Cmp_False: return "bn";
-       case pn_Cmp_Eq:    return "be";
-       case pn_Cmp_Lt:    return "bl";
-       case pn_Cmp_Le:    return "ble";
-       case pn_Cmp_Gt:    return "bg";
-       case pn_Cmp_Ge:    return "bge";
-       case pn_Cmp_Lg:    return "bne";
-       case pn_Cmp_Leg:   return "ba";
-       default: panic("Cmp has unsupported pnc");
+       switch (relation & (ir_relation_less_equal_greater)) {
+       case ir_relation_false:              return "bn";
+       case ir_relation_equal:              return "be";
+       case ir_relation_less:               return "bl";
+       case ir_relation_less_equal:         return "ble";
+       case ir_relation_greater:            return "bg";
+       case ir_relation_greater_equal:      return "bge";
+       case ir_relation_less_greater:       return "bne";
+       case ir_relation_less_equal_greater: return "ba";
+       default: panic("Cmp has unsupported relation");
        }
 }
 
-static const char *get_fcc(pn_Cmp pnc)
+static const char *get_fcc(ir_relation relation)
 {
-       switch (pnc) {
-       case pn_Cmp_False: return "fbn";
-       case pn_Cmp_Eq:    return "fbe";
-       case pn_Cmp_Lt:    return "fbl";
-       case pn_Cmp_Le:    return "fble";
-       case pn_Cmp_Gt:    return "fbg";
-       case pn_Cmp_Ge:    return "fbge";
-       case pn_Cmp_Lg:    return "fblg";
-       case pn_Cmp_Leg:   return "fbo";
-       case pn_Cmp_Uo:    return "fbu";
-       case pn_Cmp_Ue:    return "fbue";
-       case pn_Cmp_Ul:    return "fbul";
-       case pn_Cmp_Ule:   return "fbule";
-       case pn_Cmp_Ug:    return "fbug";
-       case pn_Cmp_Uge:   return "fbuge";
-       case pn_Cmp_Ne:    return "fbne";
-       case pn_Cmp_True:  return "fba";
-       case pn_Cmp_max:
-               break;
+       switch (relation) {
+       case ir_relation_false:                   return "fbn";
+       case ir_relation_equal:                   return "fbe";
+       case ir_relation_less:                    return "fbl";
+       case ir_relation_less_equal:              return "fble";
+       case ir_relation_greater:                 return "fbg";
+       case ir_relation_greater_equal:           return "fbge";
+       case ir_relation_less_greater:            return "fblg";
+       case ir_relation_less_equal_greater:      return "fbo";
+       case ir_relation_unordered:               return "fbu";
+       case ir_relation_unordered_equal:         return "fbue";
+       case ir_relation_unordered_less:          return "fbul";
+       case ir_relation_unordered_less_equal:    return "fbule";
+       case ir_relation_unordered_greater:       return "fbug";
+       case ir_relation_unordered_greater_equal: return "fbuge";
+       case ir_relation_unordered_less_greater:  return "fbne";
+       case ir_relation_true:                    return "fba";
        }
-       panic("invalid pnc");
+       panic("invalid relation");
 }
 
-typedef const char* (*get_cc_func)(pn_Cmp pnc);
+typedef const char* (*get_cc_func)(ir_relation relation);
 
 static void emit_sparc_branch(const ir_node *node, get_cc_func get_cc)
 {
        const sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr_const(node);
-       pn_Cmp           pnc         = attr->pnc;
+       ir_relation      relation    = attr->relation;
        const ir_node   *proj_true   = NULL;
        const ir_node   *proj_false  = NULL;
        const ir_edge_t *edge;
@@ -809,16 +807,12 @@ static void emit_sparc_branch(const ir_node *node, get_cc_func get_cc)
 
                proj_true  = proj_false;
                proj_false = t;
-               if (is_sparc_fbfcc(node)) {
-                       pnc = get_negated_pnc(pnc, mode_F);
-               } else {
-                       pnc = get_negated_pnc(pnc, mode_Iu);
-               }
+               relation   = get_negated_relation(relation);
        }
 
        /* emit the true proj */
        be_emit_cstring("\t");
-       be_emit_string(get_cc(pnc));
+       be_emit_string(get_cc(relation));
        be_emit_char(' ');
        sparc_emit_cfop_target(proj_true);
        be_emit_finish_line_gas(proj_true);
index b4564bc..7b9558d 100644 (file)
@@ -109,7 +109,8 @@ static void sparc_dump_node(FILE *F, ir_node *n, dump_reason_t reason)
                if (has_jmp_cond_attr(n)) {
                        const sparc_jmp_cond_attr_t *attr
                                = get_sparc_jmp_cond_attr_const(n);
-                       fprintf(F, "pnc: %d (%s)\n", attr->pnc, get_pnc_string(attr->pnc));
+                       fprintf(F, "relation: %d (%s)\n", attr->relation,
+                               get_relation_string(attr->relation));
                        fprintf(F, "unsigned: %s\n", attr->is_unsigned ? "true" : "false");
                }
                if (has_switch_jmp_attr(n)) {
@@ -141,10 +142,11 @@ static void sparc_set_attr_imm(ir_node *res, ir_entity *entity,
        attr->immediate_value        = immediate_value;
 }
 
-static void init_sparc_jmp_cond_attr(ir_node *node, pn_Cmp pnc, bool is_unsigned)
+static void init_sparc_jmp_cond_attr(ir_node *node, ir_relation relation,
+                                     bool is_unsigned)
 {
        sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr(node);
-       attr->pnc         = pnc;
+       attr->relation    = relation;
        attr->is_unsigned = is_unsigned;
 }
 
@@ -328,7 +330,7 @@ static int cmp_attr_sparc_jmp_cond(const ir_node *a, const ir_node *b)
        if (cmp_attr_sparc(a, b))
                return 1;
 
-       return attr_a->pnc != attr_b->pnc
+       return attr_a->relation != attr_b->relation
            || attr_a->is_unsigned != attr_b->is_unsigned;
 }
 
index 715a626..3753322 100644 (file)
@@ -79,7 +79,7 @@ struct sparc_load_store_attr_t {
 typedef struct sparc_jmp_cond_attr_t sparc_jmp_cond_attr_t;
 struct sparc_jmp_cond_attr_t {
        sparc_attr_t base;    /**< generic attribute */
-       pn_Cmp       pnc;
+       ir_relation  relation;
        bool         is_unsigned : 1;
 };
 
index 5af5451..8301db7 100644 (file)
@@ -373,8 +373,8 @@ Bicc => {
        state     => "pinned",
        mode      => "mode_T",
        attr_type => "sparc_jmp_cond_attr_t",
-       attr      => "pn_Cmp pnc, bool is_unsigned",
-       init_attr => "\tinit_sparc_jmp_cond_attr(res, pnc, is_unsigned);",
+       attr      => "ir_relation relation, bool is_unsigned",
+       init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, is_unsigned);",
        reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
 },
 
@@ -383,8 +383,8 @@ fbfcc => {
        state     => "pinned",
        mode      => "mode_T",
        attr_type => "sparc_jmp_cond_attr_t",
-       attr      => "pn_Cmp pnc",
-       init_attr => "\tinit_sparc_jmp_cond_attr(res, pnc, false);",
+       attr      => "ir_relation relation",
+       init_attr => "\tinit_sparc_jmp_cond_attr(res, relation, false);",
        reg_req   => { in => [ "fpflags" ], out => [ "none", "none" ] },
 },
 
index 5395ea2..6b6397d 100644 (file)
@@ -878,15 +878,11 @@ static ir_node *gen_Const(ir_node *node)
 
 static ir_mode *get_cmp_mode(ir_node *b_value)
 {
-       ir_node *pred;
        ir_node *op;
 
-       if (!is_Proj(b_value))
-               panic("can't determine cond signednes");
-       pred = get_Proj_pred(b_value);
-       if (!is_Cmp(pred))
+       if (!is_Cmp(b_value))
                panic("can't determine cond signednes (no cmp)");
-       op = get_Cmp_left(pred);
+       op = get_Cmp_left(b_value);
        return get_irn_mode(op);
 }
 
@@ -939,14 +935,14 @@ static ir_node *gen_SwitchJmp(ir_node *node)
 
 static ir_node *gen_Cond(ir_node *node)
 {
-       ir_node  *selector = get_Cond_selector(node);
-       ir_mode  *mode     = get_irn_mode(selector);
-       ir_mode  *cmp_mode;
-       ir_node  *block;
-       ir_node  *flag_node;
-       bool      is_unsigned;
-       pn_Cmp    pnc;
-       dbg_info *dbgi;
+       ir_node    *selector = get_Cond_selector(node);
+       ir_mode    *mode     = get_irn_mode(selector);
+       ir_mode    *cmp_mode;
+       ir_node    *block;
+       ir_node    *flag_node;
+       bool        is_unsigned;
+       ir_relation relation;
+       dbg_info   *dbgi;
 
        // switch/case jumps
        if (mode != mode_b) {
@@ -954,21 +950,20 @@ static ir_node *gen_Cond(ir_node *node)
        }
 
        // regular if/else jumps
-       assert(is_Proj(selector));
-       assert(is_Cmp(get_Proj_pred(selector)));
+       assert(is_Cmp(selector));
 
        cmp_mode = get_cmp_mode(selector);
 
        block       = be_transform_node(get_nodes_block(node));
        dbgi        = get_irn_dbg_info(node);
        flag_node   = be_transform_node(get_Proj_pred(selector));
-       pnc         = get_Proj_pn_cmp(selector);
+       relation    = get_Cmp_relation(selector);
        is_unsigned = !mode_is_signed(cmp_mode);
        if (mode_is_float(cmp_mode)) {
                assert(!is_unsigned);
-               return new_bd_sparc_fbfcc(dbgi, block, flag_node, pnc);
+               return new_bd_sparc_fbfcc(dbgi, block, flag_node, relation);
        } else {
-               return new_bd_sparc_Bicc(dbgi, block, flag_node, pnc, is_unsigned);
+               return new_bd_sparc_Bicc(dbgi, block, flag_node, relation, is_unsigned);
        }
 }
 
index 27e70ff..4b1ab62 100644 (file)
@@ -674,7 +674,7 @@ static struct ms magic(ir_tarval *d)
        int bits        = get_mode_size_bits(u_mode);
        int p;
        ir_tarval *ad, *anc, *delta, *q1, *r1, *q2, *r2, *t;     /* unsigned */
-       pn_Cmp d_cmp, M_cmp;
+       ir_relation d_cmp, M_cmp;
 
        ir_tarval *bits_minus_1, *two_bits_1;
 
@@ -703,7 +703,7 @@ static struct ms magic(ir_tarval *d)
                q1 = ADD(q1, q1);                           /* Update q1 = 2^p/|nc| */
                r1 = ADD(r1, r1);                           /* Update r1 = rem(2^p, |nc|) */
 
-               if (CMP(r1, anc) & pn_Cmp_Ge) {
+               if (CMP(r1, anc) & ir_relation_greater_equal) {
                        q1 = ADD(q1, ONE(u_mode));
                        r1 = SUB(r1, anc);
                }
@@ -711,17 +711,17 @@ static struct ms magic(ir_tarval *d)
                q2 = ADD(q2, q2);                           /* Update q2 = 2^p/|d| */
                r2 = ADD(r2, r2);                           /* Update r2 = rem(2^p, |d|) */
 
-               if (CMP(r2, ad) & pn_Cmp_Ge) {
+               if (CMP(r2, ad) & ir_relation_greater_equal) {
                        q2 = ADD(q2, ONE(u_mode));
                        r2 = SUB(r2, ad);
                }
 
                delta = SUB(ad, r2);
-       } while (CMP(q1, delta) & pn_Cmp_Lt || (CMP(q1, delta) & pn_Cmp_Eq && CMP(r1, ZERO(u_mode)) & pn_Cmp_Eq));
+       } while (CMP(q1, delta) & ir_relation_less || (CMP(q1, delta) & ir_relation_equal && CMP(r1, ZERO(u_mode)) & ir_relation_equal));
 
        d_cmp = CMP(d, ZERO(mode));
 
-       if (d_cmp & pn_Cmp_Ge)
+       if (d_cmp & ir_relation_greater_equal)
                mag.M = ADD(CNV(q2, mode), ONE(mode));
        else
                mag.M = SUB(ZERO(mode), ADD(CNV(q2, mode), ONE(mode)));
@@ -731,10 +731,10 @@ static struct ms magic(ir_tarval *d)
        mag.s = p - bits;
 
        /* need an add if d > 0 && M < 0 */
-       mag.need_add = d_cmp & pn_Cmp_Gt && M_cmp & pn_Cmp_Lt;
+       mag.need_add = d_cmp & ir_relation_greater && M_cmp & ir_relation_less;
 
        /* need a sub if d < 0 && M > 0 */
-       mag.need_sub = d_cmp & pn_Cmp_Lt && M_cmp & pn_Cmp_Gt;
+       mag.need_sub = d_cmp & ir_relation_less && M_cmp & ir_relation_greater;
 
        tarval_set_integer_overflow_mode(rem);
 
@@ -782,7 +782,7 @@ static struct mu magicu(ir_tarval *d)
 
        do {
                ++p;
-               if (CMP(r1, SUB(nc, r1)) & pn_Cmp_Ge) {
+               if (CMP(r1, SUB(nc, r1)) & ir_relation_greater_equal) {
                        q1 = ADD(ADD(q1, q1), ONE(mode));
                        r1 = SUB(ADD(r1, r1), nc);
                }
@@ -791,15 +791,15 @@ static struct mu magicu(ir_tarval *d)
                        r1 = ADD(r1, r1);
                }
 
-               if (CMP(ADD(r2, ONE(mode)), SUB(d, r2)) & pn_Cmp_Ge) {
-                       if (CMP(q2, seven_ff) & pn_Cmp_Ge)
+               if (CMP(ADD(r2, ONE(mode)), SUB(d, r2)) & ir_relation_greater_equal) {
+                       if (CMP(q2, seven_ff) & ir_relation_greater_equal)
                                magu.need_add = 1;
 
                        q2 = ADD(ADD(q2, q2), ONE(mode));
                        r2 = SUB(ADD(ADD(r2, r2), ONE(mode)), d);
                }
                else {
-                       if (CMP(q2, two_bits_1) & pn_Cmp_Ge)
+                       if (CMP(q2, two_bits_1) & ir_relation_greater_equal)
                                magu.need_add = 1;
 
                        q2 = ADD(q2, q2);
@@ -807,7 +807,7 @@ static struct mu magicu(ir_tarval *d)
                }
                delta = SUB(SUB(d, ONE(mode)), r2);
        } while (p < 2*bits &&
-               (CMP(q1, delta) & pn_Cmp_Lt || (CMP(q1, delta) & pn_Cmp_Eq && CMP(r1, ZERO(mode)) & pn_Cmp_Eq)));
+               (CMP(q1, delta) & ir_relation_less || (CMP(q1, delta) & ir_relation_equal && CMP(r1, ZERO(mode)) & ir_relation_equal)));
 
        magu.M = ADD(q2, ONE(mode));                       /* Magic number */
        magu.s = p - bits;                                 /* and shift amount */
index 17b320a..5af12d1 100644 (file)
@@ -189,6 +189,9 @@ static int firm_emit(lc_appendable_t *app,
                        } else if (is_Sel(node)) {
                                snprintf(buf, sizeof(buf), "%s%s %s[%s]", A("irn"), get_irn_opname(node),
                                get_mode_name(get_irn_mode(node)), get_entity_name(get_Sel_entity(node)));
+                       } else if (is_Cmp(node)) {
+                               ir_relation relation = get_Cmp_relation(node);
+                               snprintf(buf, sizeof(buf), "%s%s %s", A("irn"), get_irn_opname(node), get_relation_string(relation));
                        } else {
                                snprintf(buf, sizeof(buf), "%s%s %s", A("irn"), get_irn_opname(node),
                                get_mode_name(get_irn_mode(node)));
@@ -290,7 +293,7 @@ static int firm_emit_pnc(lc_appendable_t *app,
     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
 {
        int value = arg->v_int;
-       const char *p = get_pnc_string(value);
+       const char *p = get_relation_string(value);
 
        return lc_arg_append(app, occ, p, strlen(p));
 }
index ef5c910..63e3d64 100644 (file)
@@ -962,9 +962,7 @@ static void dump_node_nodeattr(FILE *F, ir_node *n)
                proj_nr = get_Proj_proj(n);
                code    = get_irn_opcode(pred);
 
-               if (code == iro_Cmp)
-                       fprintf(F, "%s ", get_pnc_string(get_Proj_proj(n)));
-               else if (code == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start)
+               if (code == iro_Proj && get_irn_opcode(get_Proj_pred(pred)) == iro_Start)
                        fprintf(F, "Arg %ld ", proj_nr);
                else if (code == iro_Cond && get_irn_mode(get_Cond_selector(pred)) != mode_b)
                        fprintf(F, "%ld ", proj_nr);
@@ -999,8 +997,11 @@ static void dump_node_nodeattr(FILE *F, ir_node *n)
        case iro_Cast:
                ir_fprintf(F, "(%+F)", get_Cast_type(n));
                break;
+       case iro_Cmp:
+               fprintf(F, "%s ", get_relation_string(get_Cmp_relation(n)));
+               break;
        case iro_Confirm:
-               fprintf(F, "%s ", get_pnc_string(get_Confirm_cmp(n)));
+               fprintf(F, "%s ", get_relation_string(get_Confirm_relation(n)));
                break;
        case iro_CopyB:
                ir_fprintf(F, "(%+F)", get_CopyB_type(n));
index 093daea..2c64e6a 100644 (file)
@@ -202,6 +202,10 @@ void dump_irnode_to_file(FILE *F, ir_node *n)
        case iro_Cast: {
                ir_fprintf(F, "  cast to type: %+F\n", get_Cast_type(n));
        } break;
+       case iro_Cmp: {
+               ir_relation relation = get_Cmp_relation(n);
+               ir_fprintf(F, "  relation: %s\n", get_relation_string(relation));
+       } break;
        case iro_Return: {
                size_t   i;
                ir_type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
@@ -254,7 +258,7 @@ void dump_irnode_to_file(FILE *F, ir_node *n)
                fprintf(F, "  align: %s\n", get_align_name(get_Store_align(n)));
                break;
        case iro_Confirm:
-               fprintf(F, "  compare operation: %s\n", get_pnc_string(get_Confirm_cmp(n)));
+               fprintf(F, "  compare operation: %s\n", get_relation_string(get_Confirm_relation(n)));
                break;
        case iro_ASM: {
                const ir_asm_constraint *cons;
index 707b050..a8e9ed5 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "irhooks.h"
 #include "irtools.h"
+#include "util.h"
 
 #include "beinfo.h"
 
 #define RETURN_RESULT_OFFSET  1  /* mem is not a result */
 #define END_KEEPALIVE_OFFSET  0
 
-static const char *pnc_name_arr [] = {
-       "pn_Cmp_False", "pn_Cmp_Eq", "pn_Cmp_Lt", "pn_Cmp_Le",
-       "pn_Cmp_Gt", "pn_Cmp_Ge", "pn_Cmp_Lg", "pn_Cmp_Leg",
-       "pn_Cmp_Uo", "pn_Cmp_Ue", "pn_Cmp_Ul", "pn_Cmp_Ule",
-       "pn_Cmp_Ug", "pn_Cmp_Uge", "pn_Cmp_Ne", "pn_Cmp_True"
+static const char *relation_names [] = {
+       "false",
+       "equal",
+       "less",
+       "less_equal",
+       "greater",
+       "greater_equal",
+       "less_greater",
+       "less_equal_greater",
+       "unordered",
+       "unordered_equal",
+       "unordered_less",
+       "unordered_less_equal",
+       "unordered_greater",
+       "unordered_greater_equal",
+       "not_equal",
+       "true"
 };
 
-/**
- * returns the pnc name from an pnc constant
- */
-const char *get_pnc_string(int pnc)
+const char *get_relation_string(ir_relation relation)
 {
-       assert(pnc >= 0 && pnc <
-                       (int) (sizeof(pnc_name_arr)/sizeof(pnc_name_arr[0])));
-       return pnc_name_arr[pnc];
+       assert(relation < (ir_relation)ARRAY_SIZE(relation_names));
+       return relation_names[relation];
 }
 
-/*
- * Calculates the negated (Complement(R)) pnc condition.
- */
-pn_Cmp get_negated_pnc(long pnc, ir_mode *mode)
+ir_relation get_negated_relation(ir_relation relation)
 {
-       pnc ^= pn_Cmp_True;
-
-       /* do NOT add the Uo bit for non-floating point values */
-       if (! mode_is_float(mode))
-               pnc &= ~pn_Cmp_Uo;
-
-       return (pn_Cmp) pnc;
+       return relation ^ ir_relation_true;
 }
 
-/* Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
-pn_Cmp get_inversed_pnc(long pnc)
+ir_relation get_inversed_relation(ir_relation relation)
 {
-       long code    = pnc & ~(pn_Cmp_Lt|pn_Cmp_Gt);
-       long lesser  = pnc & pn_Cmp_Lt;
-       long greater = pnc & pn_Cmp_Gt;
-
-       code |= (lesser ? pn_Cmp_Gt : 0) | (greater ? pn_Cmp_Lt : 0);
-
-       return (pn_Cmp) code;
+       ir_relation code    = relation & ~(ir_relation_less|ir_relation_greater);
+       bool        less    = relation & ir_relation_less;
+       bool        greater = relation & ir_relation_greater;
+       code |= (less ? ir_relation_greater : 0) | (greater ? ir_relation_less : 0);
+       return code;
 }
 
 /**
@@ -1357,11 +1354,6 @@ int (is_arg_Proj)(const ir_node *node)
        return _is_arg_Proj(node);
 }
 
-pn_Cmp (get_Proj_pn_cmp)(const ir_node *node)
-{
-       return _get_Proj_pn_cmp(node);
-}
-
 ir_node **get_Tuple_preds_arr(ir_node *node)
 {
        assert(is_Tuple(node));
index 7ea1c25..aa70bbd 100644 (file)
@@ -604,12 +604,6 @@ static inline int _is_arg_Proj(const ir_node *node)
        return pn_Start_T_args == get_Proj_proj(node) && is_Start(get_Proj_pred(node));
 }
 
-static inline pn_Cmp _get_Proj_pn_cmp(const ir_node *node)
-{
-       assert(is_Cmp(get_Proj_pred(node)));
-       return (pn_Cmp)get_Proj_proj(node);
-}
-
 /** initialize ir_node module */
 void init_irnode(void);
 
@@ -693,6 +687,4 @@ void init_irnode(void);
 
 #define is_arg_Proj(node)                     _is_arg_Proj(node)
 
-#define get_Proj_pn_cmp(node)                 _get_Proj_pn_cmp(node)
-
 #endif
index a7b75d5..ad66fb4 100644 (file)
@@ -197,7 +197,7 @@ static ir_tarval *computed_value_Borrow(const ir_node *n)
        ir_tarval *tb = value_of(b);
 
        if ((ta != tarval_bad) && (tb != tarval_bad)) {
-               return tarval_cmp(ta, tb) == pn_Cmp_Lt ? get_mode_one(m) : get_mode_null(m);
+               return tarval_cmp(ta, tb) == ir_relation_less ? get_mode_one(m) : get_mode_null(m);
        } else if (tarval_is_null(ta)) {
                return get_mode_null(m);
        }
@@ -435,7 +435,7 @@ static ir_tarval *computed_value_Mux(const ir_node *n)
  */
 static ir_tarval *computed_value_Confirm(const ir_node *n)
 {
-       if (get_Confirm_cmp(n) == pn_Cmp_Eq) {
+       if (get_Confirm_relation(n) == ir_relation_equal) {
                ir_tarval *tv = value_of(get_Confirm_bound(n));
                if (tv != tarval_bad)
                        return tv;
@@ -444,104 +444,72 @@ static ir_tarval *computed_value_Confirm(const ir_node *n)
 }  /* computed_value_Confirm */
 
 /**
- * Return the value of a Proj(Cmp).
- *
- * This performs a first step of unreachable code elimination.
- * Proj can not be computed, but folding a Cmp above the Proj here is
- * not as wasteful as folding a Cmp into a Tuple of 16 Consts of which
- * only 1 is used.
- * There are several case where we can evaluate a Cmp node, see later.
+ * gives a (conservative) estimation of possible relation when comparing
+ * left+right
  */
-static ir_tarval *computed_value_Proj_Cmp(const ir_node *n)
+static ir_relation determine_possible_cmp_relations(const ir_node *left,
+                                                    const ir_node *right)
 {
-       ir_node *cmp    = get_Proj_pred(n);
-       ir_node *left   = get_Cmp_left(cmp);
-       ir_node *right  = get_Cmp_right(cmp);
-       pn_Cmp   pn_cmp = get_Proj_pn_cmp(n);
-       ir_mode *mode   = get_irn_mode(left);
-       ir_tarval *tv_l, *tv_r;
-
-       /*
-        * BEWARE: a == a is NOT always True for floating Point values, as
-        * NaN != NaN is defined, so we must check this here.
-        */
-       if (left == right && (!mode_is_float(mode) || pn_cmp == pn_Cmp_Lt ||  pn_cmp == pn_Cmp_Gt)) {
-               /* This is a trick with the bits used for encoding the Cmp
-                  Proj numbers, the following statement is not the same:
-               return new_tarval_from_long(pn_cmp == pn_Cmp_Eq, mode_b) */
-               return new_tarval_from_long(pn_cmp & pn_Cmp_Eq, mode_b);
-       }
-       tv_l = value_of(left);
-       tv_r = value_of(right);
+       ir_relation possible = ir_relation_true;
+       ir_tarval  *tv_l     = value_of(left);
+       ir_tarval  *tv_r     = value_of(right);
+       ir_mode    *mode     = get_irn_mode(left);
+       ir_tarval  *min      = mode == mode_b ? tarval_b_false : get_mode_min(mode);
+       ir_tarval  *max      = mode == mode_b ? tarval_b_true  : get_mode_max(mode);
 
+       /* both values known - evaluate them */
        if ((tv_l != tarval_bad) && (tv_r != tarval_bad)) {
-               /*
-                * The predecessors of Cmp are target values.  We can evaluate
-                * the Cmp.
-                */
-               pn_Cmp flags = tarval_cmp(tv_l, tv_r);
-               if (flags != pn_Cmp_False) {
-                       return new_tarval_from_long (pn_cmp & flags, mode_b);
-               }
-       } else if (mode_is_int(mode)) {
-               /* for integer values, we can check against MIN/MAX */
-               pn_Cmp cmp_result;
-
-               if (tv_l == get_mode_min(mode)) {
-                       /* MIN <=/> x.  This results in true/false. */
-                       if (pn_cmp == pn_Cmp_Le)
-                               return tarval_b_true;
-                       else if (pn_cmp == pn_Cmp_Gt)
-                               return tarval_b_false;
-               } else if (tv_r == get_mode_min(mode)) {
-                       /* x >=/< MIN.  This results in true/false. */
-                       if (pn_cmp == pn_Cmp_Ge)
-                               return tarval_b_true;
-                       else if (pn_cmp == pn_Cmp_Lt)
-                               return tarval_b_false;
-               } else if (tv_l == get_mode_max(mode)) {
-                       /* MAX >=/< x.  This results in true/false. */
-                       if (pn_cmp == pn_Cmp_Ge)
-                               return tarval_b_true;
-                       else if (pn_cmp == pn_Cmp_Lt)
-                               return tarval_b_false;
-               } else if (tv_r == get_mode_max(mode)) {
-                       /* x <=/> MAX.  This results in true/false. */
-                       if (pn_cmp == pn_Cmp_Le)
-                               return tarval_b_true;
-                       else if (pn_cmp == pn_Cmp_Gt)
-                               return tarval_b_false;
-               }
-
-               cmp_result = vrp_cmp(left, right);
-               if (cmp_result != pn_Cmp_False) {
-                       if (cmp_result == pn_Cmp_Lg) {
-                               if (pn_cmp == pn_Cmp_Eq) {
-                                       return tarval_b_false;
-                               } else if (pn_cmp == pn_Cmp_Lg) {
-                                       return tarval_b_true;
-                               }
-                       } else {
-                               return new_tarval_from_long(cmp_result & pn_cmp, mode_b);
-                       }
-               }
-       } else if (mode_is_reference(mode)) {
-               /* pointer compare */
-               ir_node *s_l = skip_Proj(left);
-               ir_node *s_r = skip_Proj(right);
+               possible = tarval_cmp(tv_l, tv_r);
+               /* we can return now, won't get any better */
+               return possible;
+       }
+       /* a == a is never less or greater (but might be equal or unordered) */
+       if (left == right)
+               possible &= ~ir_relation_less_greater;
+       /* unordered results only happen for float compares */
+       if (!mode_is_float(mode))
+               possible &= ~ir_relation_unordered;
+       /* values can never be less than the least representable number or
+        * greater than the greatest representable number */
+       if (tv_l == min)
+               possible &= ~ir_relation_greater;
+       if (tv_l == max)
+               possible &= ~ir_relation_less;
+       if (tv_r == max)
+               possible &= ~ir_relation_greater;
+       if (tv_r == min)
+               possible &= ~ir_relation_less;
+       /* maybe vrp can tell us more */
+       possible &= vrp_cmp(left, right);
+       /* Alloc nodes never return null (but throw an exception) */
+       if (is_Alloc(left) && tarval_is_null(tv_r))
+               possible &= ~ir_relation_equal;
+
+       return possible;
+}
 
-               if ((is_Alloc(s_l) && tarval_is_null(tv_r)) ||
-                       (tarval_is_null(tv_l) && is_Alloc(s_r))) {
-                       /*
-                        * The predecessors are Allocs and (void*)(0) constants. In Firm Allocs never
-                        * return NULL, they raise an exception. Therefore we can predict
-                        * the Cmp result.
-                        */
-                       return new_tarval_from_long(pn_cmp & pn_Cmp_Lg, mode_b);
-               }
-       }
-       return computed_value_Cmp_Confirm(cmp, left, right, pn_cmp);
-}  /* computed_value_Proj_Cmp */
+/**
+ * Return the value of a Cmp.
+ *
+ * The basic idea here is to determine which relations are possible and which
+ * one are definitely impossible.
+ */
+static ir_tarval *computed_value_Cmp(const ir_node *cmp)
+{
+       ir_node    *left     = get_Cmp_left(cmp);
+       ir_node    *right    = get_Cmp_right(cmp);
+       ir_relation possible = determine_possible_cmp_relations(left, right);
+       ir_relation relation = get_Cmp_relation(cmp);
+
+       /* if none of the requested relations is possible, return false */
+       if ((possible & relation) == ir_relation_false)
+               return tarval_b_false;
+       /* if possible relations are a subset of the requested ones return true */
+       if ((possible & ~relation) == ir_relation_false)
+               return tarval_b_true;
+
+       return computed_value_Cmp_Confirm(cmp, left, right, relation);
+}
 
 /**
  * Calculate the value of an integer Div.
@@ -631,7 +599,7 @@ static ir_tarval *computed_value_Proj(const ir_node *proj)
 ir_tarval *computed_value(const ir_node *n)
 {
        vrp_attr *vrp = vrp_get_info(n);
-       if (vrp && vrp->valid && tarval_cmp(vrp->bits_set, vrp->bits_not_set) == pn_Cmp_Eq) {
+       if (vrp && vrp->valid && tarval_cmp(vrp->bits_set, vrp->bits_not_set) == ir_relation_equal) {
                return vrp->bits_set;
        }
        if (n->op->ops.computed_value)
@@ -660,29 +628,29 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops
                break
 
        switch (code) {
-       CASE(Const);
-       CASE(SymConst);
        CASE(Add);
-       CASE(Sub);
-       CASE(Carry);
+       CASE(And);
        CASE(Borrow);
+       CASE(Carry);
+       CASE(Cmp);
+       CASE(Confirm);
+       CASE(Const);
+       CASE(Conv);
+       CASE(Eor);
        CASE(Minus);
        CASE(Mul);
-       CASE(And);
-       CASE(Or);
-       CASE(Eor);
+       CASE(Mux);
        CASE(Not);
+       CASE(Or);
+       CASE(Proj);
+       CASE(Rotl);
        CASE(Shl);
        CASE(Shr);
        CASE(Shrs);
-       CASE(Rotl);
-       CASE(Conv);
-       CASE(Mux);
-       CASE(Confirm);
-       CASE_PROJ(Cmp);
+       CASE(Sub);
+       CASE(SymConst);
        CASE_PROJ(Div);
        CASE_PROJ(Mod);
-       CASE(Proj);
        default:
                /* leave NULL */
                break;
@@ -1701,65 +1669,65 @@ static ir_node *equivalent_node_Mux(ir_node *n)
                DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_EQ);
                return n;
        }
-       if (is_Proj(sel) && !mode_honor_signed_zeros(get_irn_mode(n))) {
-               ir_node *cmp = get_Proj_pred(sel);
-               long proj_nr = get_Proj_proj(sel);
-               ir_node *f   = get_Mux_false(n);
-               ir_node *t   = get_Mux_true(n);
+       if (is_Cmp(sel) && !mode_honor_signed_zeros(get_irn_mode(n))) {
+               ir_relation relation = get_Cmp_relation(sel);
+               ir_node    *f        = get_Mux_false(n);
+               ir_node    *t        = get_Mux_true(n);
 
                /*
                 * Note further that these optimization work even for floating point
                 * with NaN's because -NaN == NaN.
                 * However, if +0 and -0 is handled differently, we cannot use the first one.
                 */
-               if (is_Cmp(cmp)) {
-                       ir_node *const cmp_l = get_Cmp_left(cmp);
-                       ir_node *const cmp_r = get_Cmp_right(cmp);
-
-                       switch (proj_nr) {
-                               case pn_Cmp_Eq:
-                                       if ((cmp_l == t && cmp_r == f) || /* Mux(t == f, t, f) -> f */
-                                                       (cmp_l == f && cmp_r == t)) { /* Mux(f == t, t, f) -> f */
-                                               n = f;
-                                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
-                                               return n;
-                                       }
-                                       break;
+               ir_node *const cmp_l = get_Cmp_left(sel);
+               ir_node *const cmp_r = get_Cmp_right(sel);
+
+               switch (relation) {
+               case ir_relation_equal:
+                       if ((cmp_l == t && cmp_r == f) || /* Mux(t == f, t, f) -> f */
+                                       (cmp_l == f && cmp_r == t)) { /* Mux(f == t, t, f) -> f */
+                               n = f;
+                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
+                               return n;
+                       }
+                       break;
 
-                               case pn_Cmp_Lg:
-                               case pn_Cmp_Ne:
-                                       if ((cmp_l == t && cmp_r == f) || /* Mux(t != f, t, f) -> t */
-                                                       (cmp_l == f && cmp_r == t)) { /* Mux(f != t, t, f) -> t */
-                                               n = t;
-                                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
-                                               return n;
-                                       }
-                                       break;
+               case ir_relation_less_greater:
+               case ir_relation_unordered_less_greater:
+                       if ((cmp_l == t && cmp_r == f) || /* Mux(t != f, t, f) -> t */
+                                       (cmp_l == f && cmp_r == t)) { /* Mux(f != t, t, f) -> t */
+                               n = t;
+                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
+                               return n;
                        }
+                       break;
+               default:
+                       break;
+               }
 
-                       /*
-                        * Note: normalization puts the constant on the right side,
-                        * so we check only one case.
-                        */
-                       if (cmp_l == t && tarval_is_null(value_of(cmp_r))) {
-                               /* Mux(t CMP 0, X, t) */
-                               if (is_Minus(f) && get_Minus_op(f) == t) {
-                                       /* Mux(t CMP 0, -t, t) */
-                                       if (proj_nr == pn_Cmp_Eq) {
-                                               /* Mux(t == 0, -t, t)  ==>  -t */
-                                               n = f;
-                                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
-                                       } else if (proj_nr == pn_Cmp_Lg || proj_nr == pn_Cmp_Ne) {
-                                               /* Mux(t != 0, -t, t)  ==> t */
-                                               n = t;
-                                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
-                                       }
+               /*
+                * Note: normalization puts the constant on the right side,
+                * so we check only one case.
+                */
+               if (cmp_l == t && tarval_is_null(value_of(cmp_r))) {
+                       /* Mux(t CMP 0, X, t) */
+                       if (is_Minus(f) && get_Minus_op(f) == t) {
+                               /* Mux(t CMP 0, -t, t) */
+                               if (relation == ir_relation_equal) {
+                                       /* Mux(t == 0, -t, t)  ==>  -t */
+                                       n = f;
+                                       DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
+                               } else if (relation == ir_relation_less_greater || relation == ir_relation_unordered_less_greater) {
+                                       /* Mux(t != 0, -t, t)  ==> t */
+                                       n = t;
+                                       DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
                                }
                        }
                }
        }
+
        return n;
-}  /* equivalent_node_Mux */
+}
 
 /**
  * Remove Confirm nodes if setting is on.
@@ -1767,17 +1735,16 @@ static ir_node *equivalent_node_Mux(ir_node *n)
  */
 static ir_node *equivalent_node_Confirm(ir_node *n)
 {
-       ir_node *pred = get_Confirm_value(n);
-       pn_Cmp  pnc   = get_Confirm_cmp(n);
+       ir_node    *pred     = get_Confirm_value(n);
+       ir_relation relation = get_Confirm_relation(n);
 
-       while (is_Confirm(pred) && pnc == get_Confirm_cmp(pred)) {
+       while (is_Confirm(pred) && relation == get_Confirm_relation(pred)) {
                /*
                 * rare case: two identical Confirms one after another,
                 * replace the second one with the first.
                 */
                n    = pred;
                pred = get_Confirm_value(n);
-               pnc  = get_Confirm_cmp(n);
        }
        return n;
 }
@@ -2990,32 +2957,6 @@ make_tuple:
        return n;
 }  /* transform_node_Mod */
 
-/**
- * Optimize -a CMP -b into b CMP a.
- * This works only for for modes where unary Minus
- * cannot Overflow.
- * Note that two-complement integers can Overflow
- * so it will NOT work.
- *
- * For == and != can be handled in Proj(Cmp)
- */
-static ir_node *transform_node_Cmp(ir_node *n)
-{
-       ir_node *oldn = n;
-       ir_node *left  = get_Cmp_left(n);
-       ir_node *right = get_Cmp_right(n);
-
-       if (is_Minus(left) && is_Minus(right) &&
-               !mode_overflow_on_unary_Minus(get_irn_mode(left))) {
-               ir_node *const new_left  = get_Minus_op(right);
-               ir_node *const new_right = get_Minus_op(left);
-               n = new_rd_Cmp(get_irn_dbg_info(n), get_nodes_block(n), new_left, new_right);
-               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CMP_OP_OP);
-       }
-       return n;
-}  /* transform_node_Cmp */
-
-
 /**
  * Transform a Cond node.
  *
@@ -3177,23 +3118,25 @@ static ir_node *transform_node_And(ir_node *n)
        ir_mode *mode;
        vrp_attr *a_vrp, *b_vrp;
 
+       /* we can combine the relations of two compares with the same operands */
+       if (is_Cmp(a) && is_Cmp(b)) {
+               ir_node *a_left  = get_Cmp_left(a);
+               ir_node *a_right = get_Cmp_left(a);
+               ir_node *b_left  = get_Cmp_left(b);
+               ir_node *b_right = get_Cmp_right(b);
+               if (a_left == b_left && b_left == b_right) {
+                       dbg_info   *dbgi         = get_irn_dbg_info(n);
+                       ir_node    *block        = get_nodes_block(n);
+                       ir_relation a_relation   = get_Cmp_relation(a);
+                       ir_relation b_relation   = get_Cmp_relation(b);
+                       ir_relation new_relation = a_relation & b_relation;
+                       return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
+               }
+       }
+
        mode = get_irn_mode(n);
        HANDLE_BINOP_PHI((eval_func) tarval_and, a, b, c, mode);
 
-       /* we can evaluate 2 Projs of the same Cmp */
-       if (mode == mode_b && is_Proj(a) && is_Proj(b)) {
-               ir_node *pred_a = get_Proj_pred(a);
-               ir_node *pred_b = get_Proj_pred(b);
-               if (pred_a == pred_b) {
-                       dbg_info *dbgi  = get_irn_dbg_info(n);
-                       pn_Cmp pn_a     = get_Proj_pn_cmp(a);
-                       pn_Cmp pn_b     = get_Proj_pn_cmp(b);
-                       /* yes, we can simply calculate with pncs */
-                       pn_Cmp new_pnc  = pn_a & pn_b;
-
-                       return new_rd_Proj(dbgi, pred_a, mode_b, new_pnc);
-               }
-       }
        if (is_Or(a)) {
                if (is_Not(b)) {
                        ir_node *op = get_Not_op(b);
@@ -3297,7 +3240,7 @@ static ir_node *transform_node_And(ir_node *n)
 
        b_vrp = vrp_get_info(b);
        if (is_Const(a) && b_vrp && (tarval_cmp(tarval_or(get_Const_tarval(a),
-                                               b_vrp->bits_not_set), get_Const_tarval(a)) == pn_Cmp_Eq)) {
+                                               b_vrp->bits_not_set), get_Const_tarval(a)) == ir_relation_equal)) {
 
                return b;
 
@@ -3305,7 +3248,7 @@ static ir_node *transform_node_And(ir_node *n)
 
        a_vrp = vrp_get_info(a);
        if (is_Const(b) && a_vrp && (tarval_cmp(tarval_or(get_Const_tarval(b),
-                                               a_vrp->bits_not_set), get_Const_tarval(b)) == pn_Cmp_Eq)) {
+                                               a_vrp->bits_not_set), get_Const_tarval(b)) == ir_relation_equal)) {
                return a;
        }
 
@@ -3351,23 +3294,24 @@ static ir_node *transform_node_Eor(ir_node *n)
        ir_node *b = get_Eor_right(n);
        ir_mode *mode = get_irn_mode(n);
 
-       HANDLE_BINOP_PHI((eval_func) tarval_eor, a, b, c, mode);
-
-       /* we can evaluate 2 Projs of the same Cmp */
-       if (mode == mode_b && is_Proj(a) && is_Proj(b)) {
-               ir_node *pred_a = get_Proj_pred(a);
-               ir_node *pred_b = get_Proj_pred(b);
-               if (pred_a == pred_b) {
-                       dbg_info *dbgi  = get_irn_dbg_info(n);
-                       pn_Cmp pn_a     = get_Proj_pn_cmp(a);
-                       pn_Cmp pn_b     = get_Proj_pn_cmp(b);
-                       /* yes, we can simply calculate with pncs */
-                       pn_Cmp new_pnc  = pn_a ^ pn_b;
-
-                       return new_rd_Proj(dbgi, pred_a, mode_b, new_pnc);
+       /* we can combine the relations of two compares with the same operands */
+       if (is_Cmp(a) && is_Cmp(b)) {
+               ir_node *a_left  = get_Cmp_left(a);
+               ir_node *a_right = get_Cmp_left(a);
+               ir_node *b_left  = get_Cmp_left(b);
+               ir_node *b_right = get_Cmp_right(b);
+               if (a_left == b_left && b_left == b_right) {
+                       dbg_info   *dbgi         = get_irn_dbg_info(n);
+                       ir_node    *block        = get_nodes_block(n);
+                       ir_relation a_relation   = get_Cmp_relation(a);
+                       ir_relation b_relation   = get_Cmp_relation(b);
+                       ir_relation new_relation = a_relation ^ b_relation;
+                       return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
                }
        }
 
+       HANDLE_BINOP_PHI((eval_func) tarval_eor, a, b, c, mode);
+
        /* normalize not nodes... ~a ^ b <=> a ^ ~b */
        if (is_Not(a) && operands_are_normalized(get_Not_op(a), b)) {
                dbg_info *dbg      = get_irn_dbg_info(n);
@@ -3410,15 +3354,14 @@ static ir_node *transform_node_Not(ir_node *n)
        HANDLE_UNOP_PHI(tarval_not,a,c);
 
        /* check for a boolean Not */
-       if (mode == mode_b && is_Proj(a)) {
-               ir_node *a_pred = get_Proj_pred(a);
-               if (is_Cmp(a_pred)) {
-                       /* We negate a Cmp. The Cmp has the negated result anyways! */
-                       n = new_r_Proj(get_Proj_pred(a),
-                                      mode_b, get_negated_pnc(get_Proj_proj(a), mode_b));
-                       DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_CMP);
-                       return n;
-               }
+       if (is_Cmp(a)) {
+               dbg_info *dbgi  = get_irn_dbg_info(a);
+               ir_node  *block = get_nodes_block(a);
+               ir_relation relation = get_Cmp_relation(a);
+               relation = get_negated_relation(relation);
+               n = new_rd_Cmp(dbgi, block, get_Cmp_left(a), get_Cmp_right(a), relation);
+               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_CMP);
+               return n;
        }
 
        /* normalize ~(a ^ b) => a ^ ~b */
@@ -3452,7 +3395,7 @@ static ir_node *transform_node_Not(ir_node *n)
                }
        }
        return n;
-}  /* transform_node_Not */
+}
 
 /**
  * Transform a Minus.
@@ -3736,80 +3679,81 @@ static ir_node *transform_node_Proj_Mod(ir_node *proj)
  */
 static ir_node *transform_node_Proj_Cond(ir_node *proj)
 {
-       if (get_opt_unreachable_code()) {
-               ir_node *n = get_Proj_pred(proj);
-               ir_node *b = get_Cond_selector(n);
+       ir_node *n = get_Proj_pred(proj);
+       ir_node *b = get_Cond_selector(n);
 
-               if (mode_is_int(get_irn_mode(b))) {
-                       ir_tarval *tb = value_of(b);
+       if (!get_opt_unreachable_code())
+               return n;
 
-                       if (tb != tarval_bad) {
-                               /* we have a constant switch */
-                               long num = get_Proj_proj(proj);
+       if (mode_is_int(get_irn_mode(b))) {
+               ir_tarval *tb = value_of(b);
 
-                               if (num != get_Cond_default_proj(n)) { /* we cannot optimize default Proj's yet */
-                                       if (get_tarval_long(tb) == num) {
-                                               /* Do NOT create a jump here, or we will have 2 control flow ops
-                                                * in a block. This case is optimized away in optimize_cf(). */
-                                               return proj;
-                                       } else {
-                                               ir_graph *irg = get_irn_irg(proj);
-                                               /* this case will NEVER be taken, kill it */
-                                               return get_irg_bad(irg);
-                                       }
-                               }
-                       } else {
-                               long num = get_Proj_proj(proj);
-                               vrp_attr *b_vrp = vrp_get_info(b);
-                               if (num != get_Cond_default_proj(n) && b_vrp) {
-                                       /* Try handling with vrp data. We only remove dead parts. */
-                                       ir_tarval *tp = new_tarval_from_long(num, get_irn_mode(b));
-
-                                       if (b_vrp->range_type == VRP_RANGE) {
-                                               pn_Cmp cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
-                                               pn_Cmp cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
-
-                                               if ((cmp_result & pn_Cmp_Gt) == cmp_result && (cmp_result2
-                                                                       & pn_Cmp_Lt) == cmp_result2) {
-                                                       ir_graph *irg = get_irn_irg(proj);
-                                                       return get_irg_bad(irg);
-                                               }
-                                       } else if (b_vrp->range_type == VRP_ANTIRANGE) {
-                                               pn_Cmp cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
-                                               pn_Cmp cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
-
-                                               if ((cmp_result & pn_Cmp_Le) == cmp_result && (cmp_result2
-                                                                       & pn_Cmp_Ge) == cmp_result2) {
-                                                       ir_graph *irg = get_irn_irg(proj);
-                                                       return get_irg_bad(irg);
-                                               }
-                                       }
+               if (tb != tarval_bad) {
+                       /* we have a constant switch */
+                       long num = get_Proj_proj(proj);
 
-                                       if (!(tarval_cmp(
-                                                                       tarval_and( b_vrp->bits_set, tp),
-                                                                       b_vrp->bits_set
-                                                                       ) == pn_Cmp_Eq)) {
+                       if (num != get_Cond_default_proj(n)) { /* we cannot optimize default Proj's yet */
+                               if (get_tarval_long(tb) == num) {
+                                       /* Do NOT create a jump here, or we will have 2 control flow ops
+                                        * in a block. This case is optimized away in optimize_cf(). */
+                                       return proj;
+                               } else {
+                                       ir_graph *irg = get_irn_irg(proj);
+                                       /* this case will NEVER be taken, kill it */
+                                       return get_irg_bad(irg);
+                               }
+                       }
+               } else {
+                       long num = get_Proj_proj(proj);
+                       vrp_attr *b_vrp = vrp_get_info(b);
+                       if (num != get_Cond_default_proj(n) && b_vrp) {
+                               /* Try handling with vrp data. We only remove dead parts. */
+                               ir_tarval *tp = new_tarval_from_long(num, get_irn_mode(b));
+
+                               if (b_vrp->range_type == VRP_RANGE) {
+                                       ir_relation cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
+                                       ir_relation cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
+
+                                       if ((cmp_result & ir_relation_greater) == cmp_result && (cmp_result2
+                                                               & ir_relation_less) == cmp_result2) {
                                                ir_graph *irg = get_irn_irg(proj);
                                                return get_irg_bad(irg);
                                        }
+                               } else if (b_vrp->range_type == VRP_ANTIRANGE) {
+                                       ir_relation cmp_result = tarval_cmp(b_vrp->range_bottom, tp);
+                                       ir_relation cmp_result2 = tarval_cmp(b_vrp->range_top, tp);
 
-                                       if (!(tarval_cmp(
-                                                                       tarval_and(
-                                                                               tarval_not(tp),
-                                                                               tarval_not(b_vrp->bits_not_set)),
-                                                                       tarval_not(b_vrp->bits_not_set))
-                                                                        == pn_Cmp_Eq)) {
+                                       if ((cmp_result & ir_relation_less_equal) == cmp_result && (cmp_result2
+                                                               & ir_relation_greater_equal) == cmp_result2) {
                                                ir_graph *irg = get_irn_irg(proj);
                                                return get_irg_bad(irg);
                                        }
+                               }
 
+                               if (!(tarval_cmp(
+                                                               tarval_and( b_vrp->bits_set, tp),
+                                                               b_vrp->bits_set
+                                                               ) == ir_relation_equal)) {
+                                       ir_graph *irg = get_irn_irg(proj);
+                                       return get_irg_bad(irg);
+                               }
 
+                               if (!(tarval_cmp(
+                                                               tarval_and(
+                                                                       tarval_not(tp),
+                                                                       tarval_not(b_vrp->bits_not_set)),
+                                                               tarval_not(b_vrp->bits_not_set))
+                                                                == ir_relation_equal)) {
+                                       ir_graph *irg = get_irn_irg(proj);
+                                       return get_irg_bad(irg);
                                }
+
+
                        }
                }
        }
        return proj;
-}  /* transform_node_Proj_Cond */
+}
 
 /**
  * return true if the operation returns a value with exactly 1 bit set
@@ -3847,42 +3791,26 @@ static ir_node *create_zero_const(ir_graph *irg, ir_mode *mode)
 /**
  * Normalizes and optimizes Cmp nodes.
  */
-static ir_node *transform_node_Proj_Cmp(ir_node *proj)
-{
-       ir_node     *n       = get_Proj_pred(proj);
-       ir_node     *left    = get_Cmp_left(n);
-       ir_node     *right   = get_Cmp_right(n);
-       ir_tarval   *tv      = NULL;
-       int          changed = 0;
-       ir_mode     *mode    = get_irn_mode(left);
-       long         proj_nr = get_Proj_proj(proj);
-
-       /* we can evaluate some cases directly */
-       switch (proj_nr) {
-       case pn_Cmp_False: {
-               ir_graph *irg = get_irn_irg(proj);
-               return new_r_Const(irg, get_tarval_b_false());
-       }
-       case pn_Cmp_True: {
-               ir_graph *irg = get_irn_irg(proj);
-               return new_r_Const(irg, get_tarval_b_true());
-       }
-       case pn_Cmp_Leg:
-               if (!mode_is_float(mode)) {
-                       ir_graph *irg = get_irn_irg(proj);
-                       return new_r_Const(irg, get_tarval_b_true());
-               }
-               break;
-       default:
-               break;
-       }
+static ir_node *transform_node_Cmp(ir_node *n)
+{
+       ir_node    *left     = get_Cmp_left(n);
+       ir_node    *right    = get_Cmp_right(n);
+       ir_mode    *mode     = get_irn_mode(left);
+       ir_tarval  *tv       = NULL;
+       bool        changed  = false;
+       bool        changedc = false;
+       ir_relation relation = get_Cmp_relation(n);
+       ir_relation possible = determine_possible_cmp_relations(left, right);
 
-       /* remove Casts of both sides */
-       left  = skip_Cast(left);
-       right = skip_Cast(right);
+       /* mask out impossible relations */
+       ir_relation new_relation = relation & possible;
+       if (new_relation != relation) {
+               relation = new_relation;
+               changed  = true;
+       }
 
        /* Remove unnecessary conversions */
-       /* TODO handle constants */
+       /* TODO handle conv+constant */
        if (is_Conv(left) && is_Conv(right)) {
                ir_node *op_left     = get_Conv_op(left);
                ir_node *op_right    = get_Conv_op(right);
@@ -3896,24 +3824,38 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                        if (mode_left == mode_right) {
                                left  = op_left;
                                right = op_right;
-                               changed |= 1;
+                               changed = true;
                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV_CONV);
                        } else if (smaller_mode(mode_left, mode_right)) {
                                left  = new_r_Conv(block, op_left, mode_right);
                                right = op_right;
-                               changed |= 1;
+                               changed = true;
                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
                        } else if (smaller_mode(mode_right, mode_left)) {
                                left  = op_left;
                                right = new_r_Conv(block, op_right, mode_left);
-                               changed |= 1;
+                               changed = true;
                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
                        }
                }
        }
 
+       /*
+        * Optimize -a CMP -b into b CMP a.
+        * This works only for modes where unary Minus cannot Overflow.
+        * Note that two-complement integers can Overflow so it will NOT work.
+        */
+       if (!mode_overflow_on_unary_Minus(mode) &&
+                       is_Minus(left) && is_Minus(right)) {
+               left     = get_Minus_op(left);
+               right    = get_Minus_op(right);
+               relation = get_inversed_relation(relation);
+               changed  = true;
+               DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
+       }
+
        /* remove operation on both sides if possible */
-       if (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) {
+       if (relation == ir_relation_equal || relation == ir_relation_less_greater) {
                /*
                 * The following operations are NOT safe for floating point operations, for instance
                 * 1.0 + inf == 2.0 + inf, =/=> x == y
@@ -3931,7 +3873,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                        /* ~a CMP ~b => a CMP b, -a CMP -b ==> a CMP b */
                                        left  = get_unop_op(left);
                                        right = get_unop_op(right);
-                                       changed |= 1;
+                                       changed = true;
                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        break;
                                case iro_Add:
@@ -3944,25 +3886,25 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                /* X + a CMP X + b ==> a CMP b */
                                                left  = lr;
                                                right = rr;
-                                               changed |= 1;
+                                               changed = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        } else if (ll == rr) {
                                                /* X + a CMP b + X ==> a CMP b */
                                                left  = lr;
                                                right = rl;
-                                               changed |= 1;
+                                               changed = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        } else if (lr == rl) {
                                                /* a + X CMP X + b ==> a CMP b */
                                                left  = ll;
                                                right = rr;
-                                               changed |= 1;
+                                               changed = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        } else if (lr == rr) {
                                                /* a + X CMP b + X ==> a CMP b */
                                                left  = ll;
                                                right = rl;
-                                               changed |= 1;
+                                               changed = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        }
                                        break;
@@ -3976,13 +3918,13 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                /* X - a CMP X - b ==> a CMP b */
                                                left  = lr;
                                                right = rr;
-                                               changed |= 1;
+                                               changed = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        } else if (lr == rr) {
                                                /* a - X CMP b - X ==> a CMP b */
                                                left  = ll;
                                                right = rl;
-                                               changed |= 1;
+                                               changed = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        }
                                        break;
@@ -3991,7 +3933,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                /* a ROTL X CMP b ROTL X ==> a CMP b */
                                                left  = get_Rotl_left(left);
                                                right = get_Rotl_left(right);
-                                               changed |= 1;
+                                               changed = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                        }
                                        break;
@@ -4013,8 +3955,8 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                if (ll == right) {
                                        ir_graph *irg = get_irn_irg(n);
                                        left     = lr;
-                                       right    = create_zero_const(irg, mode);
-                                       changed |= 1;
+                                       right   = create_zero_const(irg, mode);
+                                       changed = true;
                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                }
                        }
@@ -4030,8 +3972,8 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                if (rl == left) {
                                        ir_graph *irg = get_irn_irg(n);
                                        left     = rr;
-                                       right    = create_zero_const(irg, mode);
-                                       changed |= 1;
+                                       right   = create_zero_const(irg, mode);
+                                       changed = true;
                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
                                }
                        }
@@ -4057,7 +3999,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
 
                                                left  = new_rd_And(dbg, block, get_Shr_left(ll), new_r_Const(irg, mask), mode);
                                                right = new_r_Const(irg, value);
-                                               changed |= 1;
+                                               changed = true;
                                        }
                                }
                        }
@@ -4066,16 +4008,17 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                        if (is_Const(right) && is_Const_null(right) && is_Eor(left)) {
                                right = get_Eor_right(left);
                                left  = get_Eor_left(left);
-                               changed |= 1;
+                               changed = true;
                        }
                }  /* mode_is_int(...) */
-       }  /* proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg */
+       }
 
        /* Cmp(And(1bit, val), 1bit) "bit-testing" can be replaced
         * by the simpler Cmp(And(1bit), val), 0) negated pnc */
-       if (mode_is_int(mode) && is_And(left) && (proj_nr == pn_Cmp_Eq
-                       || (mode_is_signed(mode) && proj_nr == pn_Cmp_Lg)
-                       || (!mode_is_signed(mode) && (proj_nr & pn_Cmp_Le) == pn_Cmp_Lt))) {
+       if (mode_is_int(mode) && is_And(left)
+           && (relation == ir_relation_equal
+               || (mode_is_signed(mode) && relation == ir_relation_less_greater)
+               || (!mode_is_signed(mode) && (relation & ir_relation_less_equal) == ir_relation_less))) {
                ir_node *and0 = get_And_left(left);
                ir_node *and1 = get_And_right(left);
                if (and1 == right) {
@@ -4085,27 +4028,44 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                }
                if (and0 == right && is_single_bit(and0)) {
                        ir_graph *irg = get_irn_irg(n);
-                       proj_nr = proj_nr == pn_Cmp_Eq ? pn_Cmp_Lg : pn_Cmp_Eq;
+                       relation =
+                               relation == ir_relation_equal ? ir_relation_less_greater : ir_relation_equal;
                        right = create_zero_const(irg, mode);
                        changed |= 1;
                }
        }
 
        /* replace mode_b compares with ands/ors */
-       if (get_irn_mode(left) == mode_b) {
+       if (mode == mode_b) {
                ir_node  *block = get_nodes_block(n);
                ir_node  *bres;
 
-               switch (proj_nr) {
-                       case pn_Cmp_Le: bres = new_r_Or( block, new_r_Not(block, left, mode_b), right, mode_b); break;
-                       case pn_Cmp_Lt: bres = new_r_And(block, new_r_Not(block, left, mode_b), right, mode_b); break;
-                       case pn_Cmp_Ge: bres = new_r_Or( block, left, new_r_Not(block, right, mode_b), mode_b); break;
-                       case pn_Cmp_Gt: bres = new_r_And(block, left, new_r_Not(block, right, mode_b), mode_b); break;
-                       case pn_Cmp_Lg: bres = new_r_Eor(block, left, right, mode_b); break;
-                       case pn_Cmp_Eq: bres = new_r_Not(block, new_r_Eor(block, left, right, mode_b), mode_b); break;
-                       default: bres = NULL;
-               }
-               if (bres) {
+               switch (relation) {
+                       case ir_relation_less_equal:
+                               bres = new_r_Or(block, new_r_Not(block, left, mode_b), right, mode_b);
+                               break;
+                       case ir_relation_less:
+                               bres = new_r_And(block, new_r_Not(block, left, mode_b), right, mode_b);
+                               break;
+                       case ir_relation_greater_equal:
+                               bres = new_r_Or(block, left, new_r_Not(block, right, mode_b), mode_b);
+                               break;
+                       case ir_relation_greater:
+                               bres = new_r_And(block, left, new_r_Not(block, right, mode_b), mode_b);
+                               break;
+                       case ir_relation_less_greater:
+                               bres = new_r_Eor(block, left, right, mode_b);
+                               break;
+                       case ir_relation_equal:
+                               bres = new_r_Not(block, new_r_Eor(block, left, right, mode_b), mode_b);
+                               break;
+                       default:
+#ifdef DEBUG_libfirm
+                               ir_fprintf(stderr, "Optimisation warning, unexpected mode_b Cmp %+F\n", n);
+#endif
+                               bres = NULL;
+               }
+               if (bres != NULL) {
                        DBG_OPT_ALGSIM0(n, bres, FS_OPT_CMP_TO_BOOL);
                        return bres;
                }
@@ -4118,12 +4078,11 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
         */
        if (!operands_are_normalized(left, right)) {
                ir_node *t = left;
-
                left  = right;
                right = t;
 
-               proj_nr = get_inversed_pnc(proj_nr);
-               changed |= 1;
+               relation = get_inversed_relation(relation);
+               changed  = true;
        }
 
        /*
@@ -4134,7 +4093,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
         */
        tv = value_of(right);
        if (tv != tarval_bad) {
-               mode = get_irn_mode(right);
+               ir_mode *mode = get_irn_mode(right);
 
                /* TODO extend to arbitrary constants */
                if (is_Conv(left) && tarval_is_null(tv)) {
@@ -4147,13 +4106,13 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                         * win. (on the other side it makes detection/creation of fabs hard)
                         */
                        if (get_mode_size_bits(mode) > get_mode_size_bits(op_mode) &&
-                           ((proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) ||
+                           ((relation == ir_relation_equal || relation == ir_relation_less_greater) ||
                                 mode_is_signed(mode) || !mode_is_signed(op_mode)) &&
                                !mode_is_float(mode)) {
                                tv   = get_mode_null(op_mode);
                                left = op;
                                mode = op_mode;
-                               changed |= 2;
+                               changedc = true;
                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
                        }
                }
@@ -4169,60 +4128,53 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                         */
                        if (is_Minus(left) &&
                                (!mode_overflow_on_unary_Minus(mode) ||
-                               (mode_is_int(mode) && (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg)))) {
+                               (mode_is_int(mode) && (relation == ir_relation_equal || relation == ir_relation_less_greater)))) {
                                tv = tarval_neg(tv);
 
                                if (tv != tarval_bad) {
                                        left = get_Minus_op(left);
-                                       proj_nr = get_inversed_pnc(proj_nr);
-                                       changed |= 2;
+                                       relation = get_inversed_relation(relation);
+                                       changedc = true;
                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
                                }
-                       } else if (is_Not(left) && (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg)) {
+                       } else if (is_Not(left) && (relation == ir_relation_equal || relation == ir_relation_less_greater)) {
                                /* Not(a) ==/!= c  ==>  a ==/!= Not(c) */
                                tv = tarval_not(tv);
 
                                if (tv != tarval_bad) {
                                        left = get_Not_op(left);
-                                       changed |= 2;
+                                       changedc = true;
                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
                                }
                        }
 
                        /* for integer modes, we have more */
                        if (mode_is_int(mode)) {
-                               /* Ne includes Unordered which is not possible on integers.
-                                * However, frontends often use this wrong, so fix it here */
-                               if (proj_nr & pn_Cmp_Uo) {
-                                       proj_nr &= ~pn_Cmp_Uo;
-                                       set_Proj_proj(proj, proj_nr);
-                               }
-
                                /* c > 0 : a < c  ==>  a <= (c-1)    a >= c  ==>  a > (c-1) */
-                               if ((proj_nr == pn_Cmp_Lt || proj_nr == pn_Cmp_Ge) &&
-                                       tarval_cmp(tv, get_mode_null(mode)) == pn_Cmp_Gt) {
+                               if ((relation == ir_relation_less || relation == ir_relation_greater_equal) &&
+                                       tarval_cmp(tv, get_mode_null(mode)) == ir_relation_greater) {
                                        tv = tarval_sub(tv, get_mode_one(mode), NULL);
 
                                        if (tv != tarval_bad) {
-                                               proj_nr ^= pn_Cmp_Eq;
-                                               changed |= 2;
+                                               relation ^= ir_relation_equal;
+                                               changedc = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
                                        }
                                }
                                /* c < 0 : a > c  ==>  a >= (c+1)    a <= c  ==>  a < (c+1) */
-                               else if ((proj_nr == pn_Cmp_Gt || proj_nr == pn_Cmp_Le) &&
-                                       tarval_cmp(tv, get_mode_null(mode)) == pn_Cmp_Lt) {
+                               else if ((relation == ir_relation_greater || relation == ir_relation_less_equal) &&
+                                       tarval_cmp(tv, get_mode_null(mode)) == ir_relation_less) {
                                        tv = tarval_add(tv, get_mode_one(mode));
 
                                        if (tv != tarval_bad) {
-                                               proj_nr ^= pn_Cmp_Eq;
-                                               changed |= 2;
+                                               relation ^= ir_relation_equal;
+                                               changedc = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
                                        }
                                }
 
                                /* the following reassociations work only for == and != */
-                               if (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) {
+                               if (relation == ir_relation_equal || relation == ir_relation_less_greater) {
 
 #if 0 /* Might be not that good in general */
                                        /* a-b == 0  ==>  a == b,  a-b != 0  ==>  a != b */
@@ -4248,7 +4200,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                                if (tv2 != tarval_bad) {
                                                                        left    = get_Sub_left(left);
                                                                        tv      = tv2;
-                                                                       changed |= 2;
+                                                                       changedc = true;
                                                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
                                                                }
                                                        }
@@ -4274,7 +4226,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                                if (tv2 != tarval_bad) {
                                                                        left    = a;
                                                                        tv      = tv2;
-                                                                       changed |= 2;
+                                                                       changedc = true;
                                                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
                                                                }
                                                        }
@@ -4286,7 +4238,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                        if (tv2 != tarval_bad) {
                                                                left    = get_Minus_op(left);
                                                                tv      = tv2;
-                                                               changed |= 2;
+                                                               changedc = true;
                                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
                                                        }
                                                }
@@ -4294,7 +4246,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                } /* == or != */
                        } /* mode_is_int */
 
-                       if (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) {
+                       if (relation == ir_relation_equal || relation == ir_relation_less_greater) {
                                switch (get_irn_opcode(left)) {
                                        ir_node *c1;
 
@@ -4309,9 +4261,9 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                if (mask != tv) {
                                                        /* TODO: move to constant evaluation */
                                                        ir_graph *irg = get_irn_irg(n);
-                                                       tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
+                                                       tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
                                                        c1 = new_r_Const(irg, tv);
-                                                       DBG_OPT_CSTEVAL(proj, c1);
+                                                       DBG_OPT_CSTEVAL(n, c1);
                                                        return c1;
                                                }
 
@@ -4330,8 +4282,8 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                        if (get_Const_tarval(c1) == tv) {
                                                                /* fine: do the transformation */
                                                                tv = get_mode_null(get_tarval_mode(tv));
-                                                               proj_nr ^= pn_Cmp_Leg;
-                                                               changed |= 2;
+                                                               relation ^= ir_relation_less_equal_greater;
+                                                               changedc = true;
                                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
                                                        }
                                                }
@@ -4347,9 +4299,9 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                                                if (! tarval_is_null(get_Const_tarval(c1))) {
                                                        /* TODO: move to constant evaluation */
                                                        ir_graph *irg = get_irn_irg(n);
-                                                       tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
+                                                       tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
                                                        c1 = new_r_Const(irg, tv);
-                                                       DBG_OPT_CSTEVAL(proj, c1);
+                                                       DBG_OPT_CSTEVAL(n, c1);
                                                        return c1;
                                                }
                                        }
@@ -4373,16 +4325,16 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
 
                                                if (tarval_and(tv, cmask) != tv) {
                                                        /* condition not met */
-                                                       tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
+                                                       tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
                                                        c1 = new_r_Const(irg, tv);
-                                                       DBG_OPT_CSTEVAL(proj, c1);
+                                                       DBG_OPT_CSTEVAL(n, c1);
                                                        return c1;
                                                }
                                                sl   = get_Shl_left(left);
                                                blk  = get_nodes_block(n);
                                                left = new_rd_And(get_irn_dbg_info(left), blk, sl, new_r_Const(irg, amask), mode);
                                                tv   = tarval_shr(tv, tv1);
-                                               changed |= 2;
+                                               changedc = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
                                        }
                                        break;
@@ -4405,16 +4357,16 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
 
                                                if (tarval_and(tv, cmask) != tv) {
                                                        /* condition not met */
-                                                       tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
+                                                       tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
                                                        c1 = new_r_Const(irg, tv);
-                                                       DBG_OPT_CSTEVAL(proj, c1);
+                                                       DBG_OPT_CSTEVAL(n, c1);
                                                        return c1;
                                                }
                                                sl   = get_Shr_left(left);
                                                blk  = get_nodes_block(n);
                                                left = new_rd_And(get_irn_dbg_info(left), blk, sl, new_r_Const(irg, amask), mode);
                                                tv   = tarval_shl(tv, tv1);
-                                               changed |= 2;
+                                               changedc = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
                                        }
                                        break;
@@ -4440,16 +4392,16 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
 
                                                if (!tarval_is_all_one(cond) && !tarval_is_null(cond)) {
                                                        /* condition not met */
-                                                       tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
+                                                       tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
                                                        c1 = new_r_Const(irg, tv);
-                                                       DBG_OPT_CSTEVAL(proj, c1);
+                                                       DBG_OPT_CSTEVAL(n, c1);
                                                        return c1;
                                                }
                                                sl   = get_Shrs_left(left);
                                                blk  = get_nodes_block(n);
                                                left = new_rd_And(get_irn_dbg_info(left), blk, sl, new_r_Const(irg, amask), mode);
                                                tv   = tarval_shl(tv, tv1);
-                                               changed |= 2;
+                                               changedc = true;
                                                DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
                                        }
                                        break;
@@ -4458,12 +4410,13 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
                } /* tarval != bad */
        }
 
-       if (changed & 2) {     /* need a new Const */
+       if (changedc) {     /* need a new Const */
                ir_graph *irg = get_irn_irg(n);
                right = new_r_Const(irg, tv);
+               changed = true;
        }
 
-       if ((proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) && is_Const(right) && is_Const_null(right) && is_Proj(left)) {
+       if ((relation == ir_relation_equal || relation == ir_relation_less_greater) && is_Const(right) && is_Const_null(right) && is_Proj(left)) {
                ir_node *op = get_Proj_pred(left);
 
                if (is_Mod(op) && get_Proj_proj(left) == pn_Mod_res) {
@@ -4481,7 +4434,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
 
                                        tv = tarval_sub(tv, get_mode_one(mode), NULL);
                                        left = new_rd_And(get_irn_dbg_info(op), blk, v, new_r_Const(irg, tv), mode);
-                                       changed |= 1;
+                                       changed = true;
                                        DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_MOD_TO_AND);
                                }
                        }
@@ -4489,15 +4442,15 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj)
        }
 
        if (changed) {
-               ir_node *block = get_nodes_block(n);
+               dbg_info *dbgi  = get_irn_dbg_info(n);
+               ir_node  *block = get_nodes_block(n);
 
                /* create a new compare */
-               n = new_rd_Cmp(get_irn_dbg_info(n), block, left, right);
-               proj = new_rd_Proj(get_irn_dbg_info(proj), n, get_irn_mode(proj), proj_nr);
+               n = new_rd_Cmp(dbgi, block, left, right, relation);
        }
 
-       return proj;
-}  /* transform_node_Proj_Cmp */
+       return n;
+}
 
 /**
  * Optimize CopyB(mem, x, x) into a Nop.
@@ -4609,15 +4562,15 @@ static ir_node *transform_node_Phi(ir_node *phi)
 
                /* Beware of Phi0 */
                if (n > 0) {
-                       ir_node *pred = get_irn_n(phi, 0);
-                       ir_node *bound, *new_phi, *block, **in;
-                       pn_Cmp  pnc;
+                       ir_node    *pred = get_irn_n(phi, 0);
+                       ir_node    *bound, *new_phi, *block, **in;
+                       ir_relation relation;
 
                        if (! is_Confirm(pred))
                                return phi;
 
-                       bound = get_Confirm_bound(pred);
-                       pnc   = get_Confirm_cmp(pred);
+                       bound    = get_Confirm_bound(pred);
+                       relation = get_Confirm_relation(pred);
 
                        NEW_ARR_A(ir_node *, in, n);
                        in[0] = get_Confirm_value(pred);
@@ -4627,18 +4580,18 @@ static ir_node *transform_node_Phi(ir_node *phi)
 
                                if (! is_Confirm(pred) ||
                                        get_Confirm_bound(pred) != bound ||
-                                       get_Confirm_cmp(pred) != pnc)
+                                       get_Confirm_relation(pred) != relation)
                                        return phi;
                                in[i] = get_Confirm_value(pred);
                        }
                        /* move the Confirm nodes "behind" the Phi */
                        block = get_irn_n(phi, -1);
                        new_phi = new_r_Phi(block, n, in, get_irn_mode(phi));
-                       return new_r_Confirm(block, new_phi, bound, pnc);
+                       return new_r_Confirm(block, new_phi, bound, relation);
                }
        }
        return phi;
-}  /* transform_node_Phi */
+}
 
 /**
  * Returns the operands of a commutative bin-op, if one operand is
@@ -4855,18 +4808,19 @@ static ir_node *transform_node_Or(ir_node *n)
                return n;
        }
 
-       /* we can evaluate 2 Projs of the same Cmp */
-       if (get_irn_mode(n) == mode_b && is_Proj(a) && is_Proj(b)) {
-               ir_node *pred_a = get_Proj_pred(a);
-               ir_node *pred_b = get_Proj_pred(b);
-               if (pred_a == pred_b) {
-                       dbg_info *dbgi  = get_irn_dbg_info(n);
-                       pn_Cmp pn_a     = get_Proj_pn_cmp(a);
-                       pn_Cmp pn_b     = get_Proj_pn_cmp(b);
-                       /* yes, we can simply calculate with pncs */
-                       pn_Cmp new_pnc  = pn_a | pn_b;
-
-                       return new_rd_Proj(dbgi, pred_a, mode_b, new_pnc);
+       /* we can combine the relations of two compares with the same operands */
+       if (is_Cmp(a) && is_Cmp(b)) {
+               ir_node *a_left  = get_Cmp_left(a);
+               ir_node *a_right = get_Cmp_left(a);
+               ir_node *b_left  = get_Cmp_left(b);
+               ir_node *b_right = get_Cmp_right(b);
+               if (a_left == b_left && b_left == b_right) {
+                       dbg_info   *dbgi         = get_irn_dbg_info(n);
+                       ir_node    *block        = get_nodes_block(n);
+                       ir_relation a_relation   = get_Cmp_relation(a);
+                       ir_relation b_relation   = get_Cmp_relation(b);
+                       ir_relation new_relation = a_relation | b_relation;
+                       return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
                }
        }
 
@@ -4929,7 +4883,7 @@ static ir_node *transform_node_shift(ir_node *n)
                        assert(modulo_shf >= (int) get_mode_size_bits(mode));
 
                        /* shifting too much */
-                       if (!(tarval_cmp(res, modulo) & pn_Cmp_Lt)) {
+                       if (!(tarval_cmp(res, modulo) & ir_relation_less)) {
                                if (is_Shrs(n)) {
                                        ir_node  *block = get_nodes_block(n);
                                        dbg_info *dbgi  = get_irn_dbg_info(n);
@@ -5066,7 +5020,7 @@ static ir_node *transform_node_shl_shr(ir_node *n)
        ir_tarval *tv_shift;
        ir_tarval *tv_mask;
        ir_graph  *irg;
-       pn_Cmp     pnc;
+       ir_relation relation;
        int        need_shrs = 0;
 
        assert(is_Shl(n) || is_Shr(n) || is_Shrs(n));
@@ -5088,7 +5042,7 @@ static ir_node *transform_node_shl_shr(ir_node *n)
 
                if (is_Shrs(left)) {
                        /* shrs variant only allowed if c1 >= c2 */
-                       if (! (tarval_cmp(tv_shl, tv_shr) & pn_Cmp_Ge))
+                       if (! (tarval_cmp(tv_shl, tv_shr) & ir_relation_greater_equal))
                                return n;
 
                        tv_mask = tarval_shrs(get_mode_all_one(mode), tv_shr);
@@ -5124,8 +5078,8 @@ static ir_node *transform_node_shl_shr(ir_node *n)
        irg   = get_irn_irg(block);
        dbgi  = get_irn_dbg_info(n);
 
-       pnc = tarval_cmp(tv_shl, tv_shr);
-       if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Eq) {
+       relation = tarval_cmp(tv_shl, tv_shr);
+       if (relation == ir_relation_less || relation == ir_relation_equal) {
                tv_shift  = tarval_sub(tv_shr, tv_shl, NULL);
                new_const = new_r_Const(irg, tv_shift);
                if (need_shrs) {
@@ -5134,7 +5088,7 @@ static ir_node *transform_node_shl_shr(ir_node *n)
                        new_shift = new_rd_Shr(dbgi, block, x, new_const, mode);
                }
        } else {
-               assert(pnc == pn_Cmp_Gt);
+               assert(relation == ir_relation_greater);
                tv_shift  = tarval_sub(tv_shl, tv_shr, NULL);
                new_const = new_r_Const(irg, tv_shift);
                new_shift = new_rd_Shl(dbgi, block, x, new_const, mode);
@@ -5491,21 +5445,20 @@ static ir_node *transform_node_Mux(ir_node *n)
 
        /* first normalization step: try to move a constant to the false side,
         * 0 preferred on false side too */
-       if (is_Proj(sel)) {
-               ir_node *cmp = get_Proj_pred(sel);
-
-               if (is_Cmp(cmp) && is_Const(t) &&
-                   (!is_Const(f) || (is_Const_null(t) && !is_Const_null(f)))) {
-                       pn_Cmp pnc = get_Proj_pn_cmp(sel);
-                       ir_node *tmp = t;
-                       t = f;
-                       f = tmp;
-
-                       /* Mux(x, a, b) => Mux(not(x), b, a) */
-                       sel = new_r_Proj(cmp, mode_b,
-                               get_negated_pnc(pnc, get_irn_mode(get_Cmp_left(cmp))));
-                       n = new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t, mode);
-               }
+       if (is_Cmp(sel) && is_Const(t) &&
+                       (!is_Const(f) || (is_Const_null(t) && !is_Const_null(f)))) {
+               dbg_info *seldbgi = get_irn_dbg_info(sel);
+               ir_node  *block   = get_nodes_block(sel);
+               ir_relation relation = get_Cmp_relation(sel);
+               ir_node *tmp = t;
+               t = f;
+               f = tmp;
+
+               /* Mux(x, a, b) => Mux(not(x), b, a) */
+               relation = get_negated_relation(relation);
+               sel = new_rd_Cmp(seldbgi, block, get_Cmp_left(sel),
+                               get_Cmp_right(sel), relation);
+               n = new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t, mode);
        }
 
        /* note: after normalization, false can only happen on default */
@@ -5568,77 +5521,69 @@ static ir_node *transform_node_Mux(ir_node *n)
                }
        }
 
-       if (is_Proj(sel)) {
-               ir_node *cmp = get_Proj_pred(sel);
-               long     pn  = get_Proj_proj(sel);
+       if (is_Cmp(sel)) {
+               ir_node    *cmp_r    = get_Cmp_right(sel);
+               if (is_Const(cmp_r) && is_Const_null(cmp_r)) {
+                       ir_node *block = get_nodes_block(n);
+                       ir_node *cmp_l = get_Cmp_left(sel);
 
-               /*
-                * Note: normalization puts the constant on the right side,
-                * so we check only one case.
-                */
-               if (is_Cmp(cmp)) {
-                       ir_node *cmp_r = get_Cmp_right(cmp);
-                       if (is_Const(cmp_r) && is_Const_null(cmp_r)) {
-                               ir_node *block = get_nodes_block(n);
-                               ir_node *cmp_l = get_Cmp_left(cmp);
-
-                               if (mode_is_int(mode)) {
-                                       /* integer only */
-                                       if ((pn == pn_Cmp_Lg || pn == pn_Cmp_Eq) && is_And(cmp_l)) {
-                                               /* Mux((a & b) != 0, c, 0) */
-                                               ir_node *and_r = get_And_right(cmp_l);
-                                               ir_node *and_l;
-
-                                               if (and_r == t && f == cmp_r) {
-                                                       if (is_Const(t) && tarval_is_single_bit(get_Const_tarval(t))) {
-                                                               if (pn == pn_Cmp_Lg) {
-                                                                       /* Mux((a & 2^C) != 0, 2^C, 0) */
+                       if (mode_is_int(mode)) {
+                               ir_relation relation = get_Cmp_relation(sel);
+                               /* integer only */
+                               if ((relation == ir_relation_less_greater || relation == ir_relation_equal) && is_And(cmp_l)) {
+                                       /* Mux((a & b) != 0, c, 0) */
+                                       ir_node *and_r = get_And_right(cmp_l);
+                                       ir_node *and_l;
+
+                                       if (and_r == t && f == cmp_r) {
+                                               if (is_Const(t) && tarval_is_single_bit(get_Const_tarval(t))) {
+                                                       if (relation == ir_relation_less_greater) {
+                                                               /* Mux((a & 2^C) != 0, 2^C, 0) */
+                                                               n = cmp_l;
+                                                               DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
+                                                       } else {
+                                                               /* Mux((a & 2^C) == 0, 2^C, 0) */
+                                                               n = new_rd_Eor(get_irn_dbg_info(n),
+                                                                       block, cmp_l, t, mode);
+                                                               DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
+                                                       }
+                                                       return n;
+                                               }
+                                       }
+                                       if (is_Shl(and_r)) {
+                                               ir_node *shl_l = get_Shl_left(and_r);
+                                               if (is_Const(shl_l) && is_Const_one(shl_l)) {
+                                                       if (and_r == t && f == cmp_r) {
+                                                               if (relation == ir_relation_less_greater) {
+                                                                       /* (a & (1 << n)) != 0, (1 << n), 0) */
                                                                        n = cmp_l;
-                                                                       DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_BITOP);
+                                                                       DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
                                                                } else {
-                                                                       /* Mux((a & 2^C) == 0, 2^C, 0) */
+                                                                       /* (a & (1 << n)) == 0, (1 << n), 0) */
                                                                        n = new_rd_Eor(get_irn_dbg_info(n),
                                                                                block, cmp_l, t, mode);
-                                                                       DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_BITOP);
+                                                                       DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
                                                                }
                                                                return n;
                                                        }
                                                }
-                                               if (is_Shl(and_r)) {
-                                                       ir_node *shl_l = get_Shl_left(and_r);
-                                                       if (is_Const(shl_l) && is_Const_one(shl_l)) {
-                                                               if (and_r == t && f == cmp_r) {
-                                                                       if (pn == pn_Cmp_Lg) {
-                                                                               /* (a & (1 << n)) != 0, (1 << n), 0) */
-                                                                               n = cmp_l;
-                                                                               DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_BITOP);
-                                                                       } else {
-                                                                               /* (a & (1 << n)) == 0, (1 << n), 0) */
-                                                                               n = new_rd_Eor(get_irn_dbg_info(n),
-                                                                                       block, cmp_l, t, mode);
-                                                                               DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_BITOP);
-                                                                       }
-                                                                       return n;
-                                                               }
-                                                       }
-                                               }
-                                               and_l = get_And_left(cmp_l);
-                                               if (is_Shl(and_l)) {
-                                                       ir_node *shl_l = get_Shl_left(and_l);
-                                                       if (is_Const(shl_l) && is_Const_one(shl_l)) {
-                                                               if (and_l == t && f == cmp_r) {
-                                                                       if (pn == pn_Cmp_Lg) {
-                                                                               /* ((1 << n) & a) != 0, (1 << n), 0) */
-                                                                               n = cmp_l;
-                                                                               DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_BITOP);
-                                                                       } else {
-                                                                               /* ((1 << n) & a) == 0, (1 << n), 0) */
-                                                                               n = new_rd_Eor(get_irn_dbg_info(n),
-                                                                                       block, cmp_l, t, mode);
-                                                                               DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_BITOP);
-                                                                       }
-                                                                       return n;
+                                       }
+                                       and_l = get_And_left(cmp_l);
+                                       if (is_Shl(and_l)) {
+                                               ir_node *shl_l = get_Shl_left(and_l);
+                                               if (is_Const(shl_l) && is_Const_one(shl_l)) {
+                                                       if (and_l == t && f == cmp_r) {
+                                                               if (relation == ir_relation_less_greater) {
+                                                                       /* ((1 << n) & a) != 0, (1 << n), 0) */
+                                                                       n = cmp_l;
+                                                                       DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
+                                                               } else {
+                                                                       /* ((1 << n) & a) == 0, (1 << n), 0) */
+                                                                       n = new_rd_Eor(get_irn_dbg_info(n),
+                                                                               block, cmp_l, t, mode);
+                                                                       DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
                                                                }
+                                                               return n;
                                                        }
                                                }
                                        }
@@ -5648,7 +5593,7 @@ static ir_node *transform_node_Mux(ir_node *n)
        }
 
        return n;
-}  /* transform_node_Mux */
+}
 
 /**
  * optimize Sync nodes that have other syncs as input we simply add the inputs
@@ -5818,33 +5763,33 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops
 
        switch (code) {
        CASE(Add);
-       CASE(Sub);
-       CASE(Mul);
-       CASE_PROJ_EX(Div);
-       CASE_PROJ_EX(Mod);
-       CASE_PROJ_EX(Cmp);
-       CASE_PROJ_EX(Cond);
        CASE(And);
+       CASE(Call);
+       CASE(Cmp);
+       CASE(Conv);
+       CASE(End);
        CASE(Eor);
-       CASE(Not);
        CASE(Minus);
-       CASE_PROJ(Load);
-       CASE_PROJ(Store);
-       CASE_PROJ(Bound);
-       CASE_PROJ(CopyB);
-       CASE(Proj);
-       CASE(Phi);
+       CASE(Mul);
+       CASE(Mux);
+       CASE(Not);
        CASE(Or);
+       CASE(Phi);
+       CASE(Proj);
+       CASE(Rotl);
        CASE(Sel);
+       CASE(Shl);
        CASE(Shr);
        CASE(Shrs);
-       CASE(Shl);
-       CASE(Rotl);
-       CASE(Conv);
-       CASE(End);
-       CASE(Mux);
+       CASE(Sub);
        CASE(Sync);
-       CASE(Call);
+       CASE_PROJ(Bound);
+       CASE_PROJ(CopyB);
+       CASE_PROJ(Load);
+       CASE_PROJ(Store);
+       CASE_PROJ_EX(Cond);
+       CASE_PROJ_EX(Div);
+       CASE_PROJ_EX(Mod);
        default:
          /* leave NULL */;
        }
@@ -5872,7 +5817,7 @@ static int node_cmp_attr_Const(const ir_node *a, const ir_node *b)
 static int node_cmp_attr_Proj(const ir_node *a, const ir_node *b)
 {
        return a->attr.proj.proj != b->attr.proj.proj;
-}  /* node_cmp_attr_Proj */
+}
 
 /** Compares the attributes of two Alloc nodes. */
 static int node_cmp_attr_Alloc(const ir_node *a, const ir_node *b)
@@ -5880,7 +5825,7 @@ static int node_cmp_attr_Alloc(const ir_node *a, const ir_node *b)
        const alloc_attr *pa = &a->attr.alloc;
        const alloc_attr *pb = &b->attr.alloc;
        return (pa->where != pb->where) || (pa->type != pb->type);
-}  /* node_cmp_attr_Alloc */
+}
 
 /** Compares the attributes of two Free nodes. */
 static int node_cmp_attr_Free(const ir_node *a, const ir_node *b)
@@ -5888,7 +5833,7 @@ static int node_cmp_attr_Free(const ir_node *a, const ir_node *b)
        const free_attr *pa = &a->attr.free;
        const free_attr *pb = &b->attr.free;
        return (pa->where != pb->where) || (pa->type != pb->type);
-}  /* node_cmp_attr_Free */
+}
 
 /** Compares the attributes of two SymConst nodes. */
 static int node_cmp_attr_SymConst(const ir_node *a, const ir_node *b)
@@ -5906,7 +5851,7 @@ static int node_cmp_attr_Call(const ir_node *a, const ir_node *b)
        const call_attr *pb = &b->attr.call;
        return (pa->type != pb->type)
                || (pa->tail_call != pb->tail_call);
-}  /* node_cmp_attr_Call */
+}
 
 /** Compares the attributes of two Sel nodes. */
 static int node_cmp_attr_Sel(const ir_node *a, const ir_node *b)
@@ -5914,7 +5859,7 @@ static int node_cmp_attr_Sel(const ir_node *a, const ir_node *b)
        const ir_entity *a_ent = get_Sel_entity(a);
        const ir_entity *b_ent = get_Sel_entity(b);
        return a_ent != b_ent;
-}  /* node_cmp_attr_Sel */
+}
 
 /** Compares the attributes of two Phi nodes. */
 static int node_cmp_attr_Phi(const ir_node *a, const ir_node *b)
@@ -5926,19 +5871,19 @@ static int node_cmp_attr_Phi(const ir_node *a, const ir_node *b)
                return a->attr.phi.u.pos != b->attr.phi.u.pos;
        }
        return 0;
-}  /* node_cmp_attr_Phi */
+}
 
 /** Compares the attributes of two Conv nodes. */
 static int node_cmp_attr_Conv(const ir_node *a, const ir_node *b)
 {
        return get_Conv_strict(a) != get_Conv_strict(b);
-}  /* node_cmp_attr_Conv */
+}
 
 /** Compares the attributes of two Cast nodes. */
 static int node_cmp_attr_Cast(const ir_node *a, const ir_node *b)
 {
        return get_Cast_type(a) != get_Cast_type(b);
-}  /* node_cmp_attr_Cast */
+}
 
 /** Compares the attributes of two Load nodes. */
 static int node_cmp_attr_Load(const ir_node *a, const ir_node *b)
@@ -5952,7 +5897,7 @@ static int node_cmp_attr_Load(const ir_node *a, const ir_node *b)
                return 1;
 
        return get_Load_mode(a) != get_Load_mode(b);
-}  /* node_cmp_attr_Load */
+}
 
 /** Compares the attributes of two Store nodes. */
 static int node_cmp_attr_Store(const ir_node *a, const ir_node *b)
@@ -5964,7 +5909,7 @@ static int node_cmp_attr_Store(const ir_node *a, const ir_node *b)
        /* NEVER do CSE on volatile Stores */
        return (get_Store_volatility(a) == volatility_is_volatile ||
                get_Store_volatility(b) == volatility_is_volatile);
-}  /* node_cmp_attr_Store */
+}
 
 /** Compares two exception attributes */
 static int node_cmp_exception(const ir_node *a, const ir_node *b)
@@ -5985,7 +5930,7 @@ static int node_cmp_attr_Div(const ir_node *a, const ir_node *b)
        return ma->exc.pin_state != mb->exc.pin_state ||
                   ma->resmode       != mb->resmode ||
                   ma->no_remainder  != mb->no_remainder;
-}  /* node_cmp_attr_Div */
+}
 
 /** Compares the attributes of two Mod nodes. */
 static int node_cmp_attr_Mod(const ir_node *a, const ir_node *b)
@@ -5994,21 +5939,29 @@ static int node_cmp_attr_Mod(const ir_node *a, const ir_node *b)
        const mod_attr *mb = &b->attr.mod;
        return ma->exc.pin_state != mb->exc.pin_state ||
                   ma->resmode       != mb->resmode;
-}  /* node_cmp_attr_Mod */
+}
+
+static int node_cmp_attr_Cmp(const ir_node *a, const ir_node *b)
+{
+       const cmp_attr *ma = &a->attr.cmp;
+       const cmp_attr *mb = &b->attr.cmp;
+       return ma->relation != mb->relation;
+}
 
 /** Compares the attributes of two Confirm nodes. */
 static int node_cmp_attr_Confirm(const ir_node *a, const ir_node *b)
 {
-       /* no need to compare the bound, as this is a input */
-       return (get_Confirm_cmp(a) != get_Confirm_cmp(b));
-}  /* node_cmp_attr_Confirm */
+       const confirm_attr *ma = &a->attr.confirm;
+       const confirm_attr *mb = &b->attr.confirm;
+       return ma->relation != mb->relation;
+}
 
 /** Compares the attributes of two Builtin nodes. */
 static int node_cmp_attr_Builtin(const ir_node *a, const ir_node *b)
 {
        /* no need to compare the type, equal kind means equal type */
        return get_Builtin_kind(a) != get_Builtin_kind(b);
-}  /* node_cmp_attr_Builtin */
+}
 
 /** Compares the attributes of two ASM nodes. */
 static int node_cmp_attr_ASM(const ir_node *a, const ir_node *b)
@@ -6055,7 +6008,7 @@ static int node_cmp_attr_ASM(const ir_node *a, const ir_node *b)
                        return 1;
        }
        return 0;
-}  /* node_cmp_attr_ASM */
+}
 
 /** Compares the inexistent attributes of two Dummy nodes. */
 static int node_cmp_attr_Dummy(const ir_node *a, const ir_node *b)
@@ -6090,6 +6043,7 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
        CASE(Call);
        CASE(Sel);
        CASE(Phi);
+       CASE(Cmp);
        CASE(Conv);
        CASE(Cast);
        CASE(Load);
index e767f1f..9a90dc2 100644 (file)
@@ -267,10 +267,14 @@ typedef struct phi_attr {
        } u;
 } phi_attr;
 
+/**< Cmp attribute. */
+typedef struct cmp_attr {
+       ir_relation relation;         /**< comparison condition. */
+} cmp_attr;
 
 /**< Confirm attribute. */
 typedef struct confirm_attr {
-       pn_Cmp cmp;                   /**< The compare operation. */
+       ir_relation relation;         /**< relation between value and bound */
 } confirm_attr;
 
 /** CopyB attribute. */
@@ -323,6 +327,7 @@ typedef union ir_attr {
        bad_attr       bad;           /**< for Bads: irg reference */
        anchor_attr    anchor;        /**< for Anchor: irg reference */
        block_attr     block;         /**< For Block: Fields needed to construct it */
+       cmp_attr       cmp;           /**< For Cmp. */
        cond_attr      cond;          /**< For Cond. */
        const_attr     con;           /**< For Const: contains the value of the constant and a type */
        symconst_attr  symc;          /**< For SymConst. */
index 46a679b..373d041 100644 (file)
@@ -498,28 +498,6 @@ static int verify_node_Proj_Mod(ir_node *n, ir_node *p)
        return 1;
 }
 
-/**
- * verify a Proj(Cmp) node
- */
-static int verify_node_Proj_Cmp(ir_node *n, ir_node *p)
-{
-       ir_mode *mode = get_irn_mode(p);
-       long proj     = get_Proj_proj(p);
-       (void) n;
-
-       ASSERT_AND_RET_DBG(
-               (proj >= 0 && proj <= 15 && mode == mode_b),
-               "wrong Proj from Cmp", 0,
-               show_proj_failure(p);
-       );
-       ASSERT_AND_RET_DBG(
-               (mode_is_float(get_irn_mode(get_Cmp_left(n))) || !(proj & pn_Cmp_Uo)),
-               "unordered Proj for non-float Cmp (Did you use Ne instead of Lg?)", 0,
-               show_proj_failure(p);
-       );
-       return 1;
-}
-
 /**
  * verify a Proj(Load) node
  */
@@ -1344,7 +1322,7 @@ static int verify_node_Cmp(ir_node *n, ir_graph *irg)
                /* Cmp: BB x datab x datab --> b16 */
                mode_is_datab(op1mode) &&
                op2mode == op1mode &&
-               mymode == mode_T,
+               mymode == mode_b,
                "Cmp node", 0,
                show_binop_failure(n, "/* Cmp: BB x datab x datab --> b16 */");
        );
@@ -2142,7 +2120,6 @@ void firm_set_default_verifyer(ir_opcode code, ir_op_ops *ops)
        CASE(Call);
        CASE(Div);
        CASE(Mod);
-       CASE(Cmp);
        CASE(Load);
        CASE(Store);
        CASE(Alloc);
index 51ee9b7..a9e1fa8 100644 (file)
@@ -985,16 +985,16 @@ static void lower_Not(ir_node *node, ir_mode *mode, lower_env_t *env)
  */
 static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
 {
-       ir_node *cmp, *left, *right, *block;
+       ir_node *left, *right, *block;
        ir_node *sel = get_Cond_selector(node);
        ir_mode *m = get_irn_mode(sel);
        ir_mode *cmp_mode;
        const node_entry_t *lentry, *rentry;
        ir_node  *proj, *projT = NULL, *projF = NULL;
-       ir_node  *new_bl, *cmpH, *cmpL, *irn;
+       ir_node  *new_bl, *irn;
        ir_node  *projHF, *projHT;
        ir_node  *dst_blk;
-       pn_Cmp   pnc;
+       ir_relation relation;
        ir_graph *irg;
        dbg_info *dbg;
 
@@ -1008,19 +1008,15 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
                return;
        }
 
-       if (!is_Proj(sel))
+       if (!is_Cmp(sel))
                return;
 
-       cmp = get_Proj_pred(sel);
-       if (!is_Cmp(cmp))
-               return;
-
-       left     = get_Cmp_left(cmp);
+       left     = get_Cmp_left(sel);
        cmp_mode = get_irn_mode(left);
        if (cmp_mode != env->high_signed && cmp_mode != env->high_unsigned)
                return;
 
-       right  = get_Cmp_right(cmp);
+       right  = get_Cmp_right(sel);
        lentry = get_node_entry(env, left);
        rentry = get_node_entry(env, right);
 
@@ -1042,36 +1038,33 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
        assert(projT && projF);
 
        /* create a new high compare */
-       block = get_nodes_block(node);
-       irg   = get_Block_irg(block);
-       dbg   = get_irn_dbg_info(cmp);
-       pnc   = get_Proj_pn_cmp(sel);
+       block    = get_nodes_block(node);
+       irg      = get_Block_irg(block);
+       dbg      = get_irn_dbg_info(sel);
+       relation = get_Cmp_relation(sel);
 
        if (is_Const(right) && is_Const_null(right)) {
-               if (pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) {
+               if (relation == ir_relation_equal || relation == ir_relation_less_greater) {
                        /* x ==/!= 0 ==> or(low,high) ==/!= 0 */
                        ir_mode *mode   = env->low_unsigned;
                        ir_node *low    = new_r_Conv(block, lentry->low_word, mode);
                        ir_node *high   = new_r_Conv(block, lentry->high_word, mode);
                        ir_node *ornode = new_rd_Or(dbg, block, low, high, mode);
-                       ir_node *cmp    = new_rd_Cmp(dbg, block, ornode, new_r_Const_long(irg, mode, 0));
-
-                       ir_node *proj = new_r_Proj(cmp, mode_b, pnc);
-                       set_Cond_selector(node, proj);
+                       ir_node *cmp    = new_rd_Cmp(dbg, block, ornode, new_r_Const_long(irg, mode, 0), relation);
+                       set_Cond_selector(node, cmp);
                        return;
                }
        }
 
-       cmpH = new_rd_Cmp(dbg, block, lentry->high_word, rentry->high_word);
-
-       if (pnc == pn_Cmp_Eq) {
+       if (relation == ir_relation_equal) {
                /* simple case:a == b <==> a_h == b_h && a_l == b_l */
                pmap_entry *entry = pmap_find(env->proj_2_block, projF);
 
                assert(entry);
                dst_blk = (ir_node*)entry->value;
 
-               irn = new_r_Proj(cmpH, mode_b, pn_Cmp_Eq);
+               irn = new_rd_Cmp(dbg, block, lentry->high_word, rentry->high_word,
+                                ir_relation_equal);
                dbg = get_irn_dbg_info(node);
                irn = new_rd_Cond(dbg, block, irn);
 
@@ -1084,9 +1077,9 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
 
                new_bl = new_r_Block(irg, 1, &projHT);
 
-               dbg   = get_irn_dbg_info(cmp);
-               cmpL = new_rd_Cmp(dbg, new_bl, lentry->low_word, rentry->low_word);
-               irn = new_r_Proj(cmpL, mode_b, pn_Cmp_Eq);
+               dbg = get_irn_dbg_info(sel);
+               irn = new_rd_Cmp(dbg, new_bl, lentry->low_word, rentry->low_word,
+                                 ir_relation_equal);
                dbg = get_irn_dbg_info(node);
                irn = new_rd_Cond(dbg, new_bl, irn);
 
@@ -1097,14 +1090,15 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
                proj = new_r_Proj(irn, mode_X, pn_Cond_true);
                mark_irn_visited(proj);
                exchange(projT, proj);
-       } else if (pnc == pn_Cmp_Lg) {
+       } else if (relation == ir_relation_less_greater) {
                /* simple case:a != b <==> a_h != b_h || a_l != b_l */
                pmap_entry *entry = pmap_find(env->proj_2_block, projT);
 
                assert(entry);
                dst_blk = (ir_node*)entry->value;
 
-               irn = new_r_Proj(cmpH, mode_b, pn_Cmp_Lg);
+               irn = new_rd_Cmp(dbg, block, lentry->high_word, rentry->high_word,
+                                ir_relation_less_greater);
                dbg = get_irn_dbg_info(node);
                irn = new_rd_Cond(dbg, block, irn);
 
@@ -1117,9 +1111,9 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
 
                new_bl = new_r_Block(irg, 1, &projHF);
 
-               dbg   = get_irn_dbg_info(cmp);
-               cmpL = new_rd_Cmp(dbg, new_bl, lentry->low_word, rentry->low_word);
-               irn = new_r_Proj(cmpL, mode_b, pn_Cmp_Lg);
+               dbg = get_irn_dbg_info(sel);
+               irn = new_rd_Cmp(dbg, new_bl, lentry->low_word, rentry->low_word,
+                                ir_relation_less_greater);
                dbg = get_irn_dbg_info(node);
                irn = new_rd_Cond(dbg, new_bl, irn);
 
@@ -1143,7 +1137,8 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
                assert(entry);
                dstF = (ir_node*)entry->value;
 
-               irn = new_r_Proj(cmpH, mode_b, pnc & ~pn_Cmp_Eq);
+               irn = new_rd_Cmp(dbg, block, lentry->high_word, rentry->high_word,
+                                relation & ~ir_relation_equal);
                dbg = get_irn_dbg_info(node);
                irn = new_rd_Cond(dbg, block, irn);
 
@@ -1157,7 +1152,8 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
 
                newbl_eq = new_r_Block(irg, 1, &projHF);
 
-               irn = new_r_Proj(cmpH, mode_b, pn_Cmp_Eq);
+               irn = new_rd_Cmp(dbg, block, lentry->high_word, rentry->high_word,
+                                ir_relation_equal);
                irn = new_rd_Cond(dbg, newbl_eq, irn);
 
                proj = new_r_Proj(irn, mode_X, pn_Cond_false);
@@ -1170,9 +1166,9 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env)
 
                newbl_l = new_r_Block(irg, 1, &proj);
 
-               dbg   = get_irn_dbg_info(cmp);
-               cmpL = new_rd_Cmp(dbg, newbl_l, lentry->low_word, rentry->low_word);
-               irn = new_r_Proj(cmpL, mode_b, pnc);
+               dbg = get_irn_dbg_info(sel);
+               irn = new_rd_Cmp(dbg, newbl_l, lentry->low_word, rentry->low_word,
+                                relation);
                dbg = get_irn_dbg_info(node);
                irn = new_rd_Cond(dbg, newbl_l, irn);
 
@@ -1292,66 +1288,58 @@ static void lower_Conv_from_Ll(ir_node *node, lower_env_t *env)
 }
 
 /**
- * lower boolean Proj(Cmp)
+ * lower Cmp
  */
-static void lower_Proj_Cmp(lower_env_t *env, ir_node *proj)
+static void lower_Cmp(ir_node *cmp, ir_mode *m, lower_env_t *env)
 {
-       ir_node  *cmp  = get_Proj_pred(proj);
        ir_node  *l    = get_Cmp_left(cmp);
        ir_mode  *mode = get_irn_mode(l);
        ir_node  *r, *low, *high, *t, *res;
-       pn_Cmp    pnc;
+       ir_relation relation;
        ir_node  *blk;
        dbg_info *db;
        const node_entry_t *lentry;
        const node_entry_t *rentry;
+       (void) m;
 
        if (mode != env->high_signed && mode != env->high_unsigned) {
                return;
        }
 
-       r      = get_Cmp_right(cmp);
-       lentry = get_node_entry(env, l);
-       rentry = get_node_entry(env, r);
-       pnc    = get_Proj_pn_cmp(proj);
-       blk    = get_nodes_block(cmp);
-       db     = get_irn_dbg_info(cmp);
-       low    = new_rd_Cmp(db, blk, lentry->low_word, rentry->low_word);
-       high   = new_rd_Cmp(db, blk, lentry->high_word, rentry->high_word);
+       r        = get_Cmp_right(cmp);
+       lentry   = get_node_entry(env, l);
+       rentry   = get_node_entry(env, r);
+       relation = get_Cmp_relation(cmp);
+       blk      = get_nodes_block(cmp);
+       db       = get_irn_dbg_info(cmp);
 
-       if (pnc == pn_Cmp_Eq) {
+       if (relation == ir_relation_equal) {
                /* simple case:a == b <==> a_h == b_h && a_l == b_l */
-               res = new_rd_And(db, blk,
-                       new_r_Proj(low, mode_b, pnc),
-                       new_r_Proj(high, mode_b, pnc),
-                       mode_b);
-       } else if (pnc == pn_Cmp_Lg) {
+               low  = new_rd_Cmp(db, blk, lentry->low_word, rentry->low_word,
+                                 relation);
+               high = new_rd_Cmp(db, blk, lentry->high_word, rentry->high_word,
+                                 relation);
+               res  = new_rd_And(db, blk, low, high, mode_b);
+       } else if (relation == ir_relation_less_greater) {
                /* simple case:a != b <==> a_h != b_h || a_l != b_l */
-               res = new_rd_Or(db, blk,
-                       new_r_Proj(low, mode_b, pnc),
-                       new_r_Proj(high, mode_b, pnc),
-                       mode_b);
+               low  = new_rd_Cmp(db, blk, lentry->low_word, rentry->low_word,
+                                 relation);
+               high = new_rd_Cmp(db, blk, lentry->high_word, rentry->high_word,
+                                 relation);
+               res = new_rd_Or(db, blk, low, high, mode_b);
        } else {
-               /* a rel b <==> a_h REL b_h || (a_h == b_h && a_l rel b_l) */
-               t = new_rd_And(db, blk,
-                       new_r_Proj(low, mode_b, pnc),
-                       new_r_Proj(high, mode_b, pn_Cmp_Eq),
-                       mode_b);
-               res = new_rd_Or(db, blk,
-                       new_r_Proj(high, mode_b, pnc & ~pn_Cmp_Eq),
-                       t,
-                       mode_b);
-       }
-       exchange(proj, res);
-}
+               low  = new_rd_Cmp(db, blk, lentry->low_word, rentry->low_word,
+                                 relation);
+               high = new_rd_Cmp(db, blk, lentry->high_word, rentry->high_word,
+                                 ir_relation_equal);
 
-static void lower_Proj(ir_node *node, ir_mode *mode, lower_env_t *env)
-{
-       ir_node *pred = get_Proj_pred(node);
-       (void) mode;
-       if (is_Cmp(pred)) {
-               lower_Proj_Cmp(env, node);
+               /* a rel b <==> a_h REL b_h || (a_h == b_h && a_l rel b_l) */
+               ir_node *high1 = new_rd_Cmp(db, blk, lentry->high_word,
+                                           rentry->high_word, relation & ~ir_relation_equal);
+               t = new_rd_And(db, blk, low, high, mode_b);
+               res = new_rd_Or(db, blk, high1, t, mode_b);
        }
+       exchange(cmp, res);
 }
 
 /**
@@ -2348,10 +2336,11 @@ void lower_dw_ops(const lwrdw_param_t *param)
        }
 
        clear_irp_opcodes_generic_func();
+       enter_lower_func(op_ASM,     lower_ASM);
        enter_lower_func(op_Add,     lower_binop);
        enter_lower_func(op_And,     lower_And);
-       enter_lower_func(op_ASM,     lower_ASM);
        enter_lower_func(op_Call,    lower_Call);
+       enter_lower_func(op_Cmp,     lower_Cmp);
        enter_lower_func(op_Cond,    lower_Cond);
        enter_lower_func(op_Const,   lower_Const);
        enter_lower_func(op_Conv,    lower_Conv);
@@ -2364,7 +2353,6 @@ void lower_dw_ops(const lwrdw_param_t *param)
        enter_lower_func(op_Mux,     lower_Mux);
        enter_lower_func(op_Not,     lower_Not);
        enter_lower_func(op_Or,      lower_Or);
-       enter_lower_func(op_Proj,    lower_Proj);
        enter_lower_func(op_Return,  lower_Return);
        enter_lower_func(op_Sel,     lower_Sel);
        enter_lower_func(op_Shl,     lower_Shl);
index 6d48ff6..9495023 100644 (file)
@@ -249,19 +249,18 @@ int i_mapper_abs(ir_node *call, void *ctx)
        ir_mode  *mode     = get_irn_mode(op);
        dbg_info *dbg      = get_irn_dbg_info(call);
        ir_node  *zero     = new_r_Const(irg, get_mode_null(mode));
-       ir_node  *cmp      = new_rd_Cmp(dbg, block, op, zero);
-       ir_node  *cond     = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
+       ir_node  *cmp      = new_rd_Cmp(dbg, block, op, zero, ir_relation_less);
        ir_node  *minus_op = new_rd_Minus(dbg, block, op, mode);
        ir_node  *mux;
        arch_allow_ifconv_func allow_ifconv = be_get_backend_param()->allow_ifconv;
        (void) ctx;
 
        /* mux allowed by backend? */
-       if (!allow_ifconv(cond, op, minus_op))
+       if (!allow_ifconv(cmp, op, minus_op))
                return 0;
 
        /* construct Mux */
-       mux = new_rd_Mux(dbg, block, cond, op, minus_op, mode);
+       mux = new_rd_Mux(dbg, block, cmp, op, minus_op, mode);
        DBG_OPT_ALGSIM0(call, mux, FS_OPT_RTS_ABS);
        replace_call(mux, call, mem, NULL, NULL);
        return 1;
index c541e1f..18916a5 100644 (file)
@@ -272,73 +272,75 @@ static ir_node *lower_node(ir_node *node)
                ir_tarval *tv_zeroc = get_mode_null(mode);
                ir_node   *zero_cmp = new_rd_Const(dbgi, irg, tv_zeroc);
 
-               ir_node *cmp      = new_rd_Cmp(dbgi, block, pred, zero_cmp);
-               ir_node *proj     = new_rd_Proj(dbgi, cmp, mode_b, pn_Cmp_Lg);
-               res = config->create_set(proj);
+               ir_node *cmp      = new_rd_Cmp(dbgi, block, pred, zero_cmp, ir_relation_less_greater);
+               res = config->create_set(cmp);
                break;
        }
 
-       case iro_Proj: {
-               ir_node *pred = get_Proj_pred(node);
-
-               if (is_Cmp(pred)) {
-                       ir_node *left  = get_Cmp_left(pred);
-                       ir_node *right = get_Cmp_right(pred);
-                       ir_mode *cmp_mode  = get_irn_mode(left);
-
-                       if ((mode_is_int(cmp_mode) || mode_is_reference(cmp_mode)) &&
-                           (get_mode_size_bits(cmp_mode) < get_mode_size_bits(mode) ||
-                           (mode_is_signed(cmp_mode) && is_Const(right) && is_Const_null(right)))) {
-                               int        pnc      = get_Proj_proj(node);
-                               int        need_not = 0;
-                               ir_node   *a        = NULL;
-                               ir_node   *b        = NULL;
-                               int        bits;
-                               ir_tarval *tv;
-                               ir_node   *shift_cnt;
-
-                               if (pnc == pn_Cmp_Lt) {
-                                       /* a < b  ->  (a - b) >> 31 */
-                                       a = left;
-                                       b = right;
-                               } else if (pnc == pn_Cmp_Le) {
-                                       /* a <= b  -> ~(a - b) >> 31 */
-                                       a        = right;
-                                       b        = left;
-                                       need_not = 1;
-                               } else if (pnc == pn_Cmp_Gt) {
-                                       /* a > b   -> (b - a) >> 31 */
-                                       a = right;
-                                       b = left;
-                               } else if (pnc == pn_Cmp_Ge) {
-                                       /* a >= b   -> ~(a - b) >> 31 */
-                                       a        = left;
-                                       b        = right;
-                                       need_not = 1;
-                               } else {
-                                       goto synth_zero_one;
-                               }
+       case iro_Cmp: {
+               ir_node *left  = get_Cmp_left(node);
+               ir_node *right = get_Cmp_right(node);
+               ir_mode *cmp_mode  = get_irn_mode(left);
+
+               if ((mode_is_int(cmp_mode) || mode_is_reference(cmp_mode)) &&
+                       (get_mode_size_bits(cmp_mode) < get_mode_size_bits(mode) ||
+                       (mode_is_signed(cmp_mode) && is_Const(right) && is_Const_null(right)))) {
+                       ir_relation relation = get_Cmp_relation(node);
+                       int         need_not = 0;
+                       ir_node    *a        = NULL;
+                       ir_node    *b        = NULL;
+                       int         bits;
+                       ir_tarval  *tv;
+                       ir_node    *shift_cnt;
+
+                       if (relation == ir_relation_less) {
+                               /* a < b  ->  (a - b) >> 31 */
+                               a = left;
+                               b = right;
+                       } else if (relation == ir_relation_less_equal) {
+                               /* a <= b  -> ~(a - b) >> 31 */
+                               a        = right;
+                               b        = left;
+                               need_not = 1;
+                       } else if (relation == ir_relation_greater) {
+                               /* a > b   -> (b - a) >> 31 */
+                               a = right;
+                               b = left;
+                       } else if (relation == ir_relation_greater_equal) {
+                               /* a >= b   -> ~(a - b) >> 31 */
+                               a        = left;
+                               b        = right;
+                               need_not = 1;
+                       } else {
+                               goto synth_zero_one;
+                       }
 
-                               bits      = get_mode_size_bits(mode);
-                               tv        = new_tarval_from_long(bits-1, mode_Iu);
-                               shift_cnt = new_rd_Const(dbgi, irg, tv);
+                       bits      = get_mode_size_bits(mode);
+                       tv        = new_tarval_from_long(bits-1, mode_Iu);
+                       shift_cnt = new_rd_Const(dbgi, irg, tv);
 
-                               if (cmp_mode != mode) {
-                                       a = new_rd_Conv(dbgi, block, a, mode);
-                                       b = new_rd_Conv(dbgi, block, b, mode);
-                               }
+                       if (cmp_mode != mode) {
+                               a = new_rd_Conv(dbgi, block, a, mode);
+                               b = new_rd_Conv(dbgi, block, b, mode);
+                       }
 
-                               res = new_rd_Sub(dbgi, block, a, b, mode);
-                               if (need_not) {
-                                       res = new_rd_Not(dbgi, block, res, mode);
-                               }
-                               res = new_rd_Shr(dbgi, block, res, shift_cnt, mode);
-                       } else {
-                               /* synthesize the 0/1 value */
-synth_zero_one:
-                               res = config->create_set(node);
+                       res = new_rd_Sub(dbgi, block, a, b, mode);
+                       if (need_not) {
+                               res = new_rd_Not(dbgi, block, res, mode);
                        }
-               } else if (is_Proj(pred) && is_Call(get_Proj_pred(pred))) {
+                       res = new_rd_Shr(dbgi, block, res, shift_cnt, mode);
+               } else {
+                       /* synthesize the 0/1 value */
+synth_zero_one:
+                       res = config->create_set(node);
+               }
+               break;
+       }
+
+       case iro_Proj: {
+               ir_node *pred = get_Proj_pred(node);
+
+               if (is_Proj(pred) && is_Call(get_Proj_pred(pred))) {
                        ir_type *type = get_Call_type(get_Proj_pred(pred));
                        adjust_method_type(type);
                        set_irn_mode(node, mode);
@@ -399,15 +401,13 @@ static void lower_mode_b_walker(ir_node *node, void *env)
                        continue;
 
                if (! config->lower_direct_cmp) {
-                       /* Proj(Cmp) as input for Cond and Mux nodes needs no changes.
+                       /* Cmp as input for Cond and Mux nodes needs no changes.
                           (Mux with mode_b is an exception as it gets replaced by and/or
                            anyway so we still lower the inputs then) */
                        if (is_Cond(node) ||
                            (is_Mux(node) && get_irn_mode(node) != mode_b)) {
-                               if (is_Proj(in)) {
-                                       ir_node *pred = get_Proj_pred(in);
-                                       if (is_Cmp(pred))
-                                               continue;
+                               if (is_Cmp(in)) {
+                                       continue;
                                }
                        }
                }
index 8235df9..9284492 100644 (file)
@@ -143,9 +143,9 @@ static void create_if_cascade(cond_env_t *env, dbg_info *dbgi, ir_node *block,
        } else if (numcases == 1) {
                /* only one case: "if (sel == val) goto target else goto default;" */
                ir_node *val       = new_r_Const_long(irg, cmp_mode, curcases[0].value);
-               ir_node *cmp       = new_rd_Cmp(dbgi, block, cmp_sel, val);
-               ir_node *proj      = new_r_Proj(cmp, mode_b, pn_Cmp_Eq);
-               ir_node *cond      = new_rd_Cond(dbgi, block, proj);
+               ir_node *cmp       = new_rd_Cmp(dbgi, block, cmp_sel, val,
+                                               ir_relation_equal);
+               ir_node *cond      = new_rd_Cond(dbgi, block, cmp);
                ir_node *trueproj  = new_r_Proj(cond, mode_X, pn_Cond_true);
                ir_node *falseproj = new_r_Proj(cond, mode_X, pn_Cond_false);
 
@@ -154,9 +154,9 @@ static void create_if_cascade(cond_env_t *env, dbg_info *dbgi, ir_node *block,
        } else if (numcases == 2) {
                /* only two cases: "if (sel == val[0]) goto target[0];" */
                ir_node *val       = new_r_Const_long(irg, cmp_mode, curcases[0].value);
-               ir_node *cmp       = new_rd_Cmp(dbgi, block, cmp_sel, val);
-               ir_node *proj      = new_r_Proj(cmp, mode_b, pn_Cmp_Eq);
-               ir_node *cond      = new_rd_Cond(dbgi, block, proj);
+               ir_node *cmp       = new_rd_Cmp(dbgi, block, cmp_sel, val,
+                                               ir_relation_equal);
+               ir_node *cond      = new_rd_Cond(dbgi, block, cmp);
                ir_node *trueproj  = new_r_Proj(cond, mode_X, pn_Cond_true);
                ir_node *falseproj = new_r_Proj(cond, mode_X, pn_Cond_false);
                ir_node *in[1];
@@ -169,9 +169,8 @@ static void create_if_cascade(cond_env_t *env, dbg_info *dbgi, ir_node *block,
 
                /* second part: "else if (sel == val[1]) goto target[1] else goto default;" */
                val       = new_r_Const_long(irg, cmp_mode, curcases[1].value);
-               cmp       = new_rd_Cmp(dbgi, neblock, cmp_sel, val);
-               proj      = new_r_Proj(cmp, mode_b, pn_Cmp_Eq);
-               cond      = new_rd_Cond(dbgi, neblock, proj);
+               cmp       = new_rd_Cmp(dbgi, neblock, cmp_sel, val, ir_relation_equal);
+               cond      = new_rd_Cond(dbgi, neblock, cmp);
                trueproj  = new_r_Proj(cond, mode_X, pn_Cond_true);
                falseproj = new_r_Proj(cond, mode_X, pn_Cond_false);
                set_Block_cfgpred(curcases[1].target, 0, trueproj);
@@ -181,9 +180,8 @@ static void create_if_cascade(cond_env_t *env, dbg_info *dbgi, ir_node *block,
                int midcase = numcases / 2;
                ir_node *val  = new_r_Const_long(irg, cmp_mode,
                                                 curcases[midcase].value);
-               ir_node *cmp  = new_rd_Cmp(dbgi, block, cmp_sel, val);
-               ir_node *proj = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
-               ir_node *cond = new_rd_Cond(dbgi, block, proj);
+               ir_node *cmp  = new_rd_Cmp(dbgi, block, cmp_sel, val, ir_relation_less);
+               ir_node *cond = new_rd_Cond(dbgi, block, cmp);
                ir_node *in[1];
                ir_node *ltblock;
                ir_node *geblock;
@@ -214,7 +212,6 @@ static void create_out_of_bounds_check(cond_env_t *env, ir_node *cond)
        ir_node       *proj_true;
        ir_node       *proj_false;
        ir_node       *cmp;
-       ir_node       *proj_cmp;
        ir_node       *oob_cond;
        ir_node       *in[1];
        ir_node       *new_block;
@@ -240,9 +237,8 @@ static void create_out_of_bounds_check(cond_env_t *env, ir_node *cond)
 
        /* check for out-of-bounds */
        max_const  = new_r_Const_long(irg, cmp_mode, env->switch_max);
-       cmp        = new_rd_Cmp(dbgi, block, sel, max_const);
-       proj_cmp   = new_r_Proj(cmp, mode_b, pn_Cmp_Le);
-       oob_cond   = new_rd_Cond(dbgi, block, proj_cmp);
+       cmp        = new_rd_Cmp(dbgi, block, sel, max_const, ir_relation_less);
+       oob_cond   = new_rd_Cond(dbgi, block, cmp);
        proj_true  = new_r_Proj(oob_cond, mode_X, pn_Cond_true);
        proj_false = new_r_Proj(oob_cond, mode_X, pn_Cond_false);
 
index eaae5a3..fa2d2b7 100644 (file)
 #include "irpass.h"
 #include "debug.h"
 
-/** Describes a pair of relative conditions lo < hi, lo pnc_lo x, hi pnc_hi x */
+/** Describes a pair of relative conditions lo < hi, lo rel_lo x, hi rel_hi x */
 typedef struct cond_pair {
-       ir_node   *cmp_lo;  /**< The lo compare node. */
-       ir_node   *cmp_hi;  /**< The hi compare node. */
-       pn_Cmp     pnc_lo;  /**< The lo relation node. */
-       pn_Cmp     pnc_hi;  /**< The hi relation node. */
-       ir_node   *proj_lo; /**< The mode_b result proj of cmp_lo. */
-       ir_node   *proj_hi; /**< The mode_b result proj of cmp_hi. */
-       ir_tarval *tv_lo;   /**< The tarval of cmp_lo node. */
-       ir_tarval *tv_hi;   /**< The tarval of cmp_hi node. */
-       ir_mode   *lo_mode; /**< The mode of the cmp_lo operands. */
+       ir_node    *cmp_lo;  /**< The lo compare node. */
+       ir_node    *cmp_hi;  /**< The hi compare node. */
+       ir_relation rel_lo;  /**< The lo relation node. */
+       ir_relation rel_hi;  /**< The hi relation node. */
+       ir_tarval  *tv_lo;   /**< The tarval of cmp_lo node. */
+       ir_tarval  *tv_hi;   /**< The tarval of cmp_hi node. */
+       ir_mode    *lo_mode; /**< The mode of the cmp_lo operands. */
 } cond_pair;
 
 /** Environment for all walker in boolopt. */
@@ -64,95 +62,83 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg);
  * Check if tho given nodes, l and r, represent two compares with
  * ... . If yes, return non-zero and fill the res struct.
  */
-static int find_cond_pair(ir_node *const l, ir_node *const r, cond_pair *const res)
+static bool find_cond_pair(ir_node *const l, ir_node *const r, cond_pair *const res)
 {
-       if (is_Proj(l) && is_Proj(r)) {
-               ir_node *const lo = get_Proj_pred(l);
-               ir_node *const ro = get_Proj_pred(r);
-
-               if (is_Cmp(lo) && is_Cmp(ro)) {
-                       ir_node *const lol   = get_Cmp_left(lo);
-                       ir_node *const lor   = get_Cmp_right(lo);
-                       ir_node *const rol   = get_Cmp_left(ro);
-                       ir_node *const ror   = get_Cmp_right(ro);
-                       pn_Cmp   const pnc_l = get_Proj_pn_cmp(l);
-                       pn_Cmp   const pnc_r = get_Proj_pn_cmp(r);
-
-                       if (is_Const(lor) && is_Const_null(lor) &&
-                           is_Const(ror) && is_Const_null(ror) &&
-                           pnc_l == pnc_r &&
-                           (pnc_l == pn_Cmp_Lg || pnc_l == pn_Cmp_Eq)) {
-                               /* lo == (lol !=|== NULL) && ro == (rol !=|== NULL) */
-                               res->cmp_lo  = lo;
-                               res->cmp_hi  = ro;
-                               res->pnc_lo  = pnc_l;
-                               res->pnc_hi  = pnc_l;
-                               res->proj_lo = l;
-                               res->proj_hi = r;
-                               res->tv_lo   = get_Const_tarval(lor);
-                               res->tv_hi   = get_Const_tarval(ror);
-                               res->lo_mode = get_irn_mode(lor);
-
-                               return 1;
-                       }
+       if (!is_Cmp(l) || !is_Cmp(r))
+               return false;
+
+       ir_node    *const lol   = get_Cmp_left(l);
+       ir_node    *const lor   = get_Cmp_right(l);
+       ir_node    *const rol   = get_Cmp_left(r);
+       ir_node    *const ror   = get_Cmp_right(r);
+       ir_relation const pnc_l = get_Cmp_relation(l);
+       ir_relation const pnc_r = get_Cmp_relation(r);
+
+       if (is_Const(lor) && is_Const_null(lor) &&
+               is_Const(ror) && is_Const_null(ror) &&
+               pnc_l == pnc_r &&
+               (pnc_l == ir_relation_less_greater || pnc_l == ir_relation_equal)) {
+               /* l == (lol !=|== NULL) && r == (rol !=|== NULL) */
+               res->cmp_lo  = l;
+               res->cmp_hi  = r;
+               res->rel_lo  = pnc_l;
+               res->rel_hi  = pnc_l;
+               res->tv_lo   = get_Const_tarval(lor);
+               res->tv_hi   = get_Const_tarval(ror);
+               res->lo_mode = get_irn_mode(lor);
+
+               return true;
+       }
 
-                       if (lol == rol && lor != ror && is_Const(lor) && is_Const(ror)) {
-                               /* lo == (x CMP c_l), ro == (x cmp c_r) */
-                               ir_tarval *const tv_l  = get_Const_tarval(lor);
-                               ir_tarval *const tv_r  = get_Const_tarval(ror);
-                               pn_Cmp     const rel   = tarval_cmp(tv_l, tv_r);
-
-                               res->lo_mode = get_irn_mode(lol);
-
-                               if (rel == pn_Cmp_Lt) {
-                                       /* c_l < c_r */
-                                       res->cmp_lo  = lo;
-                                       res->cmp_hi  = ro;
-                                       res->pnc_lo  = pnc_l;
-                                       res->pnc_hi  = pnc_r;
-                                       res->proj_lo = l;
-                                       res->proj_hi = r;
-                                       res->tv_lo   = tv_l;
-                                       res->tv_hi   = tv_r;
-                               } else if (rel == pn_Cmp_Gt) {
-                                       /* c_l > c_r */
-                                       res->cmp_lo  = ro;
-                                       res->cmp_hi  = lo;
-                                       res->pnc_lo  = pnc_r;
-                                       res->pnc_hi  = pnc_l;
-                                       res->proj_lo = r;
-                                       res->proj_hi = l;
-                                       res->tv_lo   = tv_r;
-                                       res->tv_hi   = tv_l;
-                               } else {
-                                       /* The constants shall be unequal but comparable.
-                                        * Local optimizations handle the equal case. */
-                                       return 0;
-                               }
-                               return 1;
-                       }
+       if (lol == rol && lor != ror && is_Const(lor) && is_Const(ror)) {
+               /* l == (x CMP c_l), r == (x cmp c_r) */
+               ir_tarval  *const tv_l  = get_Const_tarval(lor);
+               ir_tarval  *const tv_r  = get_Const_tarval(ror);
+               ir_relation const rel   = tarval_cmp(tv_l, tv_r);
+
+               res->lo_mode = get_irn_mode(lol);
+
+               if (rel == ir_relation_less) {
+                       /* c_l < c_r */
+                       res->cmp_lo  = l;
+                       res->cmp_hi  = r;
+                       res->rel_lo  = pnc_l;
+                       res->rel_hi  = pnc_r;
+                       res->tv_lo   = tv_l;
+                       res->tv_hi   = tv_r;
+               } else if (rel == ir_relation_greater) {
+                       /* c_l > c_r */
+                       res->cmp_lo  = r;
+                       res->cmp_hi  = l;
+                       res->rel_lo  = pnc_r;
+                       res->rel_hi  = pnc_l;
+                       res->tv_lo   = tv_r;
+                       res->tv_hi   = tv_l;
+               } else {
+                       /* The constants shall be unequal but comparable.
+                        * Local optimizations handle the equal case. */
+                       return false;
                }
+               return true;
        }
-       return 0;
+       return false;
 }
 
 /**
- * Handle (lo pnc_lo x) AND (hi pnc_hi x)
+ * Handle (lo rel_lo x) AND (hi rel_hi x)
  */
 static ir_node *bool_and(cond_pair* const cpair, ir_node *dst_block)
 {
        ir_node    *const cmp_lo  = cpair->cmp_lo;
        ir_node    *const cmp_hi  = cpair->cmp_hi;
-       pn_Cmp            pnc_lo  = cpair->pnc_lo;
-       pn_Cmp      const pnc_hi  = cpair->pnc_hi;
-       ir_node    *const proj_lo = cpair->proj_lo;
-       ir_node    *const proj_hi = cpair->proj_hi;
+       ir_relation       rel_lo  = cpair->rel_lo;
+       ir_relation const rel_hi  = cpair->rel_hi;
        ir_tarval  *      tv_lo   = cpair->tv_lo;
        ir_tarval  *      tv_hi   = cpair->tv_hi;
        ir_mode    *      mode    = cpair->lo_mode;
        ir_graph   *      irg     = get_irn_irg(cmp_lo);
 
-       if (pnc_lo == pn_Cmp_Eq && pnc_hi == pn_Cmp_Eq &&
+       if (rel_lo == ir_relation_equal && rel_hi == rel_lo &&
            tarval_is_null(tv_lo) && tarval_is_null(tv_hi) &&
            mode == get_tarval_mode(tv_hi)) {
                /* p == NULL && q == NULL ==> (p&q) == NULL) */
@@ -173,9 +159,8 @@ static ir_node *bool_and(cond_pair* const cpair, ir_node *dst_block)
                        hil   = new_r_Conv(dst_block, hil, mode);
                        p     = new_r_And(dst_block, lol, hil, mode);
                        c     = new_r_Const(irg, tv_lo);
-                       cmp   = new_r_Cmp(dst_block, p, c);
-                       p     = new_r_Proj(cmp, mode_b, pn_Cmp_Eq);
-                       return p;
+                       cmp   = new_r_Cmp(dst_block, p, c, ir_relation_equal);
+                       return cmp;
                }
        }
 
@@ -188,64 +173,64 @@ static ir_node *bool_and(cond_pair* const cpair, ir_node *dst_block)
                return 0;
 
        /* Beware of NaN's, we can only check for (ordered) != here (which is Lg, not Ne) */
-       if ((pnc_lo == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le || pnc_lo == pn_Cmp_Eq) &&
-           (pnc_hi == pn_Cmp_Eq || pnc_hi == pn_Cmp_Ge || pnc_hi == pn_Cmp_Gt)) {
+       if ((rel_lo == ir_relation_less || rel_lo == ir_relation_less_equal || rel_lo == ir_relation_equal) &&
+           (rel_hi == ir_relation_equal || rel_hi == ir_relation_greater_equal || rel_hi == ir_relation_greater)) {
                /* x <|<=|== lo && x ==|>=|> hi ==> false */
                ir_node *const t = new_r_Const(irg, tarval_b_false);
                return t;
-       } else if ((pnc_lo == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le || pnc_lo == pn_Cmp_Eq) &&
-                  (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Lg)) {
+       } else if ((rel_lo == ir_relation_less || rel_lo == ir_relation_less_equal || rel_lo == ir_relation_equal) &&
+                  (rel_hi == ir_relation_less || rel_hi == ir_relation_less_equal || rel_hi == ir_relation_less_greater)) {
                /* x <|<=|== lo && x <|<=|!= hi ==> x <|<=|== lo */
-               return proj_lo;
-       } else if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Lg) &&
-                  (pnc_hi == pn_Cmp_Eq || pnc_hi == pn_Cmp_Ge || pnc_hi == pn_Cmp_Gt)) {
+               return cmp_lo;
+       } else if ((rel_lo == ir_relation_greater_equal || rel_lo == ir_relation_greater || rel_lo == ir_relation_less_greater) &&
+                  (rel_hi == ir_relation_equal || rel_hi == ir_relation_greater_equal || rel_hi == ir_relation_greater)) {
                /* x >=|>|!= lo && x ==|>=|> hi ==> x ==|>=|> hi */
-               return proj_hi;
+               return cmp_hi;
        } else if (tarval_is_one(tarval_sub(tv_hi, tv_lo, NULL))) { /* lo + 1 == hi */
-               if (pnc_lo == pn_Cmp_Ge && pnc_hi == pn_Cmp_Lt) {
+               if (rel_lo == ir_relation_greater_equal && rel_hi == ir_relation_less) {
                        /* x >= c && x < c + 1 ==> x == c */
-                       ir_node  *const p = new_r_Proj(cmp_lo, mode_b, pn_Cmp_Eq);
+                       ir_node  *const p = new_r_Proj(cmp_lo, mode_b, ir_relation_equal);
                        return p;
-               } else if (pnc_lo == pn_Cmp_Gt) {
-                       if (pnc_hi == pn_Cmp_Lg) {
+               } else if (rel_lo == ir_relation_greater) {
+                       if (rel_hi == ir_relation_less_greater) {
                                /* x > c && x != c + 1 ==> x > c + 1 */
-                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, pn_Cmp_Gt);
+                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, ir_relation_greater);
                                return p;
-                       } else if (pnc_hi == pn_Cmp_Lt) {
+                       } else if (rel_hi == ir_relation_less) {
                                /* x > c && x < c + 1 ==> false */
                                ir_node *const t = new_r_Const(irg, tarval_b_false);
                                return t;
-                       } else if (pnc_hi == pn_Cmp_Le) {
+                       } else if (rel_hi == ir_relation_less_equal) {
                                /* x > c && x <= c + 1 ==> x != c + 1 */
-                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, pn_Cmp_Eq);
+                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, ir_relation_equal);
                                return p;
                        }
-               } else if (pnc_lo == pn_Cmp_Lg && pnc_hi == pn_Cmp_Lt) {
+               } else if (rel_lo == ir_relation_less_greater && rel_hi == ir_relation_less) {
                        /* x != c && c < c + 1 ==> x < c */
-                       ir_node  *const p     = new_r_Proj(cmp_lo, mode_b, pn_Cmp_Lt);
+                       ir_node  *const p     = new_r_Proj(cmp_lo, mode_b, ir_relation_less);
                        return p;
                }
-       } else if ((pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Ge) &&
-                  (pnc_hi == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le) &&
+       } else if ((rel_lo == ir_relation_greater || rel_lo == ir_relation_greater_equal) &&
+                  (rel_hi == ir_relation_less || rel_lo == ir_relation_less_equal) &&
                   get_mode_arithmetic(mode) == irma_twos_complement) {
                /* works for two-complements only */
                /* x >|\= lo && x <|<= hi ==> (x - lo) <u|<=u (hi-lo) */
-               if (pnc_lo == pn_Cmp_Gt) {
+               if (rel_lo == ir_relation_greater) {
                        /* must convert to >= */
                        ir_mode   *mode = get_tarval_mode(tv_lo);
                        ir_tarval *n    = tarval_add(tv_lo, get_mode_one(mode));
-                       if (n != tarval_bad && tarval_cmp(n, tv_lo) == pn_Cmp_Gt) {
+                       if (n != tarval_bad && tarval_cmp(n, tv_lo) == ir_relation_greater) {
                                /* no overflow */
                                tv_lo = n;
-                               pnc_lo = pn_Cmp_Ge;
+                               rel_lo = ir_relation_greater_equal;
                        }
                }
-               if (pnc_lo == pn_Cmp_Ge) {
+               if (rel_lo == ir_relation_greater_equal) {
                        /* all fine */
                        ir_node *const block = get_nodes_block(cmp_hi);
                        ir_node *      x     = get_Cmp_left(cmp_hi);
                        ir_mode *      mode  = get_irn_mode(x);
-                       ir_node *sub, *cmp, *c, *subc, *p;
+                       ir_node *sub, *cmp, *c, *subc;
 
                        if (mode_is_signed(mode)) {
                                /* convert to unsigned */
@@ -261,31 +246,28 @@ static ir_node *bool_and(cond_pair* const cpair, ir_node *dst_block)
                        c    = new_r_Const(irg, tv_lo);
                        sub  = new_r_Sub(block, x, c, mode);
                        subc = new_r_Sub(block, new_r_Const(irg, tv_hi), c, mode);
-                       cmp  = new_r_Cmp(block, sub, subc);
-                       p    = new_r_Proj(cmp, mode_b, pnc_hi);
-                       return p;
+                       cmp  = new_r_Cmp(block, sub, subc, rel_hi);
+                       return cmp;
                }
        }
        return NULL;
 }
 
 /**
- * Handle (lo pnc_lo x) OR (hi pnc_hi x)
+ * Handle (lo rel_lo x) OR (hi rel_hi x)
  */
 static ir_node *bool_or(cond_pair *const cpair, ir_node *dst_block)
 {
-       ir_node   *const cmp_lo  = cpair->cmp_lo;
-       ir_node   *const cmp_hi  = cpair->cmp_hi;
-       pn_Cmp           pnc_lo  = cpair->pnc_lo;
-       pn_Cmp     const pnc_hi  = cpair->pnc_hi;
-       ir_node   *const proj_lo = cpair->proj_lo;
-       ir_node   *const proj_hi = cpair->proj_hi;
-       ir_tarval *      tv_lo   = cpair->tv_lo;
-       ir_tarval *      tv_hi   = cpair->tv_hi;
-       ir_mode   *      mode    = cpair->lo_mode;
-       ir_graph  *      irg     = get_irn_irg(cmp_lo);
-
-       if (pnc_lo == pn_Cmp_Lg && pnc_hi == pn_Cmp_Lg &&
+       ir_node    *const cmp_lo  = cpair->cmp_lo;
+       ir_node    *const cmp_hi  = cpair->cmp_hi;
+       ir_relation       rel_lo  = cpair->rel_lo;
+       ir_relation const rel_hi  = cpair->rel_hi;
+       ir_tarval  *      tv_lo   = cpair->tv_lo;
+       ir_tarval  *      tv_hi   = cpair->tv_hi;
+       ir_mode    *      mode    = cpair->lo_mode;
+       ir_graph   *      irg     = get_irn_irg(cmp_lo);
+
+       if (rel_lo == ir_relation_less_greater && rel_hi == ir_relation_less_greater &&
                tarval_is_null(tv_lo) && tarval_is_null(tv_hi) &&
                mode == get_tarval_mode(tv_hi)) {
                /* p != NULL || q != NULL ==> (p|q) != NULL) */
@@ -306,9 +288,8 @@ static ir_node *bool_or(cond_pair *const cpair, ir_node *dst_block)
                        hil   = new_r_Conv(dst_block, hil, mode);
                        p     = new_r_Or(dst_block, lol, hil, mode);
                        c     = new_r_Const(irg, tv_lo);
-                       cmp   = new_r_Cmp(dst_block, p, c);
-                       p     = new_r_Proj(cmp, mode_b, pn_Cmp_Lg);
-                       return p;
+                       cmp   = new_r_Cmp(dst_block, p, c, ir_relation_less_greater);
+                       return cmp;
                }
        }
 
@@ -321,64 +302,64 @@ static ir_node *bool_or(cond_pair *const cpair, ir_node *dst_block)
                return 0;
 
        /* Beware of NaN's, we can only check for (ordered) != here (which is Lg, not Ne) */
-       if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Lg) &&
-           (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Lg)) {
+       if ((rel_lo == ir_relation_greater_equal || rel_lo == ir_relation_greater || rel_lo == ir_relation_less_greater) &&
+           (rel_hi == ir_relation_less || rel_hi == ir_relation_less_equal || rel_hi == ir_relation_less_greater)) {
                /* x >=|>|!= lo | x <|<=|!= hi ==> true */
                ir_node *const t = new_r_Const(irg, tarval_b_true);
                return t;
-       } else if ((pnc_lo == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le || pnc_lo == pn_Cmp_Eq) &&
-                  (pnc_hi == pn_Cmp_Lt || pnc_hi == pn_Cmp_Le || pnc_hi == pn_Cmp_Lg)) {
+       } else if ((rel_lo == ir_relation_less || rel_lo == ir_relation_less_equal || rel_lo == ir_relation_equal) &&
+                  (rel_hi == ir_relation_less || rel_hi == ir_relation_less_equal || rel_hi == ir_relation_less_greater)) {
                /* x <|<=|== lo || x <|<=|!= hi ==> x <|<=|!= hi */
-               return proj_hi;
-       } else if ((pnc_lo == pn_Cmp_Ge || pnc_lo == pn_Cmp_Gt || pnc_lo == pn_Cmp_Lg) &&
-                  (pnc_hi == pn_Cmp_Eq || pnc_hi == pn_Cmp_Ge || pnc_hi == pn_Cmp_Gt)) {
+               return cmp_hi;
+       } else if ((rel_lo == ir_relation_greater_equal || rel_lo == ir_relation_greater || rel_lo == ir_relation_less_greater) &&
+                  (rel_hi == ir_relation_equal || rel_hi == ir_relation_greater_equal || rel_hi == ir_relation_greater)) {
                /* x >=|>|!= lo || x ==|>=|> hi ==> x >=|>|!= lo */
-               return proj_lo;
+               return cmp_lo;
        } else if (tarval_is_one(tarval_sub(tv_hi, tv_lo, NULL))) { /* lo + 1 == hi */
-               if (pnc_lo == pn_Cmp_Lt && pnc_hi == pn_Cmp_Ge) {
+               if (rel_lo == ir_relation_less && rel_hi == ir_relation_greater_equal) {
                        /* x < c || x >= c + 1 ==> x != c */
-                       ir_node  *const p = new_r_Proj(cmp_lo, mode_b, pn_Cmp_Lg);
+                       ir_node  *const p = new_r_Proj(cmp_lo, mode_b, ir_relation_less_greater);
                        return p;
-               } else if (pnc_lo == pn_Cmp_Le) {
-                       if (pnc_hi == pn_Cmp_Eq) {
+               } else if (rel_lo == ir_relation_less_equal) {
+                       if (rel_hi == ir_relation_equal) {
                                /* x <= c || x == c + 1 ==> x <= c + 1 */
-                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, pn_Cmp_Le);
+                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, ir_relation_less_equal);
                                return p;
-                       } else if (pnc_hi == pn_Cmp_Ge) {
+                       } else if (rel_hi == ir_relation_greater_equal) {
                                /* x <= c || x >= c + 1 ==> true */
                                ir_node *const t = new_r_Const(irg, tarval_b_true);
                                return t;
-                       } else if (pnc_hi == pn_Cmp_Gt) {
+                       } else if (rel_hi == ir_relation_greater) {
                                /* x <= c || x > c + 1 ==> x != c + 1 */
-                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, pn_Cmp_Lg);
+                               ir_node  *const p = new_r_Proj(cmp_hi, mode_b, ir_relation_less_greater);
                                return p;
                        }
-               } else if (pnc_lo == pn_Cmp_Eq && pnc_hi == pn_Cmp_Ge) {
+               } else if (rel_lo == ir_relation_equal && rel_hi == ir_relation_greater_equal) {
                        /* x == c || x >= c + 1 ==> x >= c */
-                       ir_node  *const p     = new_r_Proj(cmp_lo, mode_b, pn_Cmp_Ge);
+                       ir_node  *const p     = new_r_Proj(cmp_lo, mode_b, ir_relation_greater_equal);
                        return p;
                }
-       } else if ((pnc_lo == pn_Cmp_Lt || pnc_lo == pn_Cmp_Le) &&
-                  (pnc_hi == pn_Cmp_Gt || pnc_lo == pn_Cmp_Ge) &&
+       } else if ((rel_lo == ir_relation_less || rel_lo == ir_relation_less_equal) &&
+                  (rel_hi == ir_relation_greater || rel_lo == ir_relation_greater_equal) &&
                   get_mode_arithmetic(mode) == irma_twos_complement) {
                /* works for two-complements only */
                /* x <|<= lo  || x >|>= hi ==> (x - lo) >u|>=u (hi-lo) */
-               if (pnc_lo == pn_Cmp_Le) {
+               if (rel_lo == ir_relation_less_equal) {
                        /* must convert to < */
                        ir_mode   *mode = get_tarval_mode(tv_lo);
                        ir_tarval *n    = tarval_add(tv_lo, get_mode_one(mode));
-                       if (n != tarval_bad && tarval_cmp(n, tv_lo) == pn_Cmp_Gt) {
+                       if (n != tarval_bad && tarval_cmp(n, tv_lo) == ir_relation_greater) {
                                /* no overflow */
                                tv_lo = n;
-                               pnc_lo = pn_Cmp_Lt;
+                               rel_lo = ir_relation_less;
                        }
                }
-               if (pnc_lo == pn_Cmp_Lt) {
+               if (rel_lo == ir_relation_less) {
                        /* all fine */
                        ir_node *const block = get_nodes_block(cmp_hi);
                        ir_node *      x     = get_Cmp_left(cmp_hi);
                        ir_mode *      mode  = get_irn_mode(x);
-                       ir_node *sub, *cmp, *c, *subc, *p;
+                       ir_node *sub, *cmp, *c, *subc;
 
                        if (mode_is_signed(mode)) {
                                /* convert to unsigned */
@@ -394,9 +375,8 @@ static ir_node *bool_or(cond_pair *const cpair, ir_node *dst_block)
                        c    = new_r_Const(irg, tv_lo);
                        sub  = new_r_Sub(block, x, c, mode);
                        subc = new_r_Sub(block, new_r_Const(irg, tv_hi), c, mode);
-                       cmp  = new_r_Cmp(block, sub, subc);
-                       p    = new_r_Proj(cmp, mode_b, pnc_hi);
-                       return p;
+                       cmp  = new_r_Cmp(block, sub, subc, rel_hi);
+                       return cmp;
                }
        }
        return NULL;
@@ -581,7 +561,7 @@ static void move_nodes_to_block(ir_node *jmp, ir_node *to_block)
  *          \      |
  *            block
  *
- * try to convert it into a (x pnc_lo c_lo) || (x pnc_hi c_hi)
+ * try to convert it into a (x rel_lo c_lo) || (x rel_hi c_hi)
  * and optimize.
  */
 static void find_cf_and_or_walker(ir_node *block, void *ctx)
@@ -639,8 +619,8 @@ restart:
                        ir_node   *replacement;
                        cond_pair  cpair;
 
-                       upper_cf    = get_Block_cfgpred(block, up_idx);
-                       upper_cf    = skip_empty_blocks(upper_cf);
+                       upper_cf = get_Block_cfgpred(block, up_idx);
+                       upper_cf = skip_empty_blocks(upper_cf);
                        if (is_Bad(upper_cf))
                                continue;
                        upper_block = get_nodes_block(upper_cf);
@@ -669,31 +649,39 @@ restart:
                        /* normalize pncs: we need the true case to jump into the
                         * common block (ie. conjunctive normal form) */
                        if (get_Proj_proj(lower_cf) == pn_Cond_false) {
-                               if (cpair.proj_lo == cond_selector) {
-                                       ir_mode *mode  = get_tarval_mode(cpair.tv_lo);
-                                       ir_node *cmp   = get_Proj_pred(cpair.proj_lo);
-                                       cpair.pnc_lo   = get_negated_pnc(cpair.pnc_lo, mode);
-                                       cpair.proj_lo  = new_r_Proj(cmp, mode_b, cpair.pnc_lo);
+                               if (cpair.cmp_lo == cond_selector) {
+                                       ir_node  *cmp   = cpair.cmp_lo;
+                                       ir_node  *block = get_nodes_block(cmp);
+                                       dbg_info *dbgi  = get_irn_dbg_info(cmp);
+                                       cpair.rel_lo    = get_negated_relation(cpair.rel_lo);
+                                       cpair.cmp_lo    = new_rd_Cmp(dbgi, block,
+                                                       get_Cmp_left(cmp), get_Cmp_right(cmp), cpair.rel_lo);
                                } else {
-                                       ir_mode *mode  = get_tarval_mode(cpair.tv_hi);
-                                       ir_node *cmp   = get_Proj_pred(cpair.proj_hi);
-                                       assert(cpair.proj_hi == cond_selector);
-                                       cpair.pnc_hi   = get_negated_pnc(cpair.pnc_hi, mode);
-                                       cpair.proj_hi  = new_r_Proj(cmp, mode_b, cpair.pnc_hi);
+                                       ir_node  *cmp   = cpair.cmp_hi;
+                                       ir_node  *block = get_nodes_block(cmp);
+                                       dbg_info *dbgi  = get_irn_dbg_info(cmp);
+                                       assert(cmp == cond_selector);
+                                       cpair.rel_hi = get_negated_relation(cpair.rel_hi);
+                                       cpair.cmp_hi = new_rd_Cmp(dbgi, block,
+                                                       get_Cmp_left(cmp), get_Cmp_right(cmp), cpair.rel_hi);
                                }
                        }
                        if (get_Proj_proj(upper_cf) == pn_Cond_false) {
-                               if (cpair.proj_lo == upper_cond_selector) {
-                                       ir_mode *mode  = get_tarval_mode(cpair.tv_lo);
-                                       ir_node *cmp   = get_Proj_pred(cpair.proj_lo);
-                                       cpair.pnc_lo   = get_negated_pnc(cpair.pnc_lo, mode);
-                                       cpair.proj_lo  = new_r_Proj(cmp, mode_b, cpair.pnc_lo);
+                               if (cpair.cmp_lo == upper_cond_selector) {
+                                       ir_node  *cmp   = cpair.cmp_lo;
+                                       ir_node  *block = get_nodes_block(cmp);
+                                       dbg_info *dbgi  = get_irn_dbg_info(cmp);
+                                       cpair.rel_lo    = get_negated_relation(cpair.rel_lo);
+                                       cpair.cmp_lo    = new_rd_Cmp(dbgi, block,
+                                                       get_Cmp_left(cmp), get_Cmp_right(cmp), cpair.rel_lo);
                                } else {
-                                       ir_mode *mode  = get_tarval_mode(cpair.tv_hi);
-                                       ir_node *cmp   = get_Proj_pred(cpair.proj_hi);
-                                       assert(cpair.proj_hi == upper_cond_selector);
-                                       cpair.pnc_hi   = get_negated_pnc(cpair.pnc_hi, mode);
-                                       cpair.proj_hi  = new_r_Proj(cmp, mode_b, cpair.pnc_hi);
+                                       ir_node  *cmp   = cpair.cmp_hi;
+                                       ir_node  *block = get_nodes_block(cmp);
+                                       dbg_info *dbgi  = get_irn_dbg_info(cmp);
+                                       assert(cmp == upper_cond_selector);
+                                       cpair.rel_hi   = get_negated_relation(cpair.rel_hi);
+                                       cpair.cmp_hi   = new_rd_Cmp(dbgi, block,
+                                                       get_Cmp_left(cmp), get_Cmp_right(cmp), cpair.rel_hi);
                                }
                        }
 
@@ -764,4 +752,4 @@ void opt_bool(ir_graph *const irg)
 ir_graph_pass_t *opt_bool_pass(const char *name)
 {
        return def_graph_pass(name ? name : "opt_bool", opt_bool);
-}  /* opt_bool_pass */
+}
index d48e849..384617c 100644 (file)
@@ -2235,44 +2235,12 @@ static void compute_Eor(node_t *node)
  */
 static void compute_Cmp(node_t *node)
 {
-       ir_node        *cmp  = node->node;
-       node_t         *l    = get_irn_node(get_Cmp_left(cmp));
-       node_t         *r    = get_irn_node(get_Cmp_right(cmp));
-       lattice_elem_t a     = l->type;
-       lattice_elem_t b     = r->type;
-       ir_mode        *mode = get_irn_mode(get_Cmp_left(cmp));
-
-       if (a.tv == tarval_top || b.tv == tarval_top) {
-               node->type.tv = tarval_top;
-       } else if (r->part == l->part) {
-               /* both nodes congruent, we can probably do something */
-               if (mode_is_float(mode)) {
-                       /* beware of NaN's */
-                       node->type.tv = tarval_bottom;
-               } else {
-                       node->type.tv = tarval_b_true;
-               }
-       } else if (is_con(a) && is_con(b)) {
-               node->type.tv = tarval_b_true;
-       } else {
-               node->type.tv = tarval_bottom;
-       }
-}  /* compute_Cmp */
-
-/**
- * (Re-)compute the type for a Proj(Cmp).
- *
- * @param node  the node
- * @param cond  the predecessor Cmp node
- */
-static void compute_Proj_Cmp(node_t *node, ir_node *cmp)
-{
-       ir_node        *proj = node->node;
-       node_t         *l    = get_irn_node(get_Cmp_left(cmp));
-       node_t         *r    = get_irn_node(get_Cmp_right(cmp));
-       lattice_elem_t a     = l->type;
-       lattice_elem_t b     = r->type;
-       pn_Cmp         pnc   = get_Proj_pn_cmp(proj);
+       ir_node        *cmp     = node->node;
+       node_t         *l       = get_irn_node(get_Cmp_left(cmp));
+       node_t         *r       = get_irn_node(get_Cmp_right(cmp));
+       lattice_elem_t a        = l->type;
+       lattice_elem_t b        = r->type;
+       ir_relation    relation = get_Cmp_relation(cmp);
        ir_tarval      *tv;
 
        if (a.tv == tarval_top || b.tv == tarval_top) {
@@ -2287,7 +2255,7 @@ static void compute_Proj_Cmp(node_t *node, ir_node *cmp)
         *  consistent with compute_Cmp, so don't do anything for floats)
         */
        } else if (r->part == l->part && !mode_is_float(get_irn_mode(l->node))) {
-               tv = pnc & pn_Cmp_Eq ? tarval_b_true : tarval_b_false;
+               tv = relation & ir_relation_equal ? tarval_b_true : tarval_b_false;
 
                /* if the node was ONCE evaluated by all constants, but now
                   this breaks AND we get from the argument partitions a different
@@ -2299,7 +2267,7 @@ static void compute_Proj_Cmp(node_t *node, ir_node *cmp)
        } else {
                node->type.tv = tarval_bottom;
        }
-}  /* compute_Proj_Cmp */
+}
 
 /**
  * (Re-)compute the type for a Proj(Cond).
@@ -2469,28 +2437,23 @@ static void compute_Proj(node_t *node)
                /* mode M is always bottom */
                node->type.tv = tarval_bottom;
                return;
+       } else if (mode == mode_X) {
+               /* handle mode_X nodes */
+               switch (get_irn_opcode(pred)) {
+               case iro_Start:
+                       /* the Proj_X from the Start is always reachable.
+                          However this is already handled at the top. */
+                       node->type.tv = tarval_reachable;
+                       return;
+               case iro_Cond:
+                       compute_Proj_Cond(node, pred);
+                       return;
+               default:
+                       break;
+               }
        }
-       if (mode != mode_X) {
-               if (is_Cmp(pred))
-                       compute_Proj_Cmp(node, pred);
-               else
-                       default_compute(node);
-               return;
-       }
-       /* handle mode_X nodes */
 
-       switch (get_irn_opcode(pred)) {
-       case iro_Start:
-               /* the Proj_X from the Start is always reachable.
-                  However this is already handled at the top. */
-               node->type.tv = tarval_reachable;
-               break;
-       case iro_Cond:
-               compute_Proj_Cond(node, pred);
-               break;
-       default:
-               default_compute(node);
-       }
+       default_compute(node);
 }  /* compute_Proj */
 
 /**
@@ -2503,7 +2466,7 @@ static void compute_Confirm(node_t *node)
        ir_node *confirm = node->node;
        node_t  *pred = get_irn_node(get_Confirm_value(confirm));
 
-       if (get_Confirm_cmp(confirm) == pn_Cmp_Eq) {
+       if (get_Confirm_relation(confirm) == ir_relation_equal) {
                node_t *bound = get_irn_node(get_Confirm_bound(confirm));
 
                if (is_con(bound->type)) {
index a3c6abf..08f9d12 100644 (file)
@@ -366,7 +366,7 @@ result_unknown_X:
                                        ir_tarval* const lzn = tarval_or(lz, tarval_neg(lz));
                                        ir_tarval* const rzn = tarval_or(rz, tarval_neg(rz));
                                        // Concatenate safe lower zeroes.
-                                       if (tarval_cmp(lzn, rzn) == pn_Cmp_Lt) {
+                                       if (tarval_cmp(lzn, rzn) == ir_relation_less) {
                                                z = tarval_mul(tarval_eor(lzn, tarval_shl(lzn, get_tarval_one(m))), rzn);
                                        } else {
                                                z = tarval_mul(tarval_eor(rzn, tarval_shl(rzn, get_tarval_one(m))), lzn);
@@ -465,86 +465,81 @@ result_unknown_X:
                                break;
                        }
 
-                       case iro_Proj: {
-                               ir_node* const pred = get_Proj_pred(irn);
-                               if (is_Cmp(pred)) { // TODO generalize
-                                       bitinfo* const l = get_bitinfo(get_Cmp_left(pred));
-                                       bitinfo* const r = get_bitinfo(get_Cmp_right(pred));
-                                       if (l == NULL || r == NULL) {
-                                               goto result_unknown; // Cmp compares something we cannot evaluate.
-                                       } else {
-                                               ir_tarval* const lz = l->z;
-                                               ir_tarval* const lo = l->o;
-                                               ir_tarval* const rz = r->z;
-                                               ir_tarval* const ro = r->o;
-                                               pn_Cmp     const pn = get_Proj_proj(irn);
-                                               switch (pn) {
-                                                       case pn_Cmp_Lg:
-                                                               if (!tarval_is_null(tarval_andnot(ro, lz)) ||
-                                                                               !tarval_is_null(tarval_andnot(lo, rz))) {
-                                                                       // At least one bit differs.
-                                                                       z = o = get_tarval_b_true();
-                                                               } else if (lz == lo && rz == ro && lz == rz) {
-                                                                       z = o = get_tarval_b_false();
-                                                               } else {
-                                                                       goto result_unknown;
-                                                               }
-                                                               break;
-
-                                                       case pn_Cmp_Eq:
-                                                               if (!tarval_is_null(tarval_andnot(ro, lz)) ||
-                                                                               !tarval_is_null(tarval_andnot(lo, rz))) {
-                                                                       // At least one bit differs.
-                                                                       z = o = get_tarval_b_false();
-                                                               } else if (lz == lo && rz == ro && lz == rz) {
-                                                                       z = o = get_tarval_b_true();
-                                                               } else {
-                                                                       goto result_unknown;
-                                                               }
-                                                               break;
-
-                                                       case pn_Cmp_Le:
-                                                       case pn_Cmp_Lt:
-                                                               /* TODO handle negative values */
-                                                               if (tarval_is_negative(lz) || tarval_is_negative(lo) ||
-                                                                               tarval_is_negative(rz) || tarval_is_negative(ro))
-                                                                       goto result_unknown;
-
-                                                               if (tarval_cmp(lz, ro) & pn) {
-                                                                       /* Left upper bound is smaller(/equal) than right lower bound. */
-                                                                       z = o = get_tarval_b_true();
-                                                               } else if (!(tarval_cmp(lo, rz) & pn)) {
-                                                                       /* Left lower bound is not smaller(/equal) than right upper bound. */
-                                                                       z = o = get_tarval_b_false();
-                                                               } else {
-                                                                       goto result_unknown;
-                                                               }
-                                                               break;
-
-                                                       case pn_Cmp_Ge:
-                                                       case pn_Cmp_Gt:
-                                                               /* TODO handle negative values */
-                                                               if (tarval_is_negative(lz) || tarval_is_negative(lo) ||
-                                                                               tarval_is_negative(rz) || tarval_is_negative(ro))
-                                                                       goto result_unknown;
-
-                                                               if (!(tarval_cmp(lz, ro) & pn)) {
-                                                                       /* Left upper bound is not greater(/equal) than right lower bound. */
-                                                                       z = o = get_tarval_b_false();
-                                                               } else if (tarval_cmp(lo, rz) & pn) {
-                                                                       /* Left lower bound is greater(/equal) than right upper bound. */
-                                                                       z = o = get_tarval_b_true();
-                                                               } else {
-                                                                       goto result_unknown;
-                                                               }
-                                                               break;
-
-                                                       default:
-                                                               goto cannot_analyse;
-                                               }
-                                       }
+                       case iro_Cmp: {
+                               bitinfo* const l = get_bitinfo(get_Cmp_left(irn));
+                               bitinfo* const r = get_bitinfo(get_Cmp_right(irn));
+                               if (l == NULL || r == NULL) {
+                                       goto result_unknown; // Cmp compares something we cannot evaluate.
                                } else {
-                                       goto cannot_analyse;
+                                       ir_tarval*  const lz       = l->z;
+                                       ir_tarval*  const lo       = l->o;
+                                       ir_tarval*  const rz       = r->z;
+                                       ir_tarval*  const ro       = r->o;
+                                       ir_relation const relation = get_Cmp_relation(irn);
+                                       switch (relation) {
+                                               case ir_relation_less_greater:
+                                                       if (!tarval_is_null(tarval_andnot(ro, lz)) ||
+                                                                       !tarval_is_null(tarval_andnot(lo, rz))) {
+                                                               // At least one bit differs.
+                                                               z = o = get_tarval_b_true();
+                                                       } else if (lz == lo && rz == ro && lz == rz) {
+                                                               z = o = get_tarval_b_false();
+                                                       } else {
+                                                               goto result_unknown;
+                                                       }
+                                                       break;
+
+                                               case ir_relation_equal:
+                                                       if (!tarval_is_null(tarval_andnot(ro, lz)) ||
+                                                                       !tarval_is_null(tarval_andnot(lo, rz))) {
+                                                               // At least one bit differs.
+                                                               z = o = get_tarval_b_false();
+                                                       } else if (lz == lo && rz == ro && lz == rz) {
+                                                               z = o = get_tarval_b_true();
+                                                       } else {
+                                                               goto result_unknown;
+                                                       }
+                                                       break;
+
+                                               case ir_relation_less_equal:
+                                               case ir_relation_less:
+                                                       /* TODO handle negative values */
+                                                       if (tarval_is_negative(lz) || tarval_is_negative(lo) ||
+                                                                       tarval_is_negative(rz) || tarval_is_negative(ro))
+                                                               goto result_unknown;
+
+                                                       if (tarval_cmp(lz, ro) & relation) {
+                                                               /* Left upper bound is smaller(/equal) than right lower bound. */
+                                                               z = o = get_tarval_b_true();
+                                                       } else if (!(tarval_cmp(lo, rz) & relation)) {
+                                                               /* Left lower bound is not smaller(/equal) than right upper bound. */
+                                                               z = o = get_tarval_b_false();
+                                                       } else {
+                                                               goto result_unknown;
+                                                       }
+                                                       break;
+
+                                               case ir_relation_greater_equal:
+                                               case ir_relation_greater:
+                                                       /* TODO handle negative values */
+                                                       if (tarval_is_negative(lz) || tarval_is_negative(lo) ||
+                                                                       tarval_is_negative(rz) || tarval_is_negative(ro))
+                                                               goto result_unknown;
+
+                                                       if (!(tarval_cmp(lz, ro) & relation)) {
+                                                               /* Left upper bound is not greater(/equal) than right lower bound. */
+                                                               z = o = get_tarval_b_false();
+                                                       } else if (tarval_cmp(lo, rz) & relation) {
+                                                               /* Left lower bound is greater(/equal) than right upper bound. */
+                                                               z = o = get_tarval_b_true();
+                                                       } else {
+                                                               goto result_unknown;
+                                                       }
+                                                       break;
+
+                                               default:
+                                                       goto cannot_analyse;
+                                       }
                                }
                                break;
                        }
index 966f9a2..6889900 100644 (file)
  */
 #define DBG_EVAL_CONFIRM(n)                                    \
        do {                                                       \
-         hook_merge_nodes(NULL, 0, &n, 1, HOOK_OPT_CONFIRM_E);    \
+         hook_merge_nodes(NULL, 0, (ir_node**)&n, 1, HOOK_OPT_CONFIRM_E);    \
        } while(0)
 
 /**
index c6120ee..f8b3cfb 100644 (file)
@@ -210,7 +210,7 @@ static void split_critical_edge(ir_node *block, int pos)
 typedef struct jumpthreading_env_t {
        ir_node       *true_block;
        ir_node       *cmp;        /**< The Compare node that might be partial evaluated */
-       pn_Cmp         pnc;        /**< The Compare mode of the Compare node. */
+       ir_relation    relation;   /**< The Compare mode of the Compare node. */
        ir_node       *cnst;
        ir_tarval     *tv;
        ir_visited_t   visited_nr;
@@ -348,47 +348,53 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
  * returns whether the cmp evaluates to true or false, or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
  *
- * @param pnc       the compare mode of the Compare
+ * @param relation  the compare mode of the Compare
  * @param tv_left   the left tarval
  * @param tv_right  the right tarval
  */
-static int eval_cmp_tv(pn_Cmp pnc, ir_tarval *tv_left, ir_tarval *tv_right)
+static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left,
+                       ir_tarval *tv_right)
 {
-       pn_Cmp cmp_result = tarval_cmp(tv_left, tv_right);
+       ir_relation cmp_result = tarval_cmp(tv_left, tv_right);
 
        /* does the compare evaluate to true? */
-       if (cmp_result == pn_Cmp_False)
+       if (cmp_result == ir_relation_false)
                return -1;
-       if ((cmp_result & pnc) != cmp_result)
-               return 0;
+       if ((cmp_result & relation) != 0)
+               return 1;
 
-       return 1;
+       return 0;
 }
 
+#if 0
+/* Matze: disabled, check first if the compare still is correct */
+
 /**
  * returns whether the cmp evaluates to true or false according to vrp
  * information , or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
  *
- * @param pnc       the compare mode of the Compare
- * @param left   the left node
- * @param right  the right node
+ * @param relation  the compare mode of the Compare
+ * @param left      the left node
+ * @param right     the right node
  */
-static int eval_cmp_vrp(pn_Cmp pnc, ir_node *left, ir_node *right)
+static int eval_cmp_vrp(ir_relation relation, ir_node *left, ir_node *right)
 {
-       pn_Cmp cmp_result = vrp_cmp(left, right);
+       ir_relation cmp_result = vrp_cmp(left, right);
        /* does the compare evaluate to true? */
-       if (cmp_result == pn_Cmp_False) {
+       if (cmp_result == ir_relation_false)
                return -1;
-       }
-       if ((cmp_result & pnc) != cmp_result) {
-               if ((cmp_result & pnc) != 0) {
+
+       if ((cmp_result & relation) != cmp_result) {
+               if ((cmp_result & relation) != 0) {
                        return -1;
                }
                return 0;
        }
        return 1;
 }
+#endif
+
 /**
  * returns whether the cmp evaluates to true or false, or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
@@ -399,12 +405,12 @@ static int eval_cmp_vrp(pn_Cmp pnc, ir_node *left, ir_node *right)
 static int eval_cmp(jumpthreading_env_t *env, ir_node *cand)
 {
        if (is_Const(cand)) {
-               ir_tarval *tv_cand   = get_Const_tarval(cand);
-               ir_tarval *tv_cmp    = get_Const_tarval(env->cnst);
+               ir_tarval *tv_cand = get_Const_tarval(cand);
+               ir_tarval *tv_cmp  = get_Const_tarval(env->cnst);
 
-               return eval_cmp_tv(env->pnc, tv_cand, tv_cmp);
+               return eval_cmp_tv(env->relation, tv_cand, tv_cmp);
        } else { /* a Confirm */
-               ir_tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst, env->pnc);
+               ir_tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst, env->relation);
 
                if (res == tarval_bad)
                        return -1;
@@ -443,9 +449,8 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
                return NULL;
 
        if (is_Const_or_Confirm(value)) {
-               if (eval_cmp(env, value) <= 0) {
+               if (eval_cmp(env, value) <= 0)
                        return NULL;
-               }
 
                DB((
                        dbg, LEVEL_1,
@@ -468,9 +473,8 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
                int i, arity;
 
                /* the Phi has to be in the same Block as the Jmp */
-               if (get_nodes_block(value) != block) {
+               if (get_nodes_block(value) != block)
                        return NULL;
-               }
 
                arity = get_irn_arity(value);
                for (i = 0; i < arity; ++i) {
@@ -558,17 +562,11 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
                        return copy_block;
                }
        }
-       if (is_Proj(value)) {
-               ir_node *left;
-               ir_node *right;
-               pn_Cmp   pnc;
-               ir_node *cmp = get_Proj_pred(value);
-               if (!is_Cmp(cmp))
-                       return NULL;
-
-               left  = get_Cmp_left(cmp);
-               right = get_Cmp_right(cmp);
-               pnc   = get_Proj_pn_cmp(value);
+       if (is_Cmp(value)) {
+               ir_node    *cmp      = value;
+               ir_node    *left     = get_Cmp_left(cmp);
+               ir_node    *right    = get_Cmp_right(cmp);
+               ir_relation relation = get_Cmp_relation(cmp);
 
                /* we assume that the constant is on the right side, swap left/right
                 * if needed */
@@ -577,25 +575,24 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
                        left       = right;
                        right      = t;
 
-                       pnc        = get_inversed_pnc(pnc);
+                       relation   = get_inversed_relation(relation);
                }
 
                if (!is_Const(right))
-                       return 0;
+                       return NULL;
 
-               if (get_nodes_block(left) != block) {
-                       return 0;
-               }
+               if (get_nodes_block(left) != block)
+                       return NULL;
 
                /* negate condition when we're looking for the false block */
                if (env->tv == tarval_b_false) {
-                       pnc = get_negated_pnc(pnc, get_irn_mode(right));
+                       relation = get_negated_relation(relation);
                }
 
                /* (recursively) look if a pred of a Phi is a constant or a Confirm */
-               env->cmp  = cmp;
-               env->pnc  = pnc;
-               env->cnst = right;
+               env->cmp      = cmp;
+               env->relation = relation;
+               env->cnst     = right;
 
                return find_const_or_confirm(env, jump, left);
        }
@@ -649,28 +646,25 @@ static void thread_jumps(ir_node* block, void* data)
 
        /* handle cases that can be immediately evaluated */
        selector_evaluated = -1;
-       if (is_Proj(selector)) {
-               ir_node *cmp = get_Proj_pred(selector);
-               if (is_Cmp(cmp)) {
-                       ir_node *left  = get_Cmp_left(cmp);
-                       ir_node *right = get_Cmp_right(cmp);
-                       if (is_Const(left) && is_Const(right)) {
-                               pn_Cmp     pnc      = get_Proj_pn_cmp(selector);
-                               ir_tarval *tv_left  = get_Const_tarval(left);
-                               ir_tarval *tv_right = get_Const_tarval(right);
-
-                               selector_evaluated = eval_cmp_tv(pnc, tv_left, tv_right);
-                       }
-                       if (selector_evaluated < 0) {
-                               /* This is only the case if the predecessor nodes are not
-                                * constant or the comparison could not be evaluated.
-                                * Try with VRP information now.
-                                */
-                               pn_Cmp pnc = get_Proj_pn_cmp(selector);
-
-                               selector_evaluated = eval_cmp_vrp(pnc, left, right);
-                       }
+       if (is_Cmp(selector)) {
+               ir_node *left  = get_Cmp_left(selector);
+               ir_node *right = get_Cmp_right(selector);
+               if (is_Const(left) && is_Const(right)) {
+                       ir_relation relation = get_Cmp_relation(selector);
+                       ir_tarval  *tv_left  = get_Const_tarval(left);
+                       ir_tarval  *tv_right = get_Const_tarval(right);
+
+                       selector_evaluated = eval_cmp_tv(relation, tv_left, tv_right);
                }
+#if 0
+               if (selector_evaluated < 0) {
+                       /* This is only the case if the predecessor nodes are not
+                        * constant or the comparison could not be evaluated.
+                        * Try with VRP information now.
+                        */
+                       selector_evaluated = eval_cmp_vrp(relation, left, right);
+               }
+#endif
        } else if (is_Const_or_Confirm(selector)) {
                ir_tarval *tv = get_Const_or_Confirm_tarval(selector);
                if (tv == tarval_b_true) {
index 15964a3..48e9fa6 100644 (file)
@@ -287,9 +287,9 @@ static ir_entity *find_constant_entity(ir_node *ptr)
                                        if (tlower == tarval_bad || tupper == tarval_bad)
                                                return NULL;
 
-                                       if (tarval_cmp(tv, tlower) & pn_Cmp_Lt)
+                                       if (tarval_cmp(tv, tlower) == ir_relation_less)
                                                return NULL;
-                                       if (tarval_cmp(tupper, tv) & pn_Cmp_Lt)
+                                       if (tarval_cmp(tupper, tv) == ir_relation_less)
                                                return NULL;
 
                                        /* ok, bounds check finished */
@@ -434,9 +434,9 @@ ptr_arith:
                        if (tlower == tarval_bad || tupper == tarval_bad)
                                return NULL;
 
-                       if (tarval_cmp(tv_index, tlower) & pn_Cmp_Lt)
+                       if (tarval_cmp(tv_index, tlower) == ir_relation_less)
                                return NULL;
-                       if (tarval_cmp(tupper, tv_index) & pn_Cmp_Lt)
+                       if (tarval_cmp(tupper, tv_index) == ir_relation_less)
                                return NULL;
 
                        /* ok, bounds check finished */
@@ -660,9 +660,9 @@ ptr_arith:
                        if (tlower == tarval_bad || tupper == tarval_bad)
                                return NULL;
 
-                       if (tarval_cmp(tv_index, tlower) & pn_Cmp_Lt)
+                       if (tarval_cmp(tv_index, tlower) == ir_relation_less)
                                return NULL;
-                       if (tarval_cmp(tupper, tv_index) & pn_Cmp_Lt)
+                       if (tarval_cmp(tupper, tv_index) == ir_relation_less)
                                return NULL;
 
                        /* ok, bounds check finished */
index f7b8914..a731042 100644 (file)
@@ -1660,10 +1660,9 @@ static ir_node *new_Abs(ir_node *op, ir_mode *mode)
   ir_graph *irg      = get_irn_irg(op);
   ir_node  *block    = get_nodes_block(op);
   ir_node  *zero     = new_r_Const(irg, get_mode_null(mode));
-  ir_node  *cmp      = new_r_Cmp(block, op, zero);
-  ir_node  *cond     = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
+  ir_node  *cmp      = new_r_Cmp(block, op, zero, ir_relation_less);
   ir_node  *minus_op = new_r_Minus(block, op, mode);
-  ir_node  *mux      = new_r_Mux(block, cond, op, minus_op, mode);
+  ir_node  *mux      = new_r_Mux(block, cmp, op, minus_op, mode);
 
   return mux;
 }
@@ -1678,7 +1677,7 @@ static void create_duffs_block(void)
 
        ir_node *block1, *count_block, *duff_block;
        ir_node *ems, *ems_mod, *ems_div, *ems_mod_proj, *cmp_null,
-               *cmp_proj, *ems_mode_cond, *x_true, *x_false, *const_null;
+               *ems_mode_cond, *x_true, *x_false, *const_null;
        ir_node *true_val, *false_val;
        ir_node *ins[2];
 
@@ -1732,10 +1731,8 @@ static void create_duffs_block(void)
        DB((dbg, LEVEL_4, "New module node %N\n", ems_mod));
 
        ems_mod_proj = new_r_Proj(ems_mod, mode_Iu, pn_Mod_res);
-       cmp_null = new_r_Cmp(block1, ems_mod_proj, const_null);
-       cmp_proj = new_r_Proj(cmp_null, mode_b, pn_Cmp_Eq);
-       ems_mode_cond = new_r_Cond(block1, cmp_proj);
-
+       cmp_null = new_r_Cmp(block1, ems_mod_proj, const_null, ir_relation_less);
+       ems_mode_cond = new_r_Cond(block1, cmp_null);
 
        /* ems % step == 0 */
        x_true = new_r_Proj(ems_mode_cond, mode_X, pn_Cond_true);
@@ -1780,8 +1777,6 @@ static void create_duffs_block(void)
        /* (end - start) / step  +  correction */
        count = new_Add(count, correction, mode);
 
-       cmp_bad_count = new_r_Cmp(count_block, count, const_null);
-
        /* We preconditioned the loop to be tail-controlled.
         * So, if count is something 'wrong' like 0,
         * negative/positive (depending on step direction),
@@ -1790,12 +1785,14 @@ static void create_duffs_block(void)
 
        /* Depending on step direction, we have to check for > or < 0 */
        if (loop_info.decreasing == 1) {
-               bad_count_neg = new_r_Proj(cmp_bad_count, mode_b, pn_Cmp_Lt);
+               cmp_bad_count = new_r_Cmp(count_block, count, const_null,
+                                         ir_relation_less);
        } else {
-               bad_count_neg = new_r_Proj(cmp_bad_count, mode_b, pn_Cmp_Gt);
+               cmp_bad_count = new_r_Cmp(count_block, count, const_null,
+                                         ir_relation_greater);
        }
 
-       bad_count_neg = new_r_Cond(count_block, bad_count_neg);
+       bad_count_neg = new_r_Cond(count_block, cmp_bad_count);
        good_count = new_Proj(bad_count_neg, mode_X, pn_Cond_true);
        bad_count = new_Proj(ems_mode_cond, mode_X, pn_Cond_false);
 
@@ -1994,38 +1991,17 @@ static unsigned get_const_pred(ir_node *node, ir_node **const_pred, ir_node **ot
                return 1;
 }
 
-/* Returns the mathematically inverted pn_Cmp. */
-static pn_Cmp get_math_inverted_case(pn_Cmp proj)
-{
-       switch(proj) {
-               case pn_Cmp_Eq:
-                       return pn_Cmp_Lg;
-               case pn_Cmp_Lg:
-                       return pn_Cmp_Eq;
-               case pn_Cmp_Lt:
-                       return pn_Cmp_Ge;
-               case pn_Cmp_Le:
-                       return pn_Cmp_Gt;
-               case pn_Cmp_Gt:
-                       return pn_Cmp_Le;
-               case pn_Cmp_Ge:
-                       return pn_Cmp_Lt;
-               default:
-                       panic("Unhandled pn_Cmp.");
-       }
-}
-
 /* Returns 1 if loop exits within 2 steps of the iv.
  * Norm_proj means we do not exit the loop.*/
 static unsigned simulate_next(ir_tarval **count_tar,
                ir_tarval *stepped, ir_tarval *step_tar, ir_tarval *end_tar,
-               pn_Cmp norm_proj)
+               ir_relation norm_proj)
 {
        ir_tarval *next;
 
        DB((dbg, LEVEL_4, "Loop taken if (stepped)%ld %s (end)%ld ",
                                get_tarval_long(stepped),
-                               get_pnc_string((norm_proj)),
+                               get_relation_string((norm_proj)),
                                get_tarval_long(end_tar)));
        DB((dbg, LEVEL_4, "comparing latest value %d\n", loop_info.latest_value));
 
@@ -2036,7 +2012,7 @@ static unsigned simulate_next(ir_tarval **count_tar,
 
        DB((dbg, LEVEL_4, "Result: (stepped)%ld IS %s (end)%ld\n",
                                get_tarval_long(stepped),
-                               get_pnc_string(tarval_cmp(stepped, end_tar)),
+                               get_relation_string(tarval_cmp(stepped, end_tar)),
                                get_tarval_long(end_tar)));
 
        /* next step */
@@ -2048,7 +2024,7 @@ static unsigned simulate_next(ir_tarval **count_tar,
 
        DB((dbg, LEVEL_4, "Loop taken if %ld %s %ld ",
                                get_tarval_long(next),
-                               get_pnc_string(norm_proj),
+                               get_relation_string(norm_proj),
                                get_tarval_long(end_tar)));
        DB((dbg, LEVEL_4, "comparing latest value %d\n", loop_info.latest_value));
 
@@ -2073,7 +2049,7 @@ static unsigned simulate_next(ir_tarval **count_tar,
 static ir_node *is_simple_loop(void)
 {
        int arity, i;
-       ir_node *loop_block, *exit_block, *projx, *cond, *projres, *loop_condition;
+       ir_node *loop_block, *exit_block, *projx, *cond, *cmp;
 
        /* Maximum of one condition, and no endless loops. */
        if (loop_info.cf_outs != 1)
@@ -2128,13 +2104,12 @@ static ir_node *is_simple_loop(void)
        /* find value on which loop exit depends */
        projx = loop_info.cf_out.pred;
        cond = get_irn_n(projx, 0);
-       projres = get_irn_n(cond, 0);
-       loop_condition = get_irn_n(projres, 0);
+       cmp = get_irn_n(cond, 0);
 
-       if (!is_Cmp(loop_condition))
+       if (!is_Cmp(cmp))
                return NULL;
 
-       DB((dbg, LEVEL_5, "projection is %s\n", get_pnc_string(get_Proj_proj(projx))));
+       DB((dbg, LEVEL_5, "projection is %s\n", get_relation_string(get_Proj_proj(projx))));
 
        switch(get_Proj_proj(projx)) {
                case pn_Cond_false:
@@ -2148,8 +2123,7 @@ static ir_node *is_simple_loop(void)
        }
 
        DB((dbg, LEVEL_4, "Valid Cmp.\n"));
-
-       return projres;
+       return cmp;
 }
 
 /* Returns 1 if all nodes are mode_Iu or mode_Is. */
@@ -2378,15 +2352,16 @@ static unsigned get_preferred_factor_constant(ir_tarval *count_tar)
 /* TODO split. */
 static unsigned get_unroll_decision_constant(void)
 {
-       ir_node   *projres, *loop_condition, *iteration_path;
-       unsigned   success, is_latest_val;
-       ir_tarval *start_tar, *end_tar, *step_tar, *diff_tar, *count_tar, *stepped;
-       pn_Cmp     proj_proj, norm_proj;
-       ir_mode   *mode;
+       ir_node     *cmp, *iteration_path;
+       unsigned     success, is_latest_val;
+       ir_tarval   *start_tar, *end_tar, *step_tar, *diff_tar, *count_tar;
+       ir_tarval   *stepped;
+       ir_relation  proj_proj, norm_proj;
+       ir_mode     *mode;
 
        /* RETURN if loop is not 'simple' */
-       projres = is_simple_loop();
-       if (projres == NULL)
+       cmp = is_simple_loop();
+       if (cmp == NULL)
                return 0;
 
        /* One in of the loop condition needs to be loop invariant. => end_val
@@ -2404,9 +2379,7 @@ static unsigned get_unroll_decision_constant(void)
             /\
        */
 
-       loop_condition = get_irn_n(projres, 0);
-
-       success = get_const_pred(loop_condition, &loop_info.end_val, &iteration_path);
+       success = get_const_pred(cmp, &loop_info.end_val, &iteration_path);
        if (! success)
                return 0;
 
@@ -2538,17 +2511,16 @@ static unsigned get_unroll_decision_constant(void)
 
        DB((dbg, LEVEL_4, "stepped to %ld\n", get_tarval_long(stepped)));
 
-       proj_proj = get_Proj_pn_cmp(projres);
+       proj_proj = get_Cmp_relation(cmp);
        /* Assure that norm_proj is the stay-in-loop case. */
        if (loop_info.exit_cond == 1)
-               norm_proj = get_math_inverted_case(proj_proj);
+               norm_proj = get_negated_relation(proj_proj);
        else
                norm_proj = proj_proj;
 
-       DB((dbg, LEVEL_4, "normalized projection %s\n", get_pnc_string(norm_proj)));
-
+       DB((dbg, LEVEL_4, "normalized projection %s\n", get_relation_string(norm_proj)));
        /* Executed at most once (stay in counting loop if a Eq b) */
-       if (norm_proj == pn_Cmp_Eq)
+       if (norm_proj == ir_relation_equal)
                /* TODO Might be worth a warning. */
                return 0;
 
index 0bab0a0..664d304 100644 (file)
@@ -58,34 +58,34 @@ typedef struct interval_t {
 
 #ifdef DEBUG_CONFIRM
 
-#define compare_iv(l_iv, r_iv, pnc)    compare_iv_dbg(l_iv, r_iv, pnc)
+#define compare_iv(l_iv, r_iv, relation)    compare_iv_dbg(l_iv, r_iv, relation)
 
 /* forward */
-static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc);
+static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, ir_relation relation);
 
 /* triangle */
-#define DBG_OUT_TR(l_pnc, l_bound, r_pnc, r_bound, pnc, v) \
+#define DBG_OUT_TR(l_relation, l_bound, r_relation, r_bound, relation, v) \
   ir_printf("In %e:\na %= %n && b %= %n  ==>  a %= b == %s\n", \
     get_irg_entity(current_ir_graph), \
-    l_pnc, l_bound, r_pnc, r_bound, pnc, v);
+    l_relation, l_bound, r_relation, r_bound, relation, v);
 
 /* right side */
-#define DBG_OUT_R(r_pnc, r_bound, left, pnc, right, v) \
+#define DBG_OUT_R(r_relation, r_bound, left, relation, right, v) \
   ir_printf("In %e:\na %= %n ==>  %n %= %n == %s\n", \
     get_irg_entity(current_ir_graph), \
-    r_pnc, r_bound, left, pnc, right, v);
+    r_relation, r_bound, left, relation, right, v);
 
 /* left side */
-#define DBG_OUT_L(l_pnc, l_bound, left, pnc, right, v) \
+#define DBG_OUT_L(l_relation, l_bound, left, relation, right, v) \
   ir_printf("In %e:\na %= %n ==>  %n %= %n == %s\n", \
     get_irg_entity(current_ir_graph), \
-    l_pnc, l_bound, left, pnc, right, v);
+    l_relation, l_bound, left, relation, right, v);
 
 #else
 
-#define DBG_OUT_TR(l_pnc, l_bound, r_pnc, r_bound, pnc, v)
-#define DBG_OUT_R(r_pnc, r_bound, left, pnc, right, v)
-#define DBG_OUT_L(l_pnc, l_bound, left, pnc, right, v)
+#define DBG_OUT_TR(l_relation, l_bound, r_relation, r_bound, relation, v)
+#define DBG_OUT_R(r_relation, r_bound, left, relation, right, v)
+#define DBG_OUT_L(l_relation, l_bound, left, relation, right, v)
 
 #endif /* DEBUG_CONFIRM */
 
@@ -101,7 +101,7 @@ FIRM_API int value_not_zero(const ir_node *n, ir_node_cnst_ptr *confirm)
 
        ir_tarval *tv;
        ir_mode *mode = get_irn_mode(n);
-       pn_Cmp pnc;
+       ir_relation relation;
 
        *confirm = NULL;
 
@@ -124,7 +124,7 @@ FIRM_API int value_not_zero(const ir_node *n, ir_node_cnst_ptr *confirm)
                if (tv == tarval_bad)
                        return 0;
 
-               pnc = tarval_cmp(tv, get_mode_null(mode));
+               relation = tarval_cmp(tv, get_mode_null(mode));
 
                /*
                 * Beware: C might by a NaN. It is not clear, what we should do
@@ -134,19 +134,19 @@ FIRM_API int value_not_zero(const ir_node *n, ir_node_cnst_ptr *confirm)
                 *
                 * Note that only the C != 0 case need additional checking.
                 */
-               switch (get_Confirm_cmp(n)) {
-               case pn_Cmp_Eq: /* n == C /\ C != 0 ==> n != 0 */
-                       RET_ON(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Uo);
-               case pn_Cmp_Lg: /* n != C /\ C == 0 ==> n != 0 */
-                       RET_ON(pnc == pn_Cmp_Eq);
-               case pn_Cmp_Lt: /* n <  C /\ C <= 0 ==> n != 0 */
-                       RET_ON(pnc == pn_Cmp_Lt || pnc == pn_Cmp_Eq);
-               case pn_Cmp_Le: /* n <= C /\ C <  0 ==> n != 0 */
-                       RET_ON(pnc == pn_Cmp_Lt);
-               case pn_Cmp_Ge: /* n >= C /\ C >  0 ==> n != 0 */
-                       RET_ON(pnc == pn_Cmp_Gt);
-               case pn_Cmp_Gt: /* n >  C /\ C >= 0 ==> n != 0 */
-                       RET_ON(pnc == pn_Cmp_Gt || pnc == pn_Cmp_Eq);
+               switch (get_Confirm_relation(n)) {
+               case ir_relation_equal: /* n == C /\ C != 0 ==> n != 0 */
+                       RET_ON(relation != ir_relation_equal && relation != ir_relation_unordered);
+               case ir_relation_less_greater: /* n != C /\ C == 0 ==> n != 0 */
+                       RET_ON(relation == ir_relation_equal);
+               case ir_relation_less: /* n <  C /\ C <= 0 ==> n != 0 */
+                       RET_ON(relation == ir_relation_less || relation == ir_relation_equal);
+               case ir_relation_less_equal: /* n <= C /\ C <  0 ==> n != 0 */
+                       RET_ON(relation == ir_relation_less);
+               case ir_relation_greater_equal: /* n >= C /\ C >  0 ==> n != 0 */
+                       RET_ON(relation == ir_relation_greater);
+               case ir_relation_greater: /* n >  C /\ C >= 0 ==> n != 0 */
+                       RET_ON(relation == ir_relation_greater || relation == ir_relation_equal);
                default:
                        break;
                }
@@ -157,10 +157,10 @@ FIRM_API int value_not_zero(const ir_node *n, ir_node_cnst_ptr *confirm)
        if (tv == tarval_bad)
                return 0;
 
-       pnc = tarval_cmp(tv, get_mode_null(mode));
+       relation = tarval_cmp(tv, get_mode_null(mode));
 
        /* again, need check for NaN */
-       return (pnc != pn_Cmp_Eq) && (pnc != pn_Cmp_Uo);
+       return (relation != ir_relation_equal) && (relation != ir_relation_unordered);
 
 #undef RET_ON
 }  /* value_not_zero */
@@ -210,7 +210,7 @@ FIRM_API int value_not_null(const ir_node *n, ir_node_cnst_ptr *confirm)
        } else {
                /* check for more Confirms */
                for (; is_Confirm(n); n = skip_Cast(get_Confirm_value(n))) {
-                       if (get_Confirm_cmp(n) == pn_Cmp_Lg) {
+                       if (get_Confirm_relation(n) == ir_relation_less_greater) {
                                ir_node   *bound = get_Confirm_bound(n);
                                ir_tarval *tv    = value_of(bound);
 
@@ -241,7 +241,7 @@ FIRM_API ir_value_classify_sign classify_value_sign(ir_node *n)
 {
        ir_tarval *tv, *c;
        ir_mode *mode;
-       pn_Cmp cmp, ncmp;
+       ir_relation cmp, ncmp;
        int negate = 1;
 
        for (;;) {
@@ -277,15 +277,15 @@ FIRM_API ir_value_classify_sign classify_value_sign(ir_node *n)
         * optimization possibilities, so we handle this
         * different.
         */
-       cmp = get_Confirm_cmp(n);
+       cmp = get_Confirm_relation(n);
 
        switch (cmp) {
-       case pn_Cmp_Lt:
+       case ir_relation_less:
                /*
                 * must be x < c <= 1 to be useful if integer mode and -0 = 0
                 *         x < c <= 0 to be useful else
                 */
-       case pn_Cmp_Le:
+       case ir_relation_less_equal:
                /*
                 * must be x <= c < 1 to be useful if integer mode and -0 = 0
                 *         x <= c < 0 to be useful else
@@ -294,21 +294,21 @@ FIRM_API ir_value_classify_sign classify_value_sign(ir_node *n)
                        get_mode_one(mode) : get_mode_null(mode);
 
                ncmp = tarval_cmp(tv, c);
-               if (ncmp == pn_Cmp_Eq)
-                       ncmp = pn_Cmp_Le;
+               if (ncmp == ir_relation_equal)
+                       ncmp = ir_relation_less_equal;
 
-               if (cmp != (ncmp ^ pn_Cmp_Eq))
+               if (cmp != (ncmp ^ ir_relation_equal))
                        return value_classified_unknown;
 
                /* yep, negative */
                return value_classified_negative * negate;
 
-       case pn_Cmp_Ge:
+       case ir_relation_greater_equal:
                /*
                 * must be x >= c > -1 to be useful if integer mode
                 *         x >= c >= 0 to be useful else
                 */
-       case pn_Cmp_Gt:
+       case ir_relation_greater:
                /*
                 * must be x > c >= -1 to be useful if integer mode
                 *         x > c >= 0 to be useful else
@@ -317,17 +317,17 @@ FIRM_API ir_value_classify_sign classify_value_sign(ir_node *n)
                        c = get_mode_minus_one(mode);
 
                        ncmp = tarval_cmp(tv, c);
-                       if (ncmp == pn_Cmp_Eq)
-                               ncmp = pn_Cmp_Ge;
+                       if (ncmp == ir_relation_equal)
+                               ncmp = ir_relation_greater_equal;
 
-                       if (cmp != (ncmp ^ pn_Cmp_Eq))
+                       if (cmp != (ncmp ^ ir_relation_equal))
                                return value_classified_unknown;
                } else {
                        c = get_mode_minus_one(mode);
 
                        ncmp = tarval_cmp(tv, c);
 
-                       if (ncmp != pn_Cmp_Eq && ncmp != pn_Cmp_Gt)
+                       if (ncmp != ir_relation_equal && ncmp != ir_relation_greater)
                                return value_classified_unknown;
                }
 
@@ -386,14 +386,14 @@ static interval_t *get_interval_from_tv(interval_t *iv, ir_tarval *tv)
 /**
  * construct an interval from a Confirm
  *
- * @param iv     an empty interval, will be filled
- * @param bound  the bound value
- * @param pnc    the Confirm compare relation
+ * @param iv       an empty interval, will be filled
+ * @param bound    the bound value
+ * @param relation the Confirm compare relation
  *
  * @return the filled interval or NULL if no interval
  *         can be created (happens only on floating point
  */
-static interval_t *get_interval(interval_t *iv, ir_node *bound, pn_Cmp pnc)
+static interval_t *get_interval(interval_t *iv, ir_node *bound, ir_relation relation)
 {
        ir_mode   *mode = get_irn_mode(bound);
        ir_tarval *tv   = value_of(bound);
@@ -422,43 +422,43 @@ static interval_t *get_interval(interval_t *iv, ir_node *bound, pn_Cmp pnc)
        }
 
        /* check which side is known */
-       switch (pnc) {
-       case pn_Cmp_Eq:
+       switch (relation) {
+       case ir_relation_equal:
                /* [tv, tv] */
                iv->min   =
                        iv->max   = tv;
                iv->flags = MIN_INCLUDED | MAX_INCLUDED;
                break;
 
-       case pn_Cmp_Le:
+       case ir_relation_less_equal:
                /* [-oo, tv] */
                iv->min   = get_mode_min(mode);
                iv->max   = tv;
                iv->flags = MIN_INCLUDED | MAX_INCLUDED;
                break;
 
-       case pn_Cmp_Lt:
+       case ir_relation_less:
                /* [-oo, tv) */
                iv->min   = get_mode_min(mode);
                iv->max   = tv;
                iv->flags = MIN_INCLUDED | MAX_EXCLUDED;
                break;
 
-       case pn_Cmp_Gt:
+       case ir_relation_greater:
                /* (tv, +oo] */
                iv->min   = tv;
                iv->max   = get_mode_max(mode);
                iv->flags = MIN_EXCLUDED | MAX_INCLUDED;
                break;
 
-       case pn_Cmp_Ge:
+       case ir_relation_greater_equal:
                /* [tv, +oo] */
                iv->min   = tv;
                iv->max   = get_mode_max(mode);
                iv->flags = MIN_INCLUDED | MAX_INCLUDED;
                break;
 
-       case pn_Cmp_Leg:
+       case ir_relation_less_equal_greater:
                /*
                 * Ordered means, that at least neither
                 * our bound nor our value ara NaN's
@@ -486,129 +486,129 @@ static interval_t *get_interval(interval_t *iv, ir_node *bound, pn_Cmp pnc)
 }  /* get_interval */
 
 /**
- * Try to evaluate l_iv pnc r_iv.
+ * Try to evaluate l_iv relation r_iv.
  *
- * @param l_iv   the left interval
- * @param r_iv   the right interval
- * @param pnc    the compare relation
+ * @param l_iv      the left interval
+ * @param r_iv      the right interval
+ * @param relation  the compare relation
  *
  * @return
  *   tarval_b_true or tarval_b_false it it can be evaluated,
  *   tarval_bad else
  */
-static ir_tarval *(compare_iv)(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
+static ir_tarval *(compare_iv)(const interval_t *l_iv, const interval_t *r_iv, ir_relation relation)
 {
-       pn_Cmp     res;
-       unsigned   flags;
-       ir_tarval *tv_true = tarval_b_true, *tv_false = tarval_b_false;
+       ir_relation res;
+       unsigned    flags;
+       ir_tarval  *tv_true = tarval_b_true, *tv_false = tarval_b_false;
 
        /* if one interval contains NaNs, we cannot evaluate anything */
        if (! l_iv || ! r_iv)
                return tarval_bad;
 
        /* we can only check ordered relations */
-       if (pnc & pn_Cmp_Uo) {
+       if (relation & ir_relation_unordered) {
                ir_tarval *t;
 
-               pnc      = get_negated_pnc(pnc, get_tarval_mode(l_iv->min));
+               relation = get_negated_relation(relation);
                t        = tv_true;
                tv_true  = tv_false;
                tv_false = t;
        }
 
        /* if we have > or >=, we do the inverse to save some cases */
-       if (pnc == pn_Cmp_Ge || pnc == pn_Cmp_Gt) {
+       if (relation == ir_relation_greater_equal || relation == ir_relation_greater) {
                const interval_t *t;
 
-               pnc  = get_inversed_pnc(pnc);
-               t    = l_iv;
-               l_iv = r_iv;
-               r_iv = t;
+               relation = get_inversed_relation(relation);
+               t        = l_iv;
+               l_iv     = r_iv;
+               r_iv     = t;
        }
 
        /* now, only the following cases remains */
-       switch (pnc) {
-       case pn_Cmp_Eq:
+       switch (relation) {
+       case ir_relation_equal:
                /* two intervals can be compared for equality only if they are a single value */
                if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
-                       return tarval_cmp(l_iv->min, r_iv->min) == pn_Cmp_Eq ? tv_true : tv_false;
+                       return tarval_cmp(l_iv->min, r_iv->min) == ir_relation_equal ? tv_true : tv_false;
 
                /* if both intervals do not intersect, it is never equal */
                res = tarval_cmp(l_iv->max, r_iv->min);
 
                /* b < c ==> [a,b] != [c,d] */
-               if (res == pn_Cmp_Lt)
+               if (res == ir_relation_less)
                        return tv_false;
 
                /* b <= c ==> [a,b) != [c,d]  AND [a,b] != (c,d] */
                if ((l_iv->flags & MAX_EXCLUDED || r_iv->flags & MIN_EXCLUDED)
-                       && (res == pn_Cmp_Eq))
+                       && (res == ir_relation_equal))
                        return tv_false;
 
                res = tarval_cmp(r_iv->max, l_iv->min);
 
                /* d < a ==> [c,d] != [a,b] */
-               if (res == pn_Cmp_Lt)
+               if (res == ir_relation_less)
                        return tv_false;
 
                /* d <= a ==> [c,d) != [a,b]  AND [c,d] != (a,b] */
                if ((r_iv->flags & MAX_EXCLUDED || l_iv->flags & MIN_EXCLUDED)
-                       && (res == pn_Cmp_Eq))
+                       && (res == ir_relation_equal))
                        return tv_false;
                break;
 
-       case pn_Cmp_Lg:
+       case ir_relation_less_greater:
                /* two intervals can be compared for not equality only if they are a single value */
                if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
-                       return tarval_cmp(l_iv->min, r_iv->min) != pn_Cmp_Eq ? tv_true : tv_false;
+                       return tarval_cmp(l_iv->min, r_iv->min) != ir_relation_equal ? tv_true : tv_false;
                break;
 
-       case pn_Cmp_Lt:
+       case ir_relation_less:
                res = tarval_cmp(l_iv->max, r_iv->min);
 
                /* [a, b] < [c, d]  <==> b < c */
-               if (res == pn_Cmp_Lt)
+               if (res == ir_relation_less)
                        return tv_true;
 
                /* if one border is excluded, b <= c is enough */
                if ((l_iv->flags & MAX_EXCLUDED || r_iv->flags & MIN_EXCLUDED) &&
-                       res == pn_Cmp_Eq)
+                       res == ir_relation_equal)
                        return tv_true;
 
                /* [a, b] >= [c, d] <==> a > d */
                res = tarval_cmp(l_iv->min, r_iv->max);
-               if (res == pn_Cmp_Gt)
+               if (res == ir_relation_greater)
                        return tv_false;
 
                /* if one border is excluded, a >= d is enough */
                if ((l_iv->flags & MIN_EXCLUDED || r_iv->flags & MAX_EXCLUDED) &&
-                       res == pn_Cmp_Eq)
+                       res == ir_relation_equal)
                        return tv_false;
                break;
 
-       case pn_Cmp_Le:
+       case ir_relation_less_equal:
                /* [a, b) <= [c, d] or [a, b] <= (c, d]  <==> b <= c */
                flags = (l_iv->flags & MAX_EXCLUDED) | (r_iv->flags & MIN_EXCLUDED);
                if (flags) {
                        res = tarval_cmp(l_iv->max, r_iv->min);
 
-                       if (res == pn_Cmp_Lt || res == pn_Cmp_Eq)
+                       if (res == ir_relation_less || res == ir_relation_equal)
                                return tv_true;
                }
 
                res = tarval_cmp(l_iv->min, r_iv->max);
 
                /* [a, b] > [c, d] <==> a > d */
-               if (res == pn_Cmp_Gt)
+               if (res == ir_relation_greater)
                        return tv_false;
 
                /* if one border is excluded, a >= d is enough */
                if ((l_iv->flags & MIN_EXCLUDED || r_iv->flags & MAX_EXCLUDED) &&
-                       res == pn_Cmp_Eq)
+                       res == ir_relation_equal)
                        return tv_false;
                break;
 
-       case pn_Cmp_Leg:
+       case ir_relation_less_equal_greater:
                /* Hmm. if both are intervals, we can find an order */
                return tv_true;
 
@@ -621,24 +621,24 @@ static ir_tarval *(compare_iv)(const interval_t *l_iv, const interval_t *r_iv, p
 /**
  * Returns non-zero, if a given relation is transitive.
  */
-static int is_transitive(pn_Cmp pnc)
+static int is_transitive(ir_relation relation)
 {
-       return (pn_Cmp_False < pnc && pnc < pn_Cmp_Lg);
+       return (ir_relation_false < relation && relation < ir_relation_less_greater);
 }  /* is_transitive */
 
 /**
  * Return the value of a Cmp if one or both predecessors
  * are Confirm nodes.
  *
- * @param cmp    the Cmp node
- * @param left   the left operand of the Cmp
- * @param right  the right operand of the Cmp
- * @param pnc    the compare relation
+ * @param cmp      the Cmp node
+ * @param left     the left operand of the Cmp
+ * @param right    the right operand of the Cmp
+ * @param relation the compare relation
  */
-FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_node *right, pn_Cmp pnc)
+FIRM_API ir_tarval *computed_value_Cmp_Confirm(const ir_node *cmp, ir_node *left, ir_node *right, ir_relation relation)
 {
        ir_node    *l_bound;
-       pn_Cmp      l_pnc, res_pnc, neg_pnc;
+       ir_relation l_relation, res_relation, neg_relation;
        interval_t  l_iv, r_iv;
        ir_tarval  *tv;
        ir_mode    *mode;
@@ -649,7 +649,7 @@ FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_n
                right = left;
                left  = t;
 
-               pnc = get_inversed_pnc(pnc);
+               relation = get_inversed_relation(relation);
        } else if (! is_Confirm(left)) {
                /* nothing more found */
                tv = tarval_bad;
@@ -657,22 +657,22 @@ FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_n
        }
 
        /* ok, here at least left is a Confirm, right might be */
-       l_bound = get_Confirm_bound(left);
-       l_pnc   = get_Confirm_cmp(left);
+       l_bound    = get_Confirm_bound(left);
+       l_relation = get_Confirm_relation(left);
 
        if (is_Confirm(right)) {
                /*
                 * both sides are Confirm's. Check some rare cases first.
                 */
-               ir_node *r_bound = get_Confirm_bound(right);
-               pn_Cmp  r_pnc    = get_Confirm_cmp(right);
+               ir_node    *r_bound    = get_Confirm_bound(right);
+               ir_relation r_relation = get_Confirm_relation(right);
 
                /*
                 * some check can be made WITHOUT constant bounds
                 */
                if (r_bound == l_bound) {
-                       if (is_transitive(l_pnc)) {
-                               pn_Cmp r_inc_pnc = get_inversed_pnc(r_pnc);
+                       if (is_transitive(l_relation)) {
+                               ir_relation r_inc_relation = get_inversed_relation(r_relation);
 
                                /*
                                 * triangle inequality:
@@ -681,18 +681,18 @@ FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_n
                                 *
                                 * We handle correctly cases with some <=/>= here
                                 */
-                               if ((l_pnc & ~pn_Cmp_Eq) == (r_inc_pnc & ~pn_Cmp_Eq)) {
-                                       res_pnc = (l_pnc & ~pn_Cmp_Eq) | (l_pnc & r_inc_pnc & pn_Cmp_Eq);
+                               if ((l_relation & ~ir_relation_equal) == (r_inc_relation & ~ir_relation_equal)) {
+                                       res_relation = (l_relation & ~ir_relation_equal) | (l_relation & r_inc_relation & ir_relation_equal);
 
-                                       if ((pnc == res_pnc) || ((pnc & ~pn_Cmp_Eq) == res_pnc)) {
-                                               DBG_OUT_TR(l_pnc, l_bound, r_pnc, r_bound, pnc, "true");
+                                       if ((relation == res_relation) || ((relation & ~ir_relation_equal) == res_relation)) {
+                                               DBG_OUT_TR(l_relation, l_bound, r_relation, r_bound, relation, "true");
                                                DBG_EVAL_CONFIRM(cmp);
                                                return tarval_b_true;
                                        } else {
-                                               pn_Cmp neg_pnc = get_negated_pnc(pnc, get_irn_mode(left));
+                                               ir_relation neg_relation = get_negated_relation(relation);
 
-                                               if ((neg_pnc == res_pnc) || ((neg_pnc & ~pn_Cmp_Eq) == res_pnc)) {
-                                                       DBG_OUT_TR(l_pnc, l_bound, r_pnc, r_bound, pnc, "false");
+                                               if ((neg_relation == res_relation) || ((neg_relation & ~ir_relation_equal) == res_relation)) {
+                                                       DBG_OUT_TR(l_relation, l_bound, r_relation, r_bound, relation, "false");
                                                        DBG_EVAL_CONFIRM(cmp);
                                                        return tarval_b_false;
                                                }
@@ -707,26 +707,26 @@ FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_n
                 */
                if (left == r_bound) {
                        /*
-                        * l == bound(r) AND pnc(r) == pnc:
+                        * l == bound(r) AND relation(r) == relation:
                         *
                         * We know that a CMP b and check for that
                         */
-                       if ((r_pnc == pnc) || (r_pnc == (pnc & ~pn_Cmp_Eq))) {
-                               DBG_OUT_R(r_pnc, r_bound, left, pnc, right, "true");
+                       if ((r_relation == relation) || (r_relation == (relation & ~ir_relation_equal))) {
+                               DBG_OUT_R(r_relation, r_bound, left, relation, right, "true");
                                DBG_EVAL_CONFIRM(cmp);
                                return tarval_b_true;
                        }
                        /*
-                        * l == bound(r) AND pnc(r) != pnc:
+                        * l == bound(r) AND relation(r) != relation:
                         *
                         * We know that a CMP b and check for a ~CMP b
                         */
                        else {
                                mode    = get_irn_mode(left);
-                               neg_pnc = get_negated_pnc(pnc, mode);
+                               neg_relation = get_negated_relation(relation);
 
-                               if ((r_pnc == neg_pnc) || (r_pnc == (neg_pnc & ~pn_Cmp_Eq))) {
-                                       DBG_OUT_R(r_pnc, r_bound, left, pnc, right, "false");
+                               if ((r_relation == neg_relation) || (r_relation == (neg_relation & ~ir_relation_equal))) {
+                                       DBG_OUT_R(r_relation, r_bound, left, relation, right, "false");
                                        DBG_EVAL_CONFIRM(cmp);
                                        return tarval_b_false;
                                }
@@ -735,9 +735,9 @@ FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_n
 
                /* now, try interval magic */
                tv = compare_iv(
-                       get_interval(&l_iv, l_bound, l_pnc),
-                       get_interval(&r_iv, r_bound, r_pnc),
-                       pnc);
+                       get_interval(&l_iv, l_bound, l_relation),
+                       get_interval(&r_iv, r_bound, r_relation),
+                       relation);
 
                if (tv != tarval_bad) {
                        DBG_EVAL_CONFIRM(cmp);
@@ -752,26 +752,26 @@ FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_n
         */
        if (right == l_bound) {
                /*
-                * r == bound(l) AND pnc(l) == pnc:
+                * r == bound(l) AND relation(l) == relation:
                 *
                 * We know that a CMP b and check for that
                 */
-               if ((l_pnc == pnc) || (l_pnc == (pnc & ~pn_Cmp_Eq))) {
-                       DBG_OUT_L(l_pnc, l_bound, left, pnc, right, "true");
+               if ((l_relation == relation) || (l_relation == (relation & ~ir_relation_equal))) {
+                       DBG_OUT_L(l_relation, l_bound, left, relation, right, "true");
                        DBG_EVAL_CONFIRM(cmp);
                        return tarval_b_true;
                }
                /*
-                * r == bound(l) AND pnc(l) is Not(pnc):
+                * r == bound(l) AND relation(l) is Not(relation):
                 *
                 * We know that a CMP b and check for a ~CMP b
                 */
                else {
                        mode = get_irn_mode(left);
-                       neg_pnc = get_negated_pnc(pnc, mode);
+                       neg_relation = get_negated_relation(relation);
 
-                       if ((l_pnc == neg_pnc) || (l_pnc == (neg_pnc & ~pn_Cmp_Eq))) {
-                               DBG_OUT_L(l_pnc, l_bound, left, pnc, right, "false");
+                       if ((l_relation == neg_relation) || (l_relation == (neg_relation & ~ir_relation_equal))) {
+                               DBG_OUT_L(l_relation, l_bound, left, relation, right, "false");
                                DBG_EVAL_CONFIRM(cmp);
                                return tarval_b_false;
                        }
@@ -783,24 +783,24 @@ FIRM_API ir_tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_n
 
        if (tv != tarval_bad) {
                tv = compare_iv(
-                       get_interval(&l_iv, l_bound, l_pnc),
+                       get_interval(&l_iv, l_bound, l_relation),
                        get_interval_from_tv(&r_iv, tv),
-                       pnc);
+                       relation);
        } else {
 check_null_case:
                /* check some other cases */
-               if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) &&
+               if ((relation == ir_relation_equal || relation == ir_relation_less_greater) &&
                        is_Const(right) && is_Const_null(right)) {
                        /* for == 0 or != 0 we have some special tools */
                        ir_mode       *mode = get_irn_mode(left);
                        const ir_node *dummy;
                        if (mode_is_reference(mode)) {
                                if (value_not_null(left, &dummy)) {
-                                       tv = pnc == pn_Cmp_Eq ? tarval_b_false : tarval_b_true;
+                                       tv = relation == ir_relation_equal ? tarval_b_false : tarval_b_true;
                                }
                        } else {
                                if (value_not_zero(left, &dummy)) {
-                                       tv = pnc == pn_Cmp_Eq ? tarval_b_false : tarval_b_true;
+                                       tv = relation == ir_relation_equal ? tarval_b_false : tarval_b_true;
                                }
                        }
                }
@@ -844,36 +844,36 @@ static int iv_snprintf(char *buf, size_t len, const interval_t *iv)
 /**
  * For debugging. Prints an interval compare.
  *
- * @param l_iv  the left interval
- * @param r_iv  the right interval
- * @param pnc   the compare relation
+ * @param l_iv      the left interval
+ * @param r_iv      the right interval
+ * @param relation  the compare relation
  */
-static void print_iv_cmp(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
+static void print_iv_cmp(const interval_t *l_iv, const interval_t *r_iv, ir_relation relation)
 {
        char sl[128], sr[128];
 
        iv_snprintf(sl, sizeof(sl), l_iv);
        iv_snprintf(sr, sizeof(sr), r_iv);
 
-       ir_printf("%s %= %s", sl, pnc, sr);
+       ir_printf("%s %= %s", sl, relation, sr);
 }  /* print_iv_cmp */
 
 /**
  * For debugging. call *compare_iv() and prints inputs and result.
  *
- * @param l_iv  the left interval
- * @param r_iv  the right interval
- * @param pnc   the compare relation
+ * @param l_iv     the left interval
+ * @param r_iv     the right interval
+ * @param relation the compare relation
  */
-static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
+static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, ir_relation relation)
 {
-       tarval *tv = (compare_iv)(l_iv, r_iv, pnc);
+       tarval *tv = (compare_iv)(l_iv, r_iv, relation);
 
        if (tv == tarval_bad)
        return tv;
 
        ir_printf("In %e:\n", get_irg_entity(current_ir_graph));
-       print_iv_cmp(l_iv, r_iv, pnc);
+       print_iv_cmp(l_iv, r_iv, relation);
        ir_printf(" = %T\n", tv);
        return tv;
 }  /* compare_iv_dbg */
index ac55061..6ad21a3 100644 (file)
@@ -578,9 +578,9 @@ static ir_entity *find_constant_entity(ir_node *ptr)
                                        if (tlower == tarval_bad || tupper == tarval_bad)
                                                return NULL;
 
-                                       if (tarval_cmp(tv, tlower) & pn_Cmp_Lt)
+                                       if (tarval_cmp(tv, tlower) == ir_relation_less)
                                                return NULL;
-                                       if (tarval_cmp(tupper, tv) & pn_Cmp_Lt)
+                                       if (tarval_cmp(tupper, tv) == ir_relation_less)
                                                return NULL;
 
                                        /* ok, bounds check finished */
@@ -725,9 +725,9 @@ ptr_arith:
                        if (tlower == tarval_bad || tupper == tarval_bad)
                                return NULL;
 
-                       if (tarval_cmp(tv_index, tlower) & pn_Cmp_Lt)
+                       if (tarval_cmp(tv_index, tlower) == ir_relation_less)
                                return NULL;
-                       if (tarval_cmp(tupper, tv_index) & pn_Cmp_Lt)
+                       if (tarval_cmp(tupper, tv_index) == ir_relation_less)
                                return NULL;
 
                        /* ok, bounds check finished */
@@ -951,9 +951,9 @@ ptr_arith:
                        if (tlower == tarval_bad || tupper == tarval_bad)
                                return NULL;
 
-                       if (tarval_cmp(tv_index, tlower) & pn_Cmp_Lt)
+                       if (tarval_cmp(tv_index, tlower) == ir_relation_less)
                                return NULL;
-                       if (tarval_cmp(tupper, tv_index) & pn_Cmp_Lt)
+                       if (tarval_cmp(tupper, tv_index) == ir_relation_less)
                                return NULL;
 
                        /* ok, bounds check finished */
index 9c821ba..0394b2b 100644 (file)
@@ -858,7 +858,7 @@ int tarval_is_minus_one(ir_tarval *a)
 /*
  * comparison
  */
-pn_Cmp tarval_cmp(ir_tarval *a, ir_tarval *b)
+ir_relation tarval_cmp(ir_tarval *a, ir_tarval *b)
 {
        carry_flag = -1;
 
@@ -867,10 +867,10 @@ pn_Cmp tarval_cmp(ir_tarval *a, ir_tarval *b)
        }
 
        if (a == tarval_undefined || b == tarval_undefined)
-               return pn_Cmp_False;
+               return ir_relation_false;
 
        if (a->mode != b->mode)
-               return pn_Cmp_False;
+               return ir_relation_false;
 
        if (get_mode_n_vector_elems(a->mode) > 1) {
                /* vector arithmetic not implemented yet */
@@ -883,36 +883,33 @@ pn_Cmp tarval_cmp(ir_tarval *a, ir_tarval *b)
        case irms_memory:
        case irms_auxiliary:
                if (a == b)
-                       return pn_Cmp_Eq;
-               return pn_Cmp_False;
+                       return ir_relation_equal;
+               return ir_relation_false;
 
        case irms_float_number:
-               /* it should be safe to enable this even if other arithmetic is disabled */
-               /*if (no_float)
-                       return pn_Cmp_False;*/
                /*
                 * BEWARE: we cannot compare a == b here, because
                 * a NaN is always Unordered to any other value, even to itself!
                 */
                switch (fc_comp((const fp_value*) a->value, (const fp_value*) b->value)) {
-               case -1: return pn_Cmp_Lt;
-               case  0: return pn_Cmp_Eq;
-               case  1: return pn_Cmp_Gt;
-               case  2: return pn_Cmp_Uo;
-               default: return pn_Cmp_False;
+               case -1: return ir_relation_less;
+               case  0: return ir_relation_equal;
+               case  1: return ir_relation_greater;
+               case  2: return ir_relation_unordered;
+               default: return ir_relation_false;
                }
        case irms_reference:
        case irms_int_number:
                if (a == b)
-                       return pn_Cmp_Eq;
-               return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
+                       return ir_relation_equal;
+               return sc_comp(a->value, b->value) == 1 ? ir_relation_greater : ir_relation_less;
 
        case irms_internal_boolean:
                if (a == b)
-                       return pn_Cmp_Eq;
-               return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
+                       return ir_relation_equal;
+               return a == tarval_b_true ? ir_relation_greater : ir_relation_less;
        }
-       return pn_Cmp_False;
+       return ir_relation_false;
 }
 
 /*
index 12797f1..9329bef 100755 (executable)
@@ -60,7 +60,7 @@ def get_io_type(type, attrname, node):
        elif type == "long" and node.name == "Proj":
                importcmd = "long %s = read_long(env);" % attrname
                exportcmd = """write_long(env, %(val)s);"""
-       elif type == "pn_Cmp" or type == "ir_where_alloc":
+       elif type == "ir_relation" or type == "ir_where_alloc":
                importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
                exportcmd = """write_long(env, (long) %(val)s);"""
        elif type == "ir_cons_flags" and node.name == "Store":
index 0d8f646..7f55e91 100755 (executable)
@@ -302,26 +302,18 @@ class Cast(Unop):
        init     = "assert(is_atomic_type(type));"
 
 class Cmp(Binop):
-       """Returns the relation of 2 operands"""
-       outs  = [
-               ("False", "always false",                            "0"),
-               ("Eq",    "equal",                                   "1"),
-               ("Lt",    "less",                                    "2"),
-               ("Le",    "less or equal",                           "pn_Cmp_Eq|pn_Cmp_Lt"),
-               ("Gt",    "greater",                                 "4"),
-               ("Ge",    "greater or equal",                        "pn_Cmp_Eq|pn_Cmp_Gt"),
-               ("Lg",    "less or greater ('not equal' for integer numbers)", "pn_Cmp_Lt|pn_Cmp_Gt"),
-               ("Leg",   "less, equal or greater ('not unordered')", "pn_Cmp_Lt|pn_Cmp_Eq|pn_Cmp_Gt"),
-               ("Uo",    "unordered",                               "8"),
-               ("Ue",    "unordered or equal",                      "pn_Cmp_Uo|pn_Cmp_Eq"),
-               ("Ul",    "unordered or less",                       "pn_Cmp_Uo|pn_Cmp_Lt"),
-               ("Ule",   "unordered, less or equal",                "pn_Cmp_Uo|pn_Cmp_Lt|pn_Cmp_Eq"),
-               ("Ug",    "unordered or greater",                    "pn_Cmp_Uo|pn_Cmp_Gt"),
-               ("Uge",   "onordered, greater or equal",             "pn_Cmp_Uo|pn_Cmp_Gt|pn_Cmp_Eq"),
-               ("Ne",    "unordered, less or greater ('not equal' for floatingpoint numbers)", "pn_Cmp_Uo|pn_Cmp_Lt|pn_Cmp_Gt"),
-               ("True",  "always true",                             "15"),
-       ]
+       """Compares its two operands and checks wether a specified
+          relation (like less or equal) is fulfilled."""
        flags = []
+       mode  = "mode_b"
+       attrs = [
+               dict(
+                       type    = "ir_relation",
+                       name    = "relation",
+                       comment = "Comparison relation"
+               )
+       ]
+       attr_struct = "cmp_attr"
 
 class Cond(Op):
        """Conditionally change control flow. There are two versions of this node:
@@ -381,9 +373,9 @@ class Confirm(Op):
        pinned   = "yes"
        attrs    = [
                dict(
-                       name    = "cmp",
-                       type    = "pn_Cmp",
-                       comment = "compare operation",
+                       name    = "relation",
+                       type    = "ir_relation",
+                       comment = "relation of value to bound",
                ),
        ]
        attr_struct = "confirm_attr"