avoid code duplication: use be_add_missing_keeps in ia32 backend also
authorMatthias Braun <matze@braunis.de>
Fri, 16 Jul 2010 16:25:31 +0000 (16:25 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 16 Jul 2010 16:25:31 +0000 (16:25 +0000)
[r27754]

ir/be/beabihelper.c
ir/be/bearch.h
ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_transform.c
ir/be/ia32/ia32_transform.h

index fcfe868..7deb489 100644 (file)
@@ -423,7 +423,7 @@ static void add_missing_keep_walker(ir_node *node, void *data)
 
                req = arch_get_out_register_req(node, i);
                cls = req->cls;
-               if (cls == NULL) {
+               if (cls == NULL || (cls->flags & arch_register_class_flag_manual_ra)) {
                        continue;
                }
 
index a17dc39..bfa1de8 100644 (file)
@@ -43,7 +43,7 @@
 typedef enum arch_register_class_flags_t {
        arch_register_class_flag_none      = 0,
        /** don't do automatic register allocation for this class */
-       arch_register_class_flag_manual_ra = 1U << 0,
+       arch_register_class_flag_manual_ra = 1U << 0,
        /** the register models an abstract state (example: fpu rounding mode) */
        arch_register_class_flag_state     = 1U << 1
 } arch_register_class_flags_t;
@@ -75,7 +75,7 @@ typedef enum arch_register_type_t {
  */
 typedef enum arch_register_req_type_t {
        /** No register requirement. */
-       arch_register_req_type_none              = 0,
+       arch_register_req_type_none              = 0,
        /** All registers in the class are allowed. */
        arch_register_req_type_normal            = 1U << 0,
        /** Only a real subset of the class is allowed. */
@@ -380,7 +380,7 @@ struct arch_inverse_t {
 struct arch_irn_ops_t {
 
        /**
-        * Get the register requirements for a given operand.
+        * Get the register requirements for a given operand.
         * @param irn The node.
         * @param pos The operand's position
         * @return    The register requirements for the selected operand.
index 3be7fe6..4b00da2 100644 (file)
@@ -71,6 +71,7 @@
 #include "../beflags.h"
 #include "../betranshlp.h"
 #include "../belistsched.h"
+#include "../beabihelper.h"
 
 #include "bearch_ia32_t.h"
 
@@ -999,7 +1000,7 @@ static void ia32_before_ra(void *self)
        be_sched_fix_flags(cg->irg, &ia32_reg_classes[CLASS_ia32_flags],
                           &flags_remat);
 
-       ia32_add_missing_keeps(cg);
+       be_add_missing_keeps(cg->irg);
 }
 
 
index b6c1828..bba8f65 100644 (file)
@@ -5779,90 +5779,6 @@ static void ia32_pretransform_node(void)
        get_fpcw();
 }
 
-/**
- * Walker, checks if all ia32 nodes producing more than one result have their
- * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
- */
-static void add_missing_keep_walker(ir_node *node, void *data)
-{
-       int              n_outs, i;
-       unsigned         found_projs = 0;
-       const ir_edge_t *edge;
-       ir_mode         *mode = get_irn_mode(node);
-       ir_node         *last_keep;
-       (void) data;
-       if (mode != mode_T)
-               return;
-       if (!is_ia32_irn(node))
-               return;
-
-       n_outs = arch_irn_get_n_outs(node);
-       if (n_outs <= 0)
-               return;
-       if (is_ia32_SwitchJmp(node))
-               return;
-
-       assert(n_outs < (int) sizeof(unsigned) * 8);
-       foreach_out_edge(node, edge) {
-               ir_node *proj = get_edge_src_irn(edge);
-               int      pn;
-
-               /* The node could be kept */
-               if (is_End(proj))
-                       continue;
-
-               if (get_irn_mode(proj) == mode_M)
-                       continue;
-
-               pn = get_Proj_proj(proj);
-               assert(pn < n_outs);
-               found_projs |= 1 << pn;
-       }
-
-
-       /* are keeps missing? */
-       last_keep = NULL;
-       for (i = 0; i < n_outs; ++i) {
-               ir_node                     *block;
-               ir_node                     *in[1];
-               const arch_register_req_t   *req;
-               const arch_register_class_t *cls;
-
-               if (found_projs & (1 << i)) {
-                       continue;
-               }
-
-               req = arch_get_out_register_req(node, i);
-               cls = req->cls;
-               if (cls == NULL) {
-                       continue;
-               }
-               if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
-                       continue;
-               }
-
-               block = get_nodes_block(node);
-               in[0] = new_r_Proj(node, arch_register_class_mode(cls), i);
-               if (last_keep != NULL) {
-                       be_Keep_add_node(last_keep, cls, in[0]);
-               } else {
-                       last_keep = be_new_Keep(block, 1, in);
-                       if (sched_is_scheduled(node)) {
-                               sched_add_after(node, last_keep);
-                       }
-               }
-       }
-}
-
-/**
- * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
- * and keeps them.
- */
-void ia32_add_missing_keeps(ia32_code_gen_t *cg)
-{
-       irg_walk_graph(cg->irg, add_missing_keep_walker, NULL, NULL);
-}
-
 /**
  * Post-process all calls if we are in SSE mode.
  * The ABI requires that the results are in st0, copy them
index 624dbf9..bd8dd2e 100644 (file)
@@ -52,8 +52,6 @@ typedef enum {
  */
 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct);
 
-void ia32_add_missing_keeps(ia32_code_gen_t *cg);
-
 /**
  * Skip all Down-Conv's on a given node and return the resulting node.
  */
@@ -62,4 +60,4 @@ ir_node *ia32_skip_downconv(ir_node *node);
 /** Initialize the ia32 instruction selector. */
 void ia32_init_transform(void);
 
-#endif /* FIRM_BE_IA32_IA32_TRANSFORM_H */
+#endif