[PATCH 3/3, RFC] Fixup COND_EXECs before reload

Alexander Monakov amonakov@ispras.ru
Wed Oct 26 19:54:00 GMT 2011


This RFC patch implements conversion of COND_EXEC instructions to control flow
for pre-RA selective scheduler.  Something like this is needed to employ
predication support before reload.

Each COND_EXEC is converted separately to a new basic block with the
unconditional variant of the instruction, and a conditional jump around it.

I'm not sure what would be an acceptable approach here.  I'm also not sure
about the recommended way to emit JUMPs.


2011-10-26  Sergey Grechanik  <mouseentity@ispras.ru>

	* sel-sched.c (convert_cond_execs): New.  Use it...
	(sel_global_finish): ... here.
	
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index f5c6f8b..b8f2663 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtlhooks-def.h"
 #include "output.h"
 #include "emit-rtl.h"
+#include "cfghooks.h"
 
 #ifdef INSN_SCHEDULING
 #include "sel-sched-ir.h"
@@ -7978,6 +7979,60 @@ sel_global_init (void)
   init_hard_regs_data ();
 }
 
+/* Convert cond_execs to jumps before reload.  */
+static void
+convert_cond_execs (void)
+{
+  basic_block bb;
+  rtx insn;
+
+  if (reload_completed)
+    return;
+
+  FOR_EACH_BB (bb)
+   /* We don't need the safe variant because we break immediately after
+      removing the current instruction.  */
+    FOR_BB_INSNS (bb, insn)
+      if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == COND_EXEC)
+	{
+	  rtx jump;
+	  rtx cond = COND_EXEC_TEST (PATTERN (insn));
+	  rtx rcond = reversed_comparison (cond, GET_MODE (cond));
+	  rtx unpredicated = copy_rtx (COND_EXEC_CODE (PATTERN (insn)));
+
+	  /* Split bb into BB, NEW_BB, NEXT_BB (in that order).  */
+	  edge e1 = split_block (bb, insn);
+	  basic_block next_bb = e1->dest;
+	  edge e2 = split_block (bb, insn);
+	  basic_block new_bb = e2->dest;
+
+	  /* Emit conditional jump at the end of bb.  */
+	  rtx label = block_label (next_bb);
+
+          /* FIXME  There should be a better way.  */
+	  rtx jump_pat
+	   = gen_rtx_SET (GET_MODE (pc_rtx), pc_rtx,
+			  gen_rtx_IF_THEN_ELSE (GET_MODE (pc_rtx),
+						rcond,
+						gen_rtx_LABEL_REF (VOIDmode,
+								   label),
+						pc_rtx));
+
+	  make_edge (bb, next_bb, 0);
+	  jump = emit_jump_insn_after (jump_pat, BB_END (bb));
+	  JUMP_LABEL (jump) = label;
+	  LABEL_NUSES (label)++;
+
+	  emit_insn_after_noloc (unpredicated, BB_HEAD (new_bb), new_bb);
+
+	  delete_insn (insn);
+	  break;
+	}
+#ifdef ENABLE_CHECKING
+  verify_flow_info ();
+#endif
+}
+
 /* Free the global data of the scheduler.  */
 static void
 sel_global_finish (void)
@@ -7998,6 +8053,8 @@ sel_global_finish (void)
 
   free_sched_pools ();
   free_dominance_info (CDI_DOMINATORS);
+
+  convert_cond_execs ();
 }
 
 /* Return true when we need to skip selective scheduling.  Used for debugging.  */




More information about the Gcc-patches mailing list