OSDN Git Service

ObjC NeXT, split encode-support code from next-mapping.h
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index b302591..81e988b 100644 (file)
@@ -1,5 +1,5 @@
 /* A pass for lowering trees to RTL.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -516,9 +516,11 @@ update_alias_info_with_stack_vars (void)
          unsigned int uid = DECL_PT_UID (decl);
          /* We should never end up partitioning SSA names (though they
             may end up on the stack).  Neither should we allocate stack
-            space to something that is unused and thus unreferenced.  */
+            space to something that is unused and thus unreferenced, except
+            for -O0 where we are preserving even unreferenced variables.  */
          gcc_assert (DECL_P (decl)
-                     && referenced_var_lookup (DECL_UID (decl)));
+                     && (!optimize
+                         || referenced_var_lookup (DECL_UID (decl))));
          bitmap_set_bit (part, uid);
          *((bitmap *) pointer_map_insert (decls_to_partitions,
                                           (void *)(size_t) uid)) = part;
@@ -684,8 +686,7 @@ partition_stack_vars (void)
        }
     }
 
-  if (optimize)
-    update_alias_info_with_stack_vars ();
+  update_alias_info_with_stack_vars ();
 }
 
 /* A debugging aid for expand_used_vars.  Dump the generated partitions.  */
@@ -1693,7 +1694,14 @@ maybe_cleanup_end_of_block (edge e, rtx last)
        {
          insn = PREV_INSN (insn);
          if (JUMP_P (NEXT_INSN (insn)))
-           delete_insn (NEXT_INSN (insn));
+           {
+             if (!any_condjump_p (NEXT_INSN (insn)))
+               {
+                 gcc_assert (BARRIER_P (NEXT_INSN (NEXT_INSN (insn))));
+                 delete_insn (NEXT_INSN (NEXT_INSN (insn)));
+               }
+             delete_insn (NEXT_INSN (insn));
+           }
        }
     }
 }
@@ -2552,15 +2560,20 @@ expand_debug_expr (tree exp)
       }
 
     case MEM_REF:
-      /* ??? FIXME.  */
-      if (!integer_zerop (TREE_OPERAND (exp, 1)))
-       return NULL;
-      /* Fallthru.  */
     case INDIRECT_REF:
       op0 = expand_debug_expr (TREE_OPERAND (exp, 0));
       if (!op0)
        return NULL;
 
+      if (TREE_CODE (exp) == MEM_REF)
+       {
+         op1 = expand_debug_expr (TREE_OPERAND (exp, 1));
+         if (!op1 || !CONST_INT_P (op1))
+           return NULL;
+
+         op0 = plus_constant (op0, INTVAL (op1));
+       }
+
       if (POINTER_TYPE_P (TREE_TYPE (exp)))
        as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
       else
@@ -2690,7 +2703,7 @@ expand_debug_expr (tree exp)
            enum machine_mode opmode = GET_MODE (op0);
 
            if (opmode == VOIDmode)
-             opmode = mode1;
+             opmode = TYPE_MODE (TREE_TYPE (tem));
 
            /* This condition may hold if we're expanding the address
               right past the end of an array that turned out not to
@@ -2711,7 +2724,8 @@ expand_debug_expr (tree exp)
                                     ? SIGN_EXTRACT
                                     : ZERO_EXTRACT, mode,
                                     GET_MODE (op0) != VOIDmode
-                                    ? GET_MODE (op0) : mode1,
+                                    ? GET_MODE (op0)
+                                    : TYPE_MODE (TREE_TYPE (tem)),
                                     op0, GEN_INT (bitsize), GEN_INT (bitpos));
       }
 
@@ -3914,6 +3928,8 @@ gimple_expand_cfg (void)
       else
        set_curr_insn_source_location (cfun->function_start_locus);
     }
+  else
+    set_curr_insn_source_location (UNKNOWN_LOCATION);
   set_curr_insn_block (DECL_INITIAL (current_function_decl));
   prologue_locator = curr_insn_locator ();
 
@@ -3936,6 +3952,10 @@ gimple_expand_cfg (void)
   crtl->preferred_stack_boundary = STACK_BOUNDARY;
   cfun->cfg->max_jumptable_ents = 0;
 
+  /* Resovle the function section.  Some targets, like ARM EABI rely on knowledge
+     of the function section at exapnsion time to predict distance of calls.  */
+  resolve_unique_section (current_function_decl, 0, flag_function_sections);
+
   /* Expand the variables recorded during gimple lowering.  */
   timevar_push (TV_VAR_EXPAND);
   start_sequence ();
@@ -4065,7 +4085,19 @@ gimple_expand_cfg (void)
       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
        {
          if (e->insns.r)
-           commit_one_edge_insertion (e);
+           {
+             /* Avoid putting insns before parm_birth_insn.  */
+             if (e->src == ENTRY_BLOCK_PTR
+                 && single_succ_p (ENTRY_BLOCK_PTR)
+                 && parm_birth_insn)
+               {
+                 rtx insns = e->insns.r;
+                 e->insns.r = NULL_RTX;
+                 emit_insn_after_noloc (insns, parm_birth_insn, e->dest);
+               }
+             else
+               commit_one_edge_insertion (e);
+           }
          else
            ei_next (&ei);
        }