@@ -375,3 +375,118 @@ gimple_bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp, tree (*va
return true;
return false;
}
+
+/*
+ * Return TRUE if the cfg matches the below layout by the given b2 in
+ * the first argument. Or return FALSE.
+ *
+ * If return TRUE, the output argument b_out will be updated to the b0
+ * block as below example.
+ *
+ * If return FALSE, the output argument b_out will be NULL_BLOCK.
+ *
+ * |
+ * |
+ * v
+ * +------+
+ * | b0: |
+ * | def | +-----+
+ * | ... | | b1: |
+ * | cond |------>| def |
+ * +------+ | ... |
+ * | +-----+
+ * | |
+ * v |
+ * +-----+ |
+ * | b2: | |
+ * | def |<----------+
+ * +-----+
+ */
+static inline bool
+match_control_flow_graph_case_0 (basic_block b2, basic_block *b_out)
+{
+ *b_out = NULL;
+
+ if (EDGE_COUNT (b2->preds) != 2)
+ return false;
+
+ basic_block pred_0 = EDGE_PRED (b2, 0)->src;
+ basic_block pred_1 = EDGE_PRED (b2, 1)->src;
+
+ if (pred_0 == NULL || pred_1 == NULL)
+ return false;
+
+ if (!(EDGE_COUNT (pred_0->succs) == 2 && EDGE_COUNT (pred_1->succs) == 1)
+ && !(EDGE_COUNT (pred_0->succs) == 1 && EDGE_COUNT (pred_1->succs) == 2))
+ return false;
+
+ basic_block b0 = EDGE_COUNT (pred_0->succs) == 2 ? pred_0 : pred_1;
+ basic_block b1 = EDGE_COUNT (pred_0->succs) == 1 ? pred_0 : pred_1;
+
+ if (EDGE_COUNT (b1->preds) != 1 || EDGE_PRED (b1, 0)->src != b0)
+ return false;
+
+ *b_out = b0;
+ return true;
+}
+
+/*
+ * Return TRUE if the cfg matches the below layout by the given b3 in
+ * the first argument. Or return FALSE.
+ *
+ * If return TRUE, the output argument b_out will be updated to the b0
+ * block as below example.
+ *
+ * If return FALSE, the output argument b_out will be NULL.
+ *
+ * |
+ * |
+ * v
+ * +------+
+ * | b0: |
+ * | ... | +-----+
+ * | cond |------>| b2: |
+ * +------+ | ... |
+ * | +-----+
+ * | |
+ * v |
+ * +-----+ |
+ * | b1: | |
+ * | ... | |
+ * +-----+ |
+ * | |
+ * | |
+ * v |
+ * +-----+ |
+ * | b3: |<----------+
+ * | ... |
+ * +-----+
+ */
+static inline bool
+match_control_flow_graph_case_1 (basic_block b3, basic_block *b_out)
+{
+ *b_out = NULL;
+
+ if (EDGE_COUNT (b3->preds) != 2)
+ return false;
+
+ basic_block b1 = EDGE_PRED (b3, 0)->src;
+ basic_block b2 = EDGE_PRED (b3, 1)->src;
+
+ if (b1 == NULL || b2 == NULL)
+ return false;
+
+ if (EDGE_COUNT (b1->succs) != 1
+ || EDGE_COUNT (b1->preds) != 1
+ || EDGE_COUNT (b2->succs) != 1
+ || EDGE_COUNT (b2->preds) != 1)
+ return false;
+
+ basic_block b0 = EDGE_PRED (b1, 0)->src;
+
+ if (EDGE_COUNT (b0->succs) != 2 || EDGE_PRED (b2, 0)->src != b0)
+ return false;
+
+ *b_out = b0;
+ return true;
+}