PhiNode* new_phi_node(int src_count) { PhiNode *phi = create_phi_node(the_suif_env, NULL, false); while (src_count-- > 0) phi->append_src(NULL); return phi; }
static tree create_tailcall_accumulator (const char *label, basic_block bb, tree init) { tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl)); if (POINTER_TYPE_P (ret_type)) ret_type = sizetype; tree tmp = make_temp_ssa_name (ret_type, NULL, label); gimple phi; phi = create_phi_node (tmp, bb); /* RET_TYPE can be a float when -ffast-maths is enabled. */ add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb), UNKNOWN_LOCATION); return PHI_RESULT (phi); }
static gphi * input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in, struct function *fn) { unsigned HOST_WIDE_INT ix; tree phi_result; int i, len; gphi *result; ix = streamer_read_uhwi (ib); phi_result = (*SSANAMES (fn))[ix]; len = EDGE_COUNT (bb->preds); result = create_phi_node (phi_result, bb); /* We have to go through a lookup process here because the preds in the reconstructed graph are generally in a different order than they were in the original program. */ for (i = 0; i < len; i++) { tree def = stream_read_tree (ib, data_in); int src_index = streamer_read_uhwi (ib); bitpack_d bp = streamer_read_bitpack (ib); /* Do not cache a location - we do not have API to get pointer to the location in PHI statement and we may trigger reallocation. */ location_t arg_loc = stream_input_location_now (&bp, data_in); basic_block sbb = BASIC_BLOCK_FOR_FN (fn, src_index); edge e = NULL; int j; for (j = 0; j < len; j++) if (EDGE_PRED (bb, j)->src == sbb) { e = EDGE_PRED (bb, j); break; } add_phi_arg (result, def, e, arg_loc); } return result; }
static gimple input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in, struct function *fn) { unsigned HOST_WIDE_INT ix; tree phi_result; int i, len; gimple result; ix = streamer_read_uhwi (ib); phi_result = VEC_index (tree, SSANAMES (fn), ix); len = EDGE_COUNT (bb->preds); result = create_phi_node (phi_result, bb); SSA_NAME_DEF_STMT (phi_result) = result; /* We have to go through a lookup process here because the preds in the reconstructed graph are generally in a different order than they were in the original program. */ for (i = 0; i < len; i++) { tree def = stream_read_tree (ib, data_in); int src_index = streamer_read_uhwi (ib); location_t arg_loc = lto_input_location (ib, data_in); basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index); edge e = NULL; int j; for (j = 0; j < len; j++) if (EDGE_PRED (bb, j)->src == sbb) { e = EDGE_PRED (bb, j); break; } add_phi_arg (result, def, e, arg_loc); } return result; }
DesignFlowStep_Status compute_implicit_calls::InternalExec() { tree_nodeRef node = TM->get_tree_node_const(function_id); function_decl * fd = GetPointer<function_decl>(node); if (!fd || !fd->body) { PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Node is not a function or it hasn't a body"); return DesignFlowStep_Status::UNCHANGED; } bool changed = false; std::list<std::pair<tree_nodeRef, unsigned int>> to_be_lowered_memset; unsigned int max_loop_id = 0; statement_list * sl = GetPointer<statement_list>(GET_NODE(fd->body)); THROW_ASSERT(sl, "Body is not a statement_list"); std::map<unsigned int, blocRef>::iterator it_bb, it_bb_end = sl->list_of_bloc.end(); for(it_bb = sl->list_of_bloc.begin(); it_bb != it_bb_end ; it_bb++) { if (it_bb->second->number == BB_ENTRY || it_bb->second->number == BB_EXIT) continue; max_loop_id = std::max(max_loop_id, it_bb->second->loop_id); for(const auto stmt : it_bb->second->CGetStmtList()) { tree_nodeRef tn = GET_NODE(stmt); if(tn->get_kind() == gimple_assign_K) { gimple_assign* gm = GetPointer<gimple_assign>(tn); INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Analyzing node " + tn->ToString()); /// check for implicit memset/memcpy calls tree_nodeRef op0 = GET_NODE(gm->op0); tree_nodeRef op1 = GET_NODE(gm->op1); unsigned int op0_type_index, op1_type_index; tree_nodeRef op0_type = tree_helper::get_type_node(op0, op0_type_index); tree_nodeRef op1_type = tree_helper::get_type_node(op1, op1_type_index); bool is_a_vector_bitfield = false; if(op1->get_kind() == bit_field_ref_K) { bit_field_ref* bfr = GetPointer<bit_field_ref>(op1); if(tree_helper::is_a_vector(TM, GET_INDEX_NODE(bfr->op0))) is_a_vector_bitfield = true; } bool load_candidate = (op1->get_kind() == bit_field_ref_K && !is_a_vector_bitfield) ||op1->get_kind() == component_ref_K || op1->get_kind() == indirect_ref_K || op1->get_kind() == misaligned_indirect_ref_K || op1->get_kind() == mem_ref_K || op1->get_kind() == array_ref_K || op1->get_kind() == target_mem_ref_K || op1->get_kind() == target_mem_ref461_K; if(op1->get_kind() == realpart_expr_K || op1->get_kind() == imagpart_expr_K) { enum kind code1 = GET_NODE(GetPointer<unary_expr>(op1)->op)->get_kind(); if((code1 == bit_field_ref_K && !is_a_vector_bitfield) || code1 == component_ref_K || code1 == indirect_ref_K || code1 == bit_field_ref_K || code1 == misaligned_indirect_ref_K || code1 == mem_ref_K || code1 == array_ref_K || code1 == target_mem_ref_K || code1 == target_mem_ref461_K) load_candidate = true; if(code1 == var_decl_K) load_candidate = true; } bool store_candidate = op0->get_kind() == bit_field_ref_K || op0->get_kind() == component_ref_K || op0->get_kind() == indirect_ref_K || op0->get_kind() == misaligned_indirect_ref_K || op0->get_kind() == mem_ref_K || op0->get_kind() == array_ref_K || op0->get_kind() == target_mem_ref_K || op0->get_kind() == target_mem_ref461_K; if(op0->get_kind() == realpart_expr_K || op0->get_kind() == imagpart_expr_K) { enum kind code0 = GET_NODE(GetPointer<unary_expr>(op0)->op)->get_kind(); if(code0 == component_ref_K || code0 == indirect_ref_K || code0 == bit_field_ref_K || code0 == misaligned_indirect_ref_K || code0 == mem_ref_K || code0 == array_ref_K || code0 == target_mem_ref_K || code0 == target_mem_ref461_K) store_candidate = true; if(code0 == var_decl_K) store_candidate = true; } if(!gm->clobber && !gm->init_assignment && op0_type && op1_type && ((op0_type->get_kind()== record_type_K && op1_type->get_kind()== record_type_K && op1->get_kind() != view_convert_expr_K) || (op0_type->get_kind()== union_type_K && op1_type->get_kind()== union_type_K && op1->get_kind() != view_convert_expr_K) || (op0_type->get_kind() == array_type_K) || (store_candidate && load_candidate) ) ) { changed = true; if(op1->get_kind() == constructor_K && GetPointer<constructor>(op1) && GetPointer<constructor>(op1)->list_of_idx_valu.size() == 0) { mem_ref * mr = GetPointer<mem_ref>(op0); THROW_ASSERT(mr, "unexpected condition"); unsigned int var = tree_helper::get_base_index(TM, GET_INDEX_NODE(mr->op0)); bool do_lowering = var != 0; if(do_lowering) { auto type_index = tree_helper::get_type_index(TM, var); const auto type_node = TM->get_tree_node_const(type_index); do_lowering = type_node->get_kind() == array_type_K; if(do_lowering) { const auto element_type = tree_helper::CGetElements(type_node); const auto element_type_kind = element_type->get_kind(); if(not (element_type_kind == boolean_type_K or element_type_kind == CharType_K or element_type_kind == enumeral_type_K or element_type_kind == integer_type_K or element_type_kind == pointer_type_K or element_type_kind == record_type_K)) { do_lowering = false; THROW_ASSERT(element_type_kind == array_type_K or element_type_kind == nullptr_type_K or element_type_kind == type_pack_expansion_K or element_type_kind == complex_type_K or element_type_kind == function_type_K or element_type_kind == lang_type_K or element_type_kind == method_type_K or element_type_kind == offset_type_K or element_type_kind == qual_union_type_K or element_type_kind == record_type_K or element_type_kind == reference_type_K or element_type_kind == set_type_K or element_type_kind == template_type_parm_K or element_type_kind == typename_type_K or element_type_kind == union_type_K or element_type_kind == vector_type_K or element_type_kind == void_type_K, element_type->get_kind_text()); } } } if(do_lowering) to_be_lowered_memset.push_front(std::make_pair(stmt,it_bb->second->number)); else { unsigned int memset_function_id = TM->function_index("__builtin_memset"); THROW_ASSERT(AppM->GetFunctionBehavior(memset_function_id)->GetBehavioralHelper()->has_implementation(), "inconsistent behavioral helper"); AppM->GetCallGraphManager()->AddCallPoint(function_id, memset_function_id, GET_INDEX_NODE(stmt), FunctionEdgeInfo::CallType::direct_call); } } else { unsigned int memcpy_function_id = TM->function_index("__builtin_memcpy"); THROW_ASSERT(AppM->GetFunctionBehavior(memcpy_function_id)->GetBehavioralHelper()->has_implementation(), "inconsistent behavioral helper"); AppM->GetCallGraphManager()->AddCallPoint(function_id, memcpy_function_id, GET_INDEX_NODE(stmt), FunctionEdgeInfo::CallType::direct_call); } } INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Analyzed node " + tn->ToString()); } } } /// do the memset transformations for(auto stmt_bb_pair : to_be_lowered_memset) { INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Transforming (" + STR(stmt_bb_pair.first->index) + ")" + STR(stmt_bb_pair.first)); auto BB1_index = stmt_bb_pair.second; auto BB1_block = sl->list_of_bloc[BB1_index]; ///create BBN1 const auto BBN1_block_index = (sl->list_of_bloc.rbegin())->first + 1; INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created BB" + STR(BBN1_block_index)); auto BBN1_block = blocRef(new bloc(BBN1_block_index)); sl->list_of_bloc[BBN1_block_index] = BBN1_block; max_loop_id++; BBN1_block->loop_id = max_loop_id; BBN1_block->schedule = BB1_block->schedule; ///Add BBN1 predecessor as BB1_index basic block BBN1_block->list_of_pred.push_back(BB1_index); BBN1_block->list_of_pred.push_back(BBN1_block_index); ///create BBN2 const auto BBN2_block_index = (sl->list_of_bloc.rbegin())->first + 1; INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created BB" + STR(BBN2_block_index)); auto BBN2_block = blocRef(new bloc(BBN2_block_index)); sl->list_of_bloc[BBN2_block_index] = BBN2_block; BBN2_block->loop_id = BB1_block->loop_id; BBN2_block->schedule = BB1_block->schedule; ///Add BBN2 predecessor as BBN1 basic block BBN2_block->list_of_pred.push_back(BBN1_block_index); ///Add BBN2 successor as BB1 basic block BBN2_block->list_of_succ = BB1_block->list_of_succ; /// fix true and false edges BBN2_block->true_edge = BB1_block->true_edge; BB1_block->true_edge = 0; BBN2_block->false_edge = BB1_block->false_edge; BB1_block->false_edge = 0; BB1_block->list_of_succ.clear(); BB1_block->list_of_succ.push_back(BBN1_block_index); ///Add BBN1 successor as succ basic block BBN1_block->list_of_succ.push_back(BBN1_block_index); BBN1_block->true_edge = BBN1_block_index; BBN1_block->list_of_succ.push_back(BBN2_block_index); BBN1_block->false_edge = BBN2_block_index; /// Fix BBN2 successors for(auto succ: BBN2_block->list_of_succ) { auto succ_block = sl->list_of_bloc[succ]; succ_block->list_of_pred.erase(std::find(succ_block->list_of_pred.begin(), succ_block->list_of_pred.end(), BB1_index)); succ_block->list_of_pred.push_back(BBN2_block_index); ///Update all the phis for(auto & phi : succ_block->CGetPhiList()) { auto gp = GetPointer<gimple_phi>(GET_NODE(phi)); for(auto & def_edge : gp->CGetDefEdgesList()) { if(def_edge.second == BB1_index) { gp->ReplaceDefEdge(TM, def_edge, gimple_phi::DefEdge(def_edge.first, BBN2_block_index)); } } } } ///The tree manipulation auto tree_man = tree_manipulationRef(new tree_manipulation(TM, parameters)); /// retrive the starting variable gimple_assign* ga = GetPointer<gimple_assign>(GET_NODE(stmt_bb_pair.first)); mem_ref * mr = GetPointer<mem_ref>(GET_NODE(ga->op0)); unsigned int var = tree_helper::get_base_index(TM, GET_INDEX_NODE(mr->op0)); tree_nodeRef init_var = mr->op0; const std::string srcp_default = ga->include_name + ":" + STR(ga->line_number) + ":" + STR(ga->column_number); auto type_index = tree_helper::get_type_index(TM, var); tree_nodeConstRef type_node = TM->CGetTreeNode(type_index); THROW_ASSERT(type_node->get_kind() == array_type_K, "unexpected condition"); while (type_node->get_kind() == array_type_K) type_node = tree_helper::CGetElements(type_node); tree_nodeRef offset_type = tree_man->create_size_type(); tree_nodeRef pt = tree_man->create_pointer_type(type_node); /// add a cast tree_nodeRef nop_init_var = tree_man->create_unary_operation(pt, init_var, srcp_default, nop_expr_K); tree_nodeRef nop_init_var_ga = tree_man->CreateGimpleAssign(pt, nop_init_var, BB1_index, srcp_default); init_var = GetPointer<gimple_assign>(GET_NODE(nop_init_var_ga))->op0; INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---adding cast statement " + GET_NODE(nop_init_var_ga)->ToString()); ///Create phi for the induction variable of BBN1 tree_nodeRef new_induction_var; ///The list of def edge which contains for the moment only the value coming from the forward edge std::vector<std::pair<tree_nodeRef, unsigned int> > list_of_def_edge; list_of_def_edge.push_back(std::pair<tree_nodeRef, unsigned int>(init_var, BB1_index)); auto phi = tree_man->create_phi_node(new_induction_var, list_of_def_edge, BBN1_block_index); BBN1_block->AddPhi(phi); gimple_phi* gp = GetPointer<gimple_phi>(GET_NODE(phi)); GetPointer<ssa_name>(GET_NODE(gp->res))->use_set = PointToSolutionRef(new PointToSolution()); GetPointer<ssa_name>(GET_NODE(gp->res))->use_set->variables.push_back(TM->GetTreeReindex(var)); /// compute the size of memory to be set with memset const auto dst_type = tree_helper::CGetType(GET_NODE(mr->op0)); const pointer_type * dst_ptr_t = GetPointer<const pointer_type>(dst_type); THROW_ASSERT(dst_ptr_t, "unexpected condition"); const auto dst_size = tree_helper::Size(dst_ptr_t->ptd); THROW_ASSERT(dst_size % 8 == 0, "unexpected condition"); const auto copy_byte_size = dst_size / 8; tree_nodeRef copy_byte_size_node = TM->CreateUniqueIntegerCst(static_cast<long long int >(copy_byte_size), GET_INDEX_NODE(offset_type)); tree_nodeRef pp = tree_man->create_binary_operation(pt, init_var, copy_byte_size_node, srcp_default, pointer_plus_expr_K); tree_nodeRef pp_ga = tree_man->CreateGimpleAssign(pt, pp, BB1_index, srcp_default); GetPointer<gimple_assign>(GET_NODE(pp_ga))->temporary_address = true; tree_nodeRef vd_limit = GetPointer<gimple_assign>(GET_NODE(pp_ga))->op0; GetPointer<ssa_name>(GET_NODE(vd_limit))->use_set = PointToSolutionRef(new PointToSolution()); GetPointer<ssa_name>(GET_NODE(vd_limit))->use_set->variables.push_back(TM->GetTreeReindex(var)); INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---adding statement " + GET_NODE(pp_ga)->ToString()); tree_nodeRef size_node = TM->CreateUniqueIntegerCst(static_cast<long long int >(tree_helper::Size(type_node)/8), GET_INDEX_NODE(offset_type)); tree_nodeRef pp_ind = tree_man->create_binary_operation(pt, gp->res, size_node, srcp_default, pointer_plus_expr_K); tree_nodeRef pp_ga_ind = tree_man->CreateGimpleAssign(pt, pp_ind, BBN1_block_index, srcp_default); GetPointer<gimple_assign>(GET_NODE(pp_ga_ind))->temporary_address = true; BBN1_block->PushBack(pp_ga_ind); tree_nodeRef vd_ind = GetPointer<gimple_assign>(GET_NODE(pp_ga_ind))->op0; GetPointer<ssa_name>(GET_NODE(vd_ind))->use_set = PointToSolutionRef(new PointToSolution()); GetPointer<ssa_name>(GET_NODE(vd_ind))->use_set->variables.push_back(TM->GetTreeReindex(var)); INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---adding statement " + GET_NODE(pp_ga_ind)->ToString()); GetPointer<gimple_phi>(GET_NODE(phi))->AddDefEdge(TM, gimple_phi::DefEdge(vd_ind, BBN1_block_index)); /// the comparison const auto boolean_type = tree_man->create_boolean_type(); const auto comparison = tree_man->create_binary_operation(boolean_type, vd_ind, vd_limit, srcp_default, ne_expr_K); tree_nodeRef comp_ga = tree_man->CreateGimpleAssign(boolean_type, comparison, BBN1_block_index, srcp_default); BBN1_block->PushBack(comp_ga); tree_nodeRef comp_res = GetPointer<gimple_assign>(GET_NODE(comp_ga))->op0; INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---comparison assign " + STR(comp_ga)); /// the gimple cond const auto gc = tree_man->create_gimple_cond(comp_res, srcp_default, BBN1_block_index); INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---gimple cond " + STR(gc)); /// restructure of the implicit memset statement tree_nodeRef zero_offset = TM->CreateUniqueIntegerCst(0, GET_INDEX_NODE(pt)); tree_nodeRef new_mem_ref = tree_man->create_binary_operation(TM->GetTreeReindex(type_node->index), gp->res, zero_offset, srcp_default, mem_ref_K); ga->op0 = new_mem_ref; tree_nodeRef zero_value = TM->CreateUniqueIntegerCst(0, type_node->index); ga->op1 = zero_value; const auto list_of_stmt = BB1_block->CGetStmtList(); bool found_memset_statement = false; ///We must use pointer since we are erasing elements in the list for(auto statement = list_of_stmt.begin(); statement != list_of_stmt.end(); statement++) { if(GET_INDEX_NODE(*statement) == GET_INDEX_CONST_NODE(stmt_bb_pair.first)) { /// move var = {}; to BBN1 found_memset_statement = true; const auto temp_statement = *statement; ///Going one step step forward to avoid invalidation of the pointer statement++; ///Moving statement BB1_block->RemoveStmt(temp_statement); BBN1_block->PushBack(temp_statement); ///Going one step back since pointer is already increment in for loop statement--; } else if(found_memset_statement) { /// move (xxxxb)* to BBN2 const auto temp_statement = *statement; ///Going one step step forward to avoid invalidation of the pointer statement++; ///Moving statement BB1_block->RemoveStmt(temp_statement); BBN2_block->PushBack(temp_statement); ///Going one step back since pointer is already increment in for loop statement--; } } THROW_ASSERT(found_memset_statement, "unexpected condition"); BB1_block->PushBack(nop_init_var_ga); BB1_block->PushBack(pp_ga); BBN1_block->PushBack(gc); INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Transformed " + STR(stmt_bb_pair.first)); } if (debug_level >= DEBUG_LEVEL_PEDANTIC or parameters->getOption<bool>(OPT_print_dot)) AppM->CGetCallGraphManager()->CGetCallGraph()->WriteDot("compute_implicit_calls" + GetSignature() + ".dot"); return changed ? DesignFlowStep_Status::SUCCESS : DesignFlowStep_Status::UNCHANGED; }
static bool factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, tree arg0, tree arg1) { gimple arg0_def_stmt = NULL, arg1_def_stmt = NULL, new_stmt; tree new_arg0 = NULL_TREE, new_arg1 = NULL_TREE; tree temp, result; gphi *newphi; gimple_stmt_iterator gsi, gsi_for_def; source_location locus = gimple_location (phi); enum tree_code convert_code; /* Handle only PHI statements with two arguments. TODO: If all other arguments to PHI are INTEGER_CST or if their defining statement have the same unary operation, we can handle more than two arguments too. */ if (gimple_phi_num_args (phi) != 2) return false; /* First canonicalize to simplify tests. */ if (TREE_CODE (arg0) != SSA_NAME) { std::swap (arg0, arg1); std::swap (e0, e1); } if (TREE_CODE (arg0) != SSA_NAME || (TREE_CODE (arg1) != SSA_NAME && TREE_CODE (arg1) != INTEGER_CST)) return false; /* Check if arg0 is an SSA_NAME and the stmt which defines arg0 is a conversion. */ arg0_def_stmt = SSA_NAME_DEF_STMT (arg0); if (!is_gimple_assign (arg0_def_stmt) || !gimple_assign_cast_p (arg0_def_stmt)) return false; /* Use the RHS as new_arg0. */ convert_code = gimple_assign_rhs_code (arg0_def_stmt); new_arg0 = gimple_assign_rhs1 (arg0_def_stmt); if (convert_code == VIEW_CONVERT_EXPR) new_arg0 = TREE_OPERAND (new_arg0, 0); if (TREE_CODE (arg1) == SSA_NAME) { /* Check if arg1 is an SSA_NAME and the stmt which defines arg1 is a conversion. */ arg1_def_stmt = SSA_NAME_DEF_STMT (arg1); if (!is_gimple_assign (arg1_def_stmt) || gimple_assign_rhs_code (arg1_def_stmt) != convert_code) return false; /* Use the RHS as new_arg1. */ new_arg1 = gimple_assign_rhs1 (arg1_def_stmt); if (convert_code == VIEW_CONVERT_EXPR) new_arg1 = TREE_OPERAND (new_arg1, 0); } else { /* If arg1 is an INTEGER_CST, fold it to new type. */ if (INTEGRAL_TYPE_P (TREE_TYPE (new_arg0)) && int_fits_type_p (arg1, TREE_TYPE (new_arg0))) { if (gimple_assign_cast_p (arg0_def_stmt)) new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1); else return false; } else return false; } /* If arg0/arg1 have > 1 use, then this transformation actually increases the number of expressions evaluated at runtime. */ if (!has_single_use (arg0) || (arg1_def_stmt && !has_single_use (arg1))) return false; /* If types of new_arg0 and new_arg1 are different bailout. */ if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1))) return false; /* Create a new PHI stmt. */ result = PHI_RESULT (phi); temp = make_ssa_name (TREE_TYPE (new_arg0), NULL); newphi = create_phi_node (temp, gimple_bb (phi)); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "PHI "); print_generic_expr (dump_file, gimple_phi_result (phi), 0); fprintf (dump_file, " changed to factor conversion out from COND_EXPR.\n"); fprintf (dump_file, "New stmt with CAST that defines "); print_generic_expr (dump_file, result, 0); fprintf (dump_file, ".\n"); } /* Remove the old cast(s) that has single use. */ gsi_for_def = gsi_for_stmt (arg0_def_stmt); gsi_remove (&gsi_for_def, true); if (arg1_def_stmt) { gsi_for_def = gsi_for_s