static void lookup_loc(FunctionInfo* fi, BeamInstr* orig_pc, BeamInstr* modp, int idx) { Eterm* line = (Eterm *) modp[MI_LINE_TABLE]; Eterm* low; Eterm* high; Eterm* mid; Eterm pc; if (line == 0) { return; } pc = (Eterm) (BeamInstr) orig_pc; fi->fname_ptr = (Eterm *) (BeamInstr) line[MI_LINE_FNAME_PTR]; low = (Eterm *) (BeamInstr) line[MI_LINE_FUNC_TAB+idx]; high = (Eterm *) (BeamInstr) line[MI_LINE_FUNC_TAB+idx+1]; while (high > low) { mid = low + (high-low) / 2; if (pc < mid[0]) { high = mid; } else if (pc < mid[1]) { int file; int index = mid - (Eterm *) (BeamInstr) line[MI_LINE_FUNC_TAB]; if (line[MI_LINE_LOC_SIZE] == 2) { Uint16* loc_table = (Uint16 *) (BeamInstr) line[MI_LINE_LOC_TAB]; fi->loc = loc_table[index]; } else { Uint32* loc_table = (Uint32 *) (BeamInstr) line[MI_LINE_LOC_TAB]; ASSERT(line[MI_LINE_LOC_SIZE] == 4); fi->loc = loc_table[index]; } if (fi->loc == LINE_INVALID_LOCATION) { return; } fi->needed += 3+2+3+2; file = LOC_FILE(fi->loc); if (file == 0) { /* Special case: Module name with ".erl" appended */ Atom* mod_atom = atom_tab(atom_val(fi->current[0])); fi->needed += 2*(mod_atom->len+4); } else { Atom* ap = atom_tab(atom_val((fi->fname_ptr)[file-1])); fi->needed += 2*ap->len; } return; } else { low = mid + 1; } } }
static void lookup_loc(FunctionInfo* fi, const BeamInstr* pc, BeamCodeHeader* code_hdr, int idx) { BeamCodeLineTab* lt = code_hdr->line_table; const BeamInstr** low; const BeamInstr** high; const BeamInstr** mid; if (lt == NULL) { return; } fi->fname_ptr = lt->fname_ptr; low = lt->func_tab[idx]; high = lt->func_tab[idx+1]; while (high > low) { mid = low + (high-low) / 2; if (pc < mid[0]) { high = mid; } else if (pc < mid[1]) { int file; int index = mid - lt->func_tab[0]; if (lt->loc_size == 2) { fi->loc = lt->loc_tab.p2[index]; } else { ASSERT(lt->loc_size == 4); fi->loc = lt->loc_tab.p4[index]; } if (fi->loc == LINE_INVALID_LOCATION) { return; } fi->needed += 3+2+3+2; file = LOC_FILE(fi->loc); if (file == 0) { /* Special case: Module name with ".erl" appended */ Atom* mod_atom = atom_tab(atom_val(fi->mfa->module)); fi->needed += 2*(mod_atom->len+4); } else { Atom* ap = atom_tab(atom_val((fi->fname_ptr)[file-1])); fi->needed += 2*ap->len; } return; } else { low = mid + 1; } } }
bool vect_print_dump_info (enum verbosity_levels vl) { if (vl > vect_verbosity_level) return false; if (!current_function_decl || !vect_dump) return false; if (vect_location == UNKNOWN_LOC) fprintf (vect_dump, "\n%s:%d: note: ", DECL_SOURCE_FILE (current_function_decl), DECL_SOURCE_LINE (current_function_decl)); else fprintf (vect_dump, "\n%s:%d: note: ", LOC_FILE (vect_location), LOC_LINE (vect_location)); return true; }
/* * Build a single {M,F,A,Loction} item to be part of * a stack trace. */ Eterm* erts_build_mfa_item(FunctionInfo* fi, Eterm* hp, Eterm args, Eterm* mfa_p) { BeamInstr* current = fi->current; Eterm loc = NIL; if (fi->loc != LINE_INVALID_LOCATION) { Eterm tuple; int line = LOC_LINE(fi->loc); int file = LOC_FILE(fi->loc); Eterm file_term = NIL; if (file == 0) { Atom* ap = atom_tab(atom_val(fi->current[0])); file_term = buf_to_intlist(&hp, ".erl", 4, NIL); file_term = buf_to_intlist(&hp, (char*)ap->name, ap->len, file_term); } else { Atom* ap = atom_tab(atom_val((fi->fname_ptr)[file-1])); file_term = buf_to_intlist(&hp, (char*)ap->name, ap->len, NIL); } tuple = TUPLE2(hp, am_line, make_small(line)); hp += 3; loc = CONS(hp, tuple, loc); hp += 2; tuple = TUPLE2(hp, am_file, file_term); hp += 3; loc = CONS(hp, tuple, loc); hp += 2; } if (is_list(args) || is_nil(args)) { *mfa_p = TUPLE4(hp, current[0], current[1], args, loc); } else { Eterm arity = make_small(current[2]); *mfa_p = TUPLE4(hp, current[0], current[1], arity, loc); } return hp + 5; }
unsigned vectorize_loops (void) { unsigned int i; unsigned int num_vectorized_loops = 0; unsigned int vect_loops_num; loop_iterator li; struct loop *loop; vect_loops_num = number_of_loops (); /* Bail out if there are no loops. */ if (vect_loops_num <= 1) return 0; /* Fix the verbosity level if not defined explicitly by the user. */ vect_set_dump_settings (false); init_stmt_vec_info_vec (); /* ----------- Analyze loops. ----------- */ /* If some loop was duplicated, it gets bigger number than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) if (optimize_loop_nest_for_speed_p (loop)) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); if (vect_location != UNKNOWN_LOC && vect_verbosity_level > REPORT_NONE) fprintf (vect_dump, "\nAnalyzing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); loop_vinfo = vect_analyze_loop (loop); loop->aux = loop_vinfo; if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo)) continue; if (vect_location != UNKNOWN_LOC && vect_verbosity_level > REPORT_NONE) fprintf (vect_dump, "\n\nVectorizing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); vect_transform_loop (loop_vinfo); num_vectorized_loops++; } vect_location = UNKNOWN_LOC; statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops); if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS) || (num_vectorized_loops > 0 && vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))) fprintf (vect_dump, "vectorized %u loops in function.\n", num_vectorized_loops); /* ----------- Finalize. ----------- */ mark_sym_for_renaming (gimple_vop (cfun)); for (i = 1; i < vect_loops_num; i++) { loop_vec_info loop_vinfo; loop = get_loop (i); if (!loop) continue; loop_vinfo = (loop_vec_info) loop->aux; destroy_loop_vec_info (loop_vinfo, true); loop->aux = NULL; } free_stmt_vec_info_vec (); return num_vectorized_loops > 0 ? TODO_cleanup_cfg : 0; }
unsigned vectorize_loops (void) { unsigned int i; unsigned int num_vectorized_loops = 0; unsigned int vect_loops_num; loop_iterator li; struct loop *loop; vect_loops_num = number_of_loops (); /* Bail out if there are no loops. */ if (vect_loops_num <= 1) return 0; init_stmt_vec_info_vec (); /* ----------- Analyze loops. ----------- */ /* If some loop was duplicated, it gets bigger number than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) if (optimize_loop_nest_for_speed_p (loop)) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf (MSG_ALL, "\nAnalyzing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); loop_vinfo = vect_analyze_loop (loop); loop->aux = loop_vinfo; if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo)) continue; if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf (MSG_ALL, "\n\nVectorizing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); vect_transform_loop (loop_vinfo); num_vectorized_loops++; } vect_location = UNKNOWN_LOC; statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops); if (dump_enabled_p () || (num_vectorized_loops > 0 && dump_enabled_p ())) dump_printf_loc (MSG_ALL, vect_location, "vectorized %u loops in function.\n", num_vectorized_loops); /* ----------- Finalize. ----------- */ for (i = 1; i < vect_loops_num; i++) { loop_vec_info loop_vinfo; loop = get_loop (i); if (!loop) continue; loop_vinfo = (loop_vec_info) loop->aux; destroy_loop_vec_info (loop_vinfo, true); loop->aux = NULL; } free_stmt_vec_info_vec (); return num_vectorized_loops > 0 ? TODO_cleanup_cfg : 0; }
unsigned vectorize_loops (void) { unsigned int i; unsigned int num_vectorized_loops = 0; unsigned int vect_loops_num; loop_iterator li; struct loop *loop; vect_loops_num = number_of_loops (cfun); /* Bail out if there are no loops. */ if (vect_loops_num <= 1) return 0; init_stmt_vec_info_vec (); /* ----------- Analyze loops. ----------- */ /* If some loop was duplicated, it gets bigger number than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) if (optimize_loop_nest_for_speed_p (loop)) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf (MSG_NOTE, "\nAnalyzing loop at %s:%d\n", LOC_FILE (vect_location), LOC_LINE (vect_location)); loop_vinfo = vect_analyze_loop (loop); loop->aux = loop_vinfo; if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo)) continue; if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC && dump_enabled_p ()) dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, "Vectorized loop\n"); vect_transform_loop (loop_vinfo); num_vectorized_loops++; } vect_location = UNKNOWN_LOC; statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops); if (dump_enabled_p () || (num_vectorized_loops > 0 && dump_enabled_p ())) dump_printf_loc (MSG_NOTE, vect_location, "vectorized %u loops in function.\n", num_vectorized_loops); /* ----------- Finalize. ----------- */ for (i = 1; i < vect_loops_num; i++) { loop_vec_info loop_vinfo; loop = get_loop (cfun, i); if (!loop) continue; loop_vinfo = (loop_vec_info) loop->aux; destroy_loop_vec_info (loop_vinfo, true); loop->aux = NULL; } free_stmt_vec_info_vec (); if (num_vectorized_loops > 0) { /* If we vectorized any loop only virtual SSA form needs to be updated. ??? Also while we try hard to update loop-closed SSA form we fail to properly do this in some corner-cases (see PR56286). */ rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa_only_virtuals); return TODO_cleanup_cfg; } return 0; }