Implement binary emitters for FldCW, FnstCW and fistp.
[libfirm] / ir / be / beirgmod.c
index ac09a21..843ce75 100644 (file)
 
 #include "be_t.h"
 #include "bechordal_t.h"
-#include "bearch_t.h"
-#include "besched_t.h"
+#include "bearch.h"
+#include "besched.h"
 #include "belive_t.h"
-#include "benode_t.h"
+#include "benode.h"
 #include "beutil.h"
 #include "beinsn_t.h"
 #include "bessaconstr.h"
-#include "beirg_t.h"
+#include "beirg.h"
 #include "beirgmod.h"
 #include "bemodule.h"
 
@@ -85,7 +85,6 @@ ir_node *insert_Perm_after(be_irg_t *birg,
 {
        be_lv_t *lv     = birg->lv;
        ir_node *bl     = is_Block(pos) ? pos : get_nodes_block(pos);
-       ir_graph *irg   = get_irn_irg(bl);
        ir_nodeset_t          live;
        ir_nodeset_iterator_t iter;
 
@@ -114,7 +113,7 @@ ir_node *insert_Perm_after(be_irg_t *birg,
        }
        ir_nodeset_destroy(&live);
 
-       perm = be_new_Perm(cls, irg, bl, n, nodes);
+       perm = be_new_Perm(cls, bl, n, nodes);
        sched_add_after(pos, perm);
        free(nodes);
 
@@ -125,7 +124,7 @@ ir_node *insert_Perm_after(be_irg_t *birg,
                be_ssa_construction_env_t senv;
 
                ir_mode *mode = get_irn_mode(perm_op);
-               ir_node *proj = new_r_Proj(irg, bl, perm, mode, i);
+               ir_node *proj = new_r_Proj(bl, perm, mode, i);
                arch_set_irn_register(proj, reg);
 
                curr = proj;
@@ -184,16 +183,29 @@ static void remove_empty_block(ir_node *block)
 
                assert(succ_block == NULL);
                succ_block = get_edge_src_irn(edge);
+               if (has_Block_entity(succ_block) && has_Block_entity(block)) {
+                       /*
+                        * Currently we can add only one label for a block.
+                        * Therefore we cannot combine them if  both block already have one.
+                        */
+                       goto check_preds;
+               }
 
                set_irn_n(succ_block, pos, pred);
        }
 
+       if (has_Block_entity(block)) {
+               /* move the label to the successor block */
+               ir_entity *entity = get_Block_entity(block);
+               set_Block_entity(succ_block, entity);
+       }
+
        /* there can be some non-scheduled Pin nodes left in the block, move them
         * to the succ block (Pin) or pred block (Sync) */
        foreach_out_edge_safe(block, edge, next) {
                node = get_edge_src_irn(edge);
 
-               if(node == jump)
+               if (node == jump)
                        continue;
                if (is_Block(node)) {
                        /* a Block->Block edge: This should be the MacroBlock
@@ -201,8 +213,11 @@ static void remove_empty_block(ir_node *block)
                        assert(get_Block_MacroBlock(node) == block && "Wrong Block->Block edge");
                        continue;
                }
+               /* we simply kill Pins, because there are some strange interactions
+                * between jump threading, which produce PhiMs with Pins, we simply
+                * kill the pins here, everything is scheduled anyway */
                if (is_Pin(node)) {
-                       set_nodes_block(node, succ_block);
+                       exchange(node, get_Pin_op(node));
                        continue;
                }
                if (is_Sync(node)) {
@@ -246,9 +261,9 @@ int be_remove_empty_blocks(ir_graph *irg)
        remove_empty_block(get_irg_end_block(irg));
        end   = get_irg_end(irg);
        arity = get_irn_arity(end);
-       for(i = 0; i < arity; ++i) {
+       for (i = 0; i < arity; ++i) {
                ir_node *pred = get_irn_n(end, i);
-               if(!is_Block(pred))
+               if (!is_Block(pred))
                        continue;
                remove_empty_block(pred);
        }