2014-11-25 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Nov 2014 20:20:10 +0000 (20:20 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Nov 2014 20:20:10 +0000 (20:20 +0000)
PR target/63527
* ira-lives.c (process_bb_node_lives): Check and remove conflict
of pic pseudo with pic hard reg.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218059 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ira-lives.c

index 01cf1ae..849b70e 100644 (file)
@@ -1,3 +1,9 @@
+2014-11-25  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/63527
+       * ira-lives.c (process_bb_node_lives): Check and remove conflict
+       of pic pseudo with pic hard reg.
+
 2014-11-25  Rohit  <rohitarulraj@freescale.com>
 
        PR bootstrap/63703
index 0604c47..368b118 100644 (file)
@@ -1123,8 +1123,10 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
         pessimistic, but it probably doesn't matter much in practice.  */
       FOR_BB_INSNS_REVERSE (bb, insn)
        {
+         int regno;
+         ira_allocno_t a;
          df_ref def, use;
-         bool call_p;
+         bool call_p, clear_pic_use_conflict_p;
 
          if (!NONDEBUG_INSN_P (insn))
            continue;
@@ -1134,6 +1136,21 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
                     INSN_UID (insn), loop_tree_node->parent->loop_num,
                     curr_point);
 
+         call_p = CALL_P (insn);
+         clear_pic_use_conflict_p = false;
+         /* Processing insn usage in call insn can create conflict
+            with pic pseudo and pic hard reg and that is wrong.
+            Check this situation and fix it at the end of the insn
+            processing.  */
+         if (call_p && pic_offset_table_rtx != NULL_RTX
+             && (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER
+             && (a = ira_curr_regno_allocno_map[regno]) != NULL)
+           clear_pic_use_conflict_p
+               = (find_regno_fusage (insn, USE, REAL_PIC_OFFSET_TABLE_REGNUM)
+                  && ! TEST_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS
+                                          (ALLOCNO_OBJECT (a, 0)),
+                                          REAL_PIC_OFFSET_TABLE_REGNUM));
+
          /* Mark each defined value as live.  We need to do this for
             unused values because they still conflict with quantities
             that are live at the time of the definition.
@@ -1143,7 +1160,6 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
             on a call-clobbered register.  Marking the register as
             live would stop us from allocating it to a call-crossing
             allocno.  */
-         call_p = CALL_P (insn);
          FOR_EACH_INSN_DEF (def, insn)
            if (!call_p || !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
              mark_ref_live (def);
@@ -1207,7 +1223,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
              EXECUTE_IF_SET_IN_SPARSESET (objects_live, i)
                {
                  ira_object_t obj = ira_object_id_map[i];
-                 ira_allocno_t a = OBJECT_ALLOCNO (obj);
+                 a = OBJECT_ALLOCNO (obj);
                  int num = ALLOCNO_NUM (a);
                  HARD_REG_SET this_call_used_reg_set;
 
@@ -1257,7 +1273,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
          make_early_clobber_and_input_conflicts ();
 
          curr_point++;
-
+         
          /* Mark each used value as live.  */
          FOR_EACH_INSN_USE (use, insn)
            mark_ref_live (use);
@@ -1286,6 +1302,17 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
                }
            }
 
+         if (clear_pic_use_conflict_p)
+           {
+             regno = REGNO (pic_offset_table_rtx);
+             a = ira_curr_regno_allocno_map[regno];
+             CLEAR_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (ALLOCNO_OBJECT (a, 0)),
+                                 REAL_PIC_OFFSET_TABLE_REGNUM);
+             CLEAR_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS
+                                 (ALLOCNO_OBJECT (a, 0)),
+                                 REAL_PIC_OFFSET_TABLE_REGNUM);
+           }
+
          curr_point++;
        }