static void gen_one_condition (tree arg, int lbub, enum tree_code tcode, const char *temp_name1, const char *temp_name2, vec<gimple> conds, unsigned *nconds) { tree lbub_real_cst, lbub_cst, float_type; tree temp, tempn, tempc, tempcn; gimple stmt1, stmt2, stmt3; float_type = TREE_TYPE (arg); lbub_cst = build_int_cst (integer_type_node, lbub); lbub_real_cst = build_real_from_int_cst (float_type, lbub_cst); temp = create_tmp_var (float_type, temp_name1); stmt1 = gimple_build_assign (temp, arg); tempn = make_ssa_name (temp, stmt1); gimple_assign_set_lhs (stmt1, tempn); tempc = create_tmp_var (boolean_type_node, temp_name2); stmt2 = gimple_build_assign (tempc, fold_build2 (tcode, boolean_type_node, tempn, lbub_real_cst)); tempcn = make_ssa_name (tempc, stmt2); gimple_assign_set_lhs (stmt2, tempcn); stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE); conds.quick_push (stmt1); conds.quick_push (stmt2); conds.quick_push (stmt3); (*nconds)++; }
static basic_block hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip, tree cond, edge e_true, bool update_dominators) { tree tmp; gcond *cond_stmt; edge e_false; basic_block new_bb, split_bb = gsi_bb (*gsip); bool dominated_e_true = false; gcc_assert (e_true->src == split_bb); if (update_dominators && get_immediate_dominator (CDI_DOMINATORS, e_true->dest) == split_bb) dominated_e_true = true; tmp = force_gimple_operand_gsi (gsip, cond, /*simple=*/true, NULL, /*before=*/true, GSI_SAME_STMT); cond_stmt = gimple_build_cond_from_tree (tmp, NULL_TREE, NULL_TREE); gsi_insert_before (gsip, cond_stmt, GSI_SAME_STMT); e_false = split_block (split_bb, cond_stmt); new_bb = e_false->dest; redirect_edge_pred (e_true, split_bb); e_true->flags &= ~EDGE_FALLTHRU; e_true->flags |= EDGE_TRUE_VALUE; e_false->flags &= ~EDGE_FALLTHRU; e_false->flags |= EDGE_FALSE_VALUE; e_false->probability = REG_BR_PROB_BASE - e_true->probability; e_false->count = split_bb->count - e_true->count; new_bb->count = e_false->count; if (update_dominators) { if (dominated_e_true) set_immediate_dominator (CDI_DOMINATORS, e_true->dest, split_bb); set_immediate_dominator (CDI_DOMINATORS, e_false->dest, split_bb); } return new_bb; }
lbub_real_cst = build_real_from_int_cst (float_type, lbub_cst); temp = create_tmp_var (float_type, temp_name1); stmt1 = gimple_build_assign (temp, arg); tempn = make_ssa_name (temp, stmt1); gimple_assign_set_lhs (stmt1, tempn); tempc = create_tmp_var (boolean_type_node, temp_name2); stmt2 = gimple_build_assign (tempc, fold_build2 (tcode, boolean_type_node, tempn, lbub_real_cst)); tempcn = make_ssa_name (tempc, stmt2); gimple_assign_set_lhs (stmt2, tempcn); stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE); VEC_quick_push (gimple, conds, stmt1); VEC_quick_push (gimple, conds, stmt2); VEC_quick_push (gimple, conds, stmt3); (*nconds)++; } /* A helper function to generate GIMPLE statements for out of input domain check. ARG is the call argument to be runtime checked, DOMAIN holds the valid domain for the given function, CONDS points to the vector holding the result GIMPLE statements. *NCONDS is the number of logical comparisons. This function produces no more than two logical comparisons, one for lower bound check, one for upper bound check. */