static bool graphite_initialize (isl_ctx *ctx) { if (number_of_loops (cfun) <= 1 /* FIXME: This limit on the number of basic blocks of a function should be removed when the SCOP detection is faster. */ || n_basic_blocks > PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION)) { if (dump_file && (dump_flags & TDF_DETAILS)) print_global_statistics (dump_file); isl_ctx_free (ctx); return false; } scev_reset (); recompute_all_dominators (); initialize_original_copy_tables (); cloog_state = cloog_isl_state_malloc (ctx); if (dump_file && dump_flags) dump_function_to_file (current_function_decl, dump_file, dump_flags); return true; }
void dump_function (int phase, tree fn) { FILE *stream; int flags; stream = dump_begin (phase, &flags); if (stream) { dump_function_to_file (fn, stream, flags); dump_end (phase, stream); } }
/* parsing language hook */ static void slang_parse_file () { int i; for(i = 0; i<num_in_fnames; ++i) { parse_program(in_fnames[i]); } #if 0 tree char_p = build_pointer_type (char_type_node); tree puts_type = build_function_type_list (integer_type_node, char_p, NULL_TREE); tree puts_fndecl = build_function_decl ("puts", true, puts_type); tree main_type = build_function_type_list (integer_type_node, NULL_TREE); tree main_fndecl = build_function_decl ("main", false, main_type); const char *msg = "HelloWorld , ... This is pradeeps compiler"; tree hello_str = build_string_literal (strlen(msg) + 1, msg); tree call = build_call_expr (puts_fndecl,1, hello_str); tree block = make_node(BLOCK); tree c1 = build_pointer_type (char_type_node); tree stmts = NULL_TREE ;//alloc_stmt_list (); append_to_statement_list (call, &stmts); build_function (main_fndecl, stmts, block); FILE *fd = fopen("/home/pradeep/Desktop/dump.txt","w"); gimplify_function_tree (main_fndecl); dump_function_to_file (main_fndecl, fd, 0); fclose(fd); cgraph_finalize_function (main_fndecl, false); current_function_decl = NULL_TREE; pop_cfun(); #endif }
/* 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 unsigned int execute_trace () { gimple_seq body, body_bind_body, inner_cleanup, outer_cleanup; gimple inner_try, outer_try; tree record_type, func_start_decl, func_end_decl, var_decl, function_name_decl, constructor_clobber; gimple call_func_start; gimple_stmt_iterator gsi; // build record type record_type = build_type (); // build start & end function decl func_start_decl = build_function_decl ("__start_ctrace__", record_type); func_end_decl = build_function_decl ("__end_ctrace__", record_type); // init variables of current body body = gimple_body (current_function_decl); var_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier ("__ctrace_var__"), record_type); DECL_CONTEXT (var_decl) = current_function_decl; TREE_ADDRESSABLE (var_decl) = 1; declare_vars (var_decl, body, false); TREE_USED (var_decl) = 1; // mimic __FUNCTION__ builtin. function_name_decl = make_fname_decl (); declare_vars (function_name_decl, body, false); // construct inner try // init calls call_func_start = gimple_build_call ( func_start_decl, 2, build1 (ADDR_EXPR, build_pointer_type (record_type), var_decl), build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (function_name_decl)), function_name_decl)); // make inner clean up inner_cleanup = gimple_build_call ( func_end_decl, 2, build1 (ADDR_EXPR, build_pointer_type (record_type), var_decl), build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (function_name_decl)), function_name_decl)); // update inner try body_bind_body = gimple_bind_body (body); inner_try = gimple_build_try (body_bind_body, inner_cleanup, GIMPLE_TRY_FINALLY); gsi = gsi_start (inner_try); gsi_insert_before (&gsi, call_func_start, GSI_NEW_STMT); // construct outer try constructor_clobber = make_node (CONSTRUCTOR); TREE_THIS_VOLATILE (constructor_clobber) = 1; TREE_TYPE (constructor_clobber) = TREE_TYPE (var_decl); outer_cleanup = gimple_build_assign (var_decl, constructor_clobber); // update outer try outer_try = gimple_build_try (call_func_start, outer_cleanup, GIMPLE_TRY_FINALLY); // update body bind body gimple_bind_set_body (body, outer_try); if (dump_file) { dump_function_to_file (current_function_decl, dump_file, TDF_TREE | TDF_BLOCKS | TDF_VERBOSE); } // exit (0); return 0; }