diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2016-02-18 19:40:10 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2016-02-18 19:40:10 +0200 |
commit | 8635225f337cc96b28b411a7599962503059cc25 (patch) | |
tree | 7e74b90a3fa27cf02d8681753dea391a4824fe08 /profile.c | |
parent | 7224d3f6b8db04439e8fdf8025b99db321a3f5ea (diff) | |
download | egawk-8635225f337cc96b28b411a7599962503059cc25.tar.gz egawk-8635225f337cc96b28b411a7599962503059cc25.tar.bz2 egawk-8635225f337cc96b28b411a7599962503059cc25.zip |
Make pretty-printing and profiling chain else-if's.
Diffstat (limited to 'profile.c')
-rw-r--r-- | profile.c | 108 |
1 files changed, 68 insertions, 40 deletions
@@ -25,7 +25,7 @@ #include "awk.h" -static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header); +static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, int flags); static void pp_parenthesize(NODE *n); static void parenthesize(int type, NODE *left, NODE *right); static char *pp_list(int nargs, const char *paren, const char *delim); @@ -57,9 +57,12 @@ static FILE *prof_fp; /* where to send the profile */ static long indent_level = 0; - #define SPACEOVER 0 +#define NO_PPRINT_FLAGS 0 +#define IN_FOR_HEADER 1 +#define IN_ELSE_IF 2 + /* set_prof_file --- set the output file for profiling or pretty-printing */ void @@ -187,7 +190,7 @@ pp_free(NODE *n) /* pprint --- pretty print a program segment */ static void -pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header) +pprint(INSTRUCTION *startp, INSTRUCTION *endp, int flags) { INSTRUCTION *pc; NODE *t1; @@ -219,7 +222,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header) ip = pc->nexti; indent(ip->exec_count); if (ip != (pc + 1)->firsti) { /* non-empty pattern */ - pprint(ip->nexti, (pc + 1)->firsti, false); + pprint(ip->nexti, (pc + 1)->firsti, NO_PPRINT_FLAGS); t1 = pp_pop(); fprintf(prof_fp, "%s {", t1->pp_str); pp_free(t1); @@ -236,7 +239,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header) ip = ip->nexti; } indent_in(); - pprint(ip, (pc + 1)->lasti, false); + pprint(ip, (pc + 1)->lasti, NO_PPRINT_FLAGS); indent_out(); fprintf(prof_fp, "\t}\n\n"); pc = (pc + 1)->lasti; @@ -322,7 +325,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header) cleanup: pp_free(t2); pp_free(t1); - if (! in_for_header) + if ((flags & IN_FOR_HEADER) == 0) fprintf(prof_fp, "\n"); break; @@ -344,7 +347,7 @@ cleanup: case Op_and: case Op_or: - pprint(pc->nexti, pc->target_jmp, in_for_header); + pprint(pc->nexti, pc->target_jmp, flags); t2 = pp_pop(); t1 = pp_pop(); parenthesize(pc->opcode, t1, t2); @@ -448,7 +451,7 @@ cleanup: fprintf(prof_fp, "$%s%s%s", t1->pp_str, op2str(pc->opcode), t2->pp_str); pp_free(t2); pp_free(t1); - if (! in_for_header) + if ((flags & IN_FOR_HEADER) == 0) fprintf(prof_fp, "\n"); break; @@ -469,7 +472,7 @@ cleanup: efree(sub); } else fprintf(prof_fp, "%s %s", op2str(Op_K_delete), array); - if (! in_for_header) + if ((flags & IN_FOR_HEADER) == 0) fprintf(prof_fp, "\n"); pp_free(t1); } @@ -581,7 +584,7 @@ cleanup: } else fprintf(prof_fp, "%s%s", op2str(pc->opcode), tmp); efree(tmp); - if (! in_for_header) + if ((flags & IN_FOR_HEADER) == 0) fprintf(prof_fp, "\n"); break; @@ -699,15 +702,15 @@ cleanup: case Op_pop: t1 = pp_pop(); fprintf(prof_fp, "%s", t1->pp_str); - if (! in_for_header) + if ((flags & IN_FOR_HEADER) == 0) fprintf(prof_fp, "\n"); pp_free(t1); break; case Op_line_range: ip = pc + 1; - pprint(pc->nexti, ip->condpair_left, false); - pprint(ip->condpair_left->nexti, ip->condpair_right, false); + pprint(pc->nexti, ip->condpair_left, NO_PPRINT_FLAGS); + pprint(ip->condpair_left->nexti, ip->condpair_right, NO_PPRINT_FLAGS); t2 = pp_pop(); t1 = pp_pop(); str = pp_group3(t1->pp_str, ", ", t2->pp_str); @@ -721,12 +724,12 @@ cleanup: ip = pc + 1; indent(ip->while_body->exec_count); fprintf(prof_fp, "%s (", op2str(pc->opcode)); - pprint(pc->nexti, ip->while_body, false); + pprint(pc->nexti, ip->while_body, NO_PPRINT_FLAGS); t1 = pp_pop(); fprintf(prof_fp, "%s) {\n", t1->pp_str); pp_free(t1); indent_in(); - pprint(ip->while_body->nexti, pc->target_break, false); + pprint(ip->while_body->nexti, pc->target_break, NO_PPRINT_FLAGS); indent_out(); indent(SPACEOVER); fprintf(prof_fp, "}\n"); @@ -738,9 +741,9 @@ cleanup: indent(pc->nexti->exec_count); fprintf(prof_fp, "%s {\n", op2str(pc->opcode)); indent_in(); - pprint(pc->nexti->nexti, ip->doloop_cond, false); + pprint(pc->nexti->nexti, ip->doloop_cond, NO_PPRINT_FLAGS); indent_out(); - pprint(ip->doloop_cond, pc->target_break, false); + pprint(ip->doloop_cond, pc->target_break, NO_PPRINT_FLAGS); indent(SPACEOVER); t1 = pp_pop(); fprintf(prof_fp, "} %s (%s)\n", op2str(Op_K_while), t1->pp_str); @@ -759,24 +762,24 @@ cleanup: && pc->target_continue->opcode == Op_jmp) { fprintf(prof_fp, ";;"); } else { - pprint(pc->nexti, ip->forloop_cond, true); + pprint(pc->nexti, ip->forloop_cond, IN_FOR_HEADER); fprintf(prof_fp, "; "); if (ip->forloop_cond->opcode == Op_no_op && ip->forloop_cond->nexti == ip->forloop_body) fprintf(prof_fp, "; "); else { - pprint(ip->forloop_cond, ip->forloop_body, true); + pprint(ip->forloop_cond, ip->forloop_body, IN_FOR_HEADER); t1 = pp_pop(); fprintf(prof_fp, "%s; ", t1->pp_str); pp_free(t1); } - pprint(pc->target_continue, pc->target_break, true); + pprint(pc->target_continue, pc->target_break, IN_FOR_HEADER); } fprintf(prof_fp, ") {\n"); indent_in(); - pprint(ip->forloop_body->nexti, pc->target_continue, false); + pprint(ip->forloop_body->nexti, pc->target_continue, NO_PPRINT_FLAGS); indent_out(); indent(SPACEOVER); fprintf(prof_fp, "}\n"); @@ -801,7 +804,7 @@ cleanup: item, op2str(Op_in_array), array); indent_in(); pp_free(t1); - pprint(ip->forloop_body->nexti, pc->target_break, false); + pprint(ip->forloop_body->nexti, pc->target_break, NO_PPRINT_FLAGS); indent_out(); indent(SPACEOVER); fprintf(prof_fp, "}\n"); @@ -812,11 +815,11 @@ cleanup: case Op_K_switch: ip = pc + 1; fprintf(prof_fp, "%s (", op2str(pc->opcode)); - pprint(pc->nexti, ip->switch_start, false); + pprint(pc->nexti, ip->switch_start, NO_PPRINT_FLAGS); t1 = pp_pop(); fprintf(prof_fp, "%s) {\n", t1->pp_str); pp_free(t1); - pprint(ip->switch_start, ip->switch_end, false); + pprint(ip->switch_start, ip->switch_end, NO_PPRINT_FLAGS); indent(SPACEOVER); fprintf(prof_fp, "}\n"); pc = pc->target_break; @@ -832,13 +835,13 @@ cleanup: } else fprintf(prof_fp, "%s:\n", op2str(pc->opcode)); indent_in(); - pprint(pc->stmt_start->nexti, pc->stmt_end->nexti, false); + pprint(pc->stmt_start->nexti, pc->stmt_end->nexti, NO_PPRINT_FLAGS); indent_out(); break; case Op_K_if: fprintf(prof_fp, "%s (", op2str(pc->opcode)); - pprint(pc->nexti, pc->branch_if, false); + pprint(pc->nexti, pc->branch_if, NO_PPRINT_FLAGS); t1 = pp_pop(); fprintf(prof_fp, "%s) {", t1->pp_str); pp_free(t1); @@ -848,22 +851,47 @@ cleanup: fprintf(prof_fp, " # %ld", ip->exec_count); fprintf(prof_fp, "\n"); indent_in(); - pprint(ip->nexti, pc->branch_else, false); + pprint(ip->nexti, pc->branch_else, NO_PPRINT_FLAGS); indent_out(); pc = pc->branch_else; - if (pc->nexti->opcode == Op_no_op) { + if (pc->nexti->opcode == Op_no_op) { /* no following else */ indent(SPACEOVER); fprintf(prof_fp, "}\n"); } + /* + * See next case; turn off the flag so that the + * following else is correctly indented. + */ + flags &= ~IN_ELSE_IF; break; case Op_K_else: - fprintf(prof_fp, "} %s {\n", op2str(pc->opcode)); - indent_in(); - pprint(pc->nexti, pc->branch_end, false); - indent_out(); - indent(SPACEOVER); - fprintf(prof_fp, "}\n"); + /* + * If possible, chain else-if's together on the + * same line. + * + * See awkgram.y:mk_condition to understand + * what is being checked here. + * + * Op_exec_count follows Op_K_else, check the + * opcode of the following instruction. + * Additionally, check that the subsequent if + * terminates where this else does; in that case + * it's ok to compact the if to follow the else. + */ + + fprintf(prof_fp, "} %s ", op2str(pc->opcode)); + if (pc->nexti->nexti->opcode == Op_K_if + && pc->branch_end == pc->nexti->nexti->branch_else->lasti) { + pprint(pc->nexti, pc->branch_end, IN_ELSE_IF); + } else { + fprintf(prof_fp, "{\n", op2str(pc->opcode)); + indent_in(); + pprint(pc->nexti, pc->branch_end, NO_PPRINT_FLAGS); + indent_out(); + indent(SPACEOVER); + fprintf(prof_fp, "}\n"); + } pc = pc->branch_end; break; @@ -872,14 +900,14 @@ cleanup: NODE *f, *t, *cond; size_t len; - pprint(pc->nexti, pc->branch_if, false); + pprint(pc->nexti, pc->branch_if, NO_PPRINT_FLAGS); ip = pc->branch_if; - pprint(ip->nexti, pc->branch_else, false); + pprint(ip->nexti, pc->branch_else, NO_PPRINT_FLAGS); ip = pc->branch_else->nexti; pc = ip->nexti; assert(pc->opcode == Op_cond_exp); - pprint(pc->nexti, pc->branch_end, false); + pprint(pc->nexti, pc->branch_end, NO_PPRINT_FLAGS); f = pp_pop(); t = pp_pop(); @@ -898,7 +926,7 @@ cleanup: break; case Op_exec_count: - if (! in_for_header) + if (flags == NO_PPRINT_FLAGS) indent(pc->exec_count); break; @@ -1000,7 +1028,7 @@ dump_prog(INSTRUCTION *code) /* \n on purpose, with \n in ctime() output */ fprintf(prof_fp, _("\t# gawk profile, created %s\n"), ctime(& now)); print_lib_list(prof_fp); - pprint(code, NULL, false); + pprint(code, NULL, NO_PPRINT_FLAGS); } /* prec_level --- return the precedence of an operator, for paren tests */ @@ -1579,7 +1607,7 @@ pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED) } fprintf(prof_fp, ")\n\t{\n"); indent_in(); - pprint(pc->nexti->nexti, NULL, false); /* function body */ + pprint(pc->nexti->nexti, NULL, NO_PPRINT_FLAGS); /* function body */ indent_out(); fprintf(prof_fp, "\t}\n"); return 0; |