static tree vxworks_emutls_var_init (tree var, tree decl, tree tmpl_addr) { VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 3); constructor_elt *elt; tree type = TREE_TYPE (var); tree field = TYPE_FIELDS (type); elt = VEC_quick_push (constructor_elt, v, NULL); elt->index = field; elt->value = fold_convert (TREE_TYPE (field), tmpl_addr); elt = VEC_quick_push (constructor_elt, v, NULL); field = DECL_CHAIN (field); elt->index = field; elt->value = build_int_cst (TREE_TYPE (field), 0); elt = VEC_quick_push (constructor_elt, v, NULL); field = DECL_CHAIN (field); elt->index = field; elt->value = fold_convert (TREE_TYPE (field), DECL_SIZE_UNIT (decl)); return build_constructor (type, v); }
static void require_user_regions (int from_tty) { struct mem_region *m; int ix, length; /* If we're already using a user-provided list, nothing to do. */ if (!mem_use_target) return; /* Switch to a user-provided list (possibly a copy of the current one). */ mem_use_target = 0; /* If we don't have a target-provided region list yet, then no need to warn. */ if (mem_region_list == NULL) return; /* Otherwise, let the user know how to get back. */ if (from_tty) warning (_("Switching to manual control of memory regions; use " "\"mem auto\" to fetch regions from the target again.")); /* And create a new list for the user to modify. */ length = VEC_length (mem_region_s, target_mem_region_list); mem_region_list = VEC_alloc (mem_region_s, length); for (ix = 0; VEC_iterate (mem_region_s, target_mem_region_list, ix, m); ix++) VEC_quick_push (mem_region_s, mem_region_list, m); }
struct ui_file * cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream) { cli_out_data *data = ui_out_data (uiout); struct ui_file *old; old = VEC_pop (ui_filep, data->streams); VEC_quick_push (ui_filep, data->streams, stream); return old; }
static void lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, tree expr) { unsigned i, len; tree t; /* Note that the number of slots in EXPR was read in streamer_alloc_tree when instantiating EXPR. However, the vector is empty so we cannot rely on VEC_length to know how many elements to read. So, this list is emitted as a 0-terminated list on the writer side. */ do { t = stream_read_tree (ib, data_in); if (t) VEC_quick_push (tree, BINFO_BASE_BINFOS (expr), t); } while (t); BINFO_OFFSET (expr) = stream_read_tree (ib, data_in); BINFO_VTABLE (expr) = stream_read_tree (ib, data_in); BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in); len = streamer_read_uhwi (ib); if (len > 0) { VEC_reserve_exact (tree, gc, BINFO_BASE_ACCESSES (expr), len); for (i = 0; i < len; i++) { tree a = stream_read_tree (ib, data_in); VEC_quick_push (tree, BINFO_BASE_ACCESSES (expr), a); } } BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in); BINFO_SUBVTT_INDEX (expr) = stream_read_tree (ib, data_in); BINFO_VPTR_INDEX (expr) = stream_read_tree (ib, data_in); }
void init_ssanames (void) { ssa_names = VEC_alloc (tree, gc, 50); /* Version 0 is special, so reserve the first slot in the table. Though currently unused, we may use version 0 in alias analysis as part of the heuristics used to group aliases when the alias sets are too large. We use VEC_quick_push here because we know that SSA_NAMES has at least 50 elements reserved in it. */ VEC_quick_push (tree, ssa_names, NULL_TREE); free_ssanames = NULL; }
void pbb_remove_duplicate_pdrs (poly_bb_p pbb) { int i, j; poly_dr_p pdr1, pdr2; unsigned n = VEC_length (poly_dr_p, PBB_DRS (pbb)); VEC (poly_dr_p, heap) *collapsed = VEC_alloc (poly_dr_p, heap, n); for (i = 0; VEC_iterate (poly_dr_p, PBB_DRS (pbb), i, pdr1); i++) for (j = 0; VEC_iterate (poly_dr_p, collapsed, j, pdr2); j++) if (!can_collapse_pdrs (pdr1, pdr2)) VEC_quick_push (poly_dr_p, collapsed, pdr1); VEC_free (poly_dr_p, heap, collapsed); PBB_PDR_DUPLICATES_REMOVED (pbb) = true; }
void init_ssanames (struct function *fn, int size) { if (size < 50) size = 50; SSANAMES (fn) = VEC_alloc (tree, gc, size); /* Version 0 is special, so reserve the first slot in the table. Though currently unused, we may use version 0 in alias analysis as part of the heuristics used to group aliases when the alias sets are too large. We use VEC_quick_push here because we know that SSA_NAMES has at least 50 elements reserved in it. */ VEC_quick_push (tree, SSANAMES (fn), NULL_TREE); FREE_SSANAMES (fn) = NULL; SYMS_TO_RENAME (fn) = BITMAP_GGC_ALLOC (); }
/* Propagate the constant parameters found by ipcp_iterate_stage() to the function's code. */ static void ipcp_insert_stage (void) { struct cgraph_node *node, *node1 = NULL; int i; VEC (cgraph_edge_p, heap) * redirect_callers; VEC (ipa_replace_map_p,gc)* replace_trees; int node_callers, count; tree parm_tree; struct ipa_replace_map *replace_param; fibheap_t heap; long overall_size = 0, new_size = 0; long max_new_size; ipa_check_create_node_params (); ipa_check_create_edge_args (); if (dump_file) fprintf (dump_file, "\nIPA insert stage:\n\n"); dead_nodes = BITMAP_ALLOC (NULL); for (node = cgraph_nodes; node; node = node->next) if (node->analyzed) { if (node->count > max_count) max_count = node->count; overall_size += node->local.inline_summary.self_size; } max_new_size = overall_size; if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS)) max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS); max_new_size = max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1; /* First collect all functions we proved to have constant arguments to heap. */ heap = fibheap_new (); for (node = cgraph_nodes; node; node = node->next) { struct ipa_node_params *info; /* Propagation of the constant is forbidden in certain conditions. */ if (!node->analyzed || !ipcp_node_modifiable_p (node)) continue; info = IPA_NODE_REF (node); if (ipa_is_called_with_var_arguments (info)) continue; if (ipcp_const_param_count (node)) node->aux = fibheap_insert (heap, ipcp_estimate_cloning_cost (node), node); } /* Now clone in priority order until code size growth limits are met or heap is emptied. */ while (!fibheap_empty (heap)) { struct ipa_node_params *info; int growth = 0; bitmap args_to_skip; struct cgraph_edge *cs; node = (struct cgraph_node *)fibheap_extract_min (heap); node->aux = NULL; if (dump_file) fprintf (dump_file, "considering function %s\n", cgraph_node_name (node)); growth = ipcp_estimate_growth (node); if (new_size + growth > max_new_size) break; if (growth && optimize_function_for_size_p (DECL_STRUCT_FUNCTION (node->decl))) { if (dump_file) fprintf (dump_file, "Not versioning, cold code would grow"); continue; } info = IPA_NODE_REF (node); count = ipa_get_param_count (info); replace_trees = VEC_alloc (ipa_replace_map_p, gc, 1); if (node->local.can_change_signature) args_to_skip = BITMAP_GGC_ALLOC (); else args_to_skip = NULL; for (i = 0; i < count; i++) { struct ipcp_lattice *lat = ipcp_get_lattice (info, i); parm_tree = ipa_get_param (info, i); /* We can proactively remove obviously unused arguments. */ if (!ipa_is_param_used (info, i)) { if (args_to_skip) bitmap_set_bit (args_to_skip, i); continue; } if (lat->type == IPA_CONST_VALUE) { replace_param = ipcp_create_replace_map (parm_tree, lat); if (replace_param == NULL) break; VEC_safe_push (ipa_replace_map_p, gc, replace_trees, replace_param); if (args_to_skip) bitmap_set_bit (args_to_skip, i); } } if (i < count) { if (dump_file) fprintf (dump_file, "Not versioning, some parameters couldn't be replaced"); continue; } new_size += growth; /* Look if original function becomes dead after cloning. */ for (cs = node->callers; cs != NULL; cs = cs->next_caller) if (cs->caller == node || ipcp_need_redirect_p (cs)) break; if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node)) bitmap_set_bit (dead_nodes, node->uid); /* Compute how many callers node has. */ node_callers = 0; for (cs = node->callers; cs != NULL; cs = cs->next_caller) node_callers++; redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers); for (cs = node->callers; cs != NULL; cs = cs->next_caller) if (!cs->indirect_inlining_edge) VEC_quick_push (cgraph_edge_p, redirect_callers, cs); /* Redirecting all the callers of the node to the new versioned node. */ node1 = cgraph_create_virtual_clone (node, redirect_callers, replace_trees, args_to_skip, "constprop"); args_to_skip = NULL; VEC_free (cgraph_edge_p, heap, redirect_callers); replace_trees = NULL; if (node1 == NULL) continue; ipcp_process_devirtualization_opportunities (node1); if (dump_file) fprintf (dump_file, "versioned function %s with growth %i, overall %i\n", cgraph_node_name (node), (int)growth, (int)new_size); ipcp_init_cloned_node (node, node1); info = IPA_NODE_REF (node); for (i = 0; i < count; i++) { struct ipcp_lattice *lat = ipcp_get_lattice (info, i); if (lat->type == IPA_CONST_VALUE) ipcp_discover_new_direct_edges (node1, i, lat->constant); } if (dump_file) dump_function_to_file (node1->decl, dump_file, dump_flags); for (cs = node->callees; cs; cs = cs->next_callee) if (cs->callee->aux) { fibheap_delete_node (heap, (fibnode_t) cs->callee->aux); cs->callee->aux = fibheap_insert (heap, ipcp_estimate_cloning_cost (cs->callee), cs->callee); } } while (!fibheap_empty (heap)) { if (dump_file) fprintf (dump_file, "skipping function %s\n", cgraph_node_name (node)); node = (struct cgraph_node *) fibheap_extract_min (heap); node->aux = NULL; } fibheap_delete (heap); BITMAP_FREE (dead_nodes); ipcp_update_callgraph (); ipcp_update_profiling (); }
static void build_constructors (gimple swtch) { unsigned i, branch_num = gimple_switch_num_labels (swtch); tree pos = info.range_min; for (i = 1; i < branch_num; i++) { tree cs = gimple_switch_label (swtch, i); basic_block bb = label_to_block (CASE_LABEL (cs)); edge e; tree high; gimple_stmt_iterator gsi; int j; if (bb == info.final_bb) e = find_edge (info.switch_bb, bb); else e = single_succ_edge (bb); gcc_assert (e); while (tree_int_cst_lt (pos, CASE_LOW (cs))) { int k; for (k = 0; k < info.phi_count; k++) { constructor_elt *elt; elt = VEC_quick_push (constructor_elt, info.constructors[k], NULL); elt->index = int_const_binop (MINUS_EXPR, pos, info.range_min, 0); elt->value = info.default_values[k]; } pos = int_const_binop (PLUS_EXPR, pos, integer_one_node, 0); } gcc_assert (tree_int_cst_equal (pos, CASE_LOW (cs))); j = 0; if (CASE_HIGH (cs)) high = CASE_HIGH (cs); else high = CASE_LOW (cs); for (gsi = gsi_start_phis (info.final_bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple phi = gsi_stmt (gsi); tree val = PHI_ARG_DEF_FROM_EDGE (phi, e); tree low = CASE_LOW (cs); pos = CASE_LOW (cs); do { constructor_elt *elt; elt = VEC_quick_push (constructor_elt, info.constructors[j], NULL); elt->index = int_const_binop (MINUS_EXPR, pos, info.range_min, 0); elt->value = val; pos = int_const_binop (PLUS_EXPR, pos, integer_one_node, 0); } while (!tree_int_cst_lt (high, pos) && tree_int_cst_lt (low, pos)); j++; } } }