place loads for stack parameters in the correct block
authorChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Wed, 10 May 2006 15:01:13 +0000 (15:01 +0000)
committerChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Wed, 10 May 2006 15:01:13 +0000 (15:01 +0000)
ir/be/ia32/ia32_transform.c

index 47703c0..d498aa6 100644 (file)
@@ -25,6 +25,7 @@
 #include "dbginfo.h"
 #include "irprintf.h"
 #include "debug.h"
+#include "irdom.h"
 
 #include "../benode_t.h"
 #include "../besched.h"
@@ -2054,6 +2055,39 @@ static ir_node *gen_Conv(ia32_transform_env_t *env) {
  *
  ********************************************/
 
+ /**
+  * Decides in which block the transformed StackParam should be placed.
+  * If the StackParam has more than one user, the dominator block of
+  * the users will be returned. In case of only one user, this is either
+  * the user block or, in case of a Phi, the predecessor block of the Phi.
+  */
+ static ir_node *get_block_transformed_stack_param(ir_node *irn) {
+        ir_node *dom_bl = NULL;
+
+        if (get_irn_n_edges(irn) == 1) {
+                ir_node *src = get_edge_src_irn(get_irn_out_edge_first(irn));
+
+                if (! is_Phi(src)) {
+                        dom_bl = get_nodes_block(src);
+                }
+                else {
+                        /* Determine on which in position of the Phi the irn is */
+                        /* and get the corresponding cfg predecessor block.     */
+
+                        int i  = get_irn_pred_pos(src, irn);
+                        assert(i >= 0 && "kaputt");
+                        dom_bl = get_Block_cfgpred_block(get_nodes_block(src), i);
+                }
+        }
+        else {
+                dom_bl = node_users_smallest_common_dominator(irn, 1);
+        }
+
+        assert(dom_bl && "dominator block not found");
+
+        return dom_bl;
+ }
+
 static ir_node *gen_be_StackParam(ia32_transform_env_t *env) {
        ir_node *new_op = NULL;
        ir_node *node   = env->irn;
@@ -2063,13 +2097,8 @@ static ir_node *gen_be_StackParam(ia32_transform_env_t *env) {
        entity  *ent    = be_get_frame_entity(node);
        ir_mode *mode   = env->mode;
 
-#if 0
-       /* If the StackParam has only one user ->     */
-       /* put it in the Block where the user resides */
-       if (get_irn_n_edges(node) == 1) {
-               env->block = get_nodes_block(get_edge_src_irn(get_irn_out_edge_first(node)));
-       }
-#endif
+       /* choose the block where to place the load */
+       env->block = get_block_transformed_stack_param(node);
 
        if (mode_is_float(mode)) {
                FP_USED(env->cg);