From a366436782315f0bffb6b8642396d32a4bc90a2c Mon Sep 17 00:00:00 2001 From: Teddy Date: Tue, 6 May 2014 19:51:28 +0800 Subject: even more printf opt --- lib.s | 3 +- mips.c | 41 ++++++++------ semantics.c | 12 +++-- semantics.h | 3 +- ssa.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- ssa.h | 15 ++++-- 6 files changed, 210 insertions(+), 38 deletions(-) diff --git a/lib.s b/lib.s index 72b138c..3efbd17 100644 --- a/lib.s +++ b/lib.s @@ -82,7 +82,8 @@ __L14: bnez $10, __L13 __L15: # len_5 = 4 - len_4 - subu $11, $2, 4 + li $2, 4 + subu $11, $2, $11 # goto __L17 j __L17 __L16: diff --git a/mips.c b/mips.c index 6dce7f5..efb51ba 100644 --- a/mips.c +++ b/mips.c @@ -10,6 +10,7 @@ int reg_v1 = 3; int memcpy_cnt; static int save_pos[32]; static int used_reg[32]; +static CType_t func; void mips_prologue(void) { CVList_t v; @@ -60,7 +61,7 @@ void mips_prologue(void) { } printf("\t.align 2\n"); prev += align_shift(prev); - for (s = cstrs; s; s = s->next) + for (s = cstrs->next; s != cstrs; s = s->next) { int len = 1; char *p = s->str; @@ -190,7 +191,7 @@ void mips_space_alloc(void) { CBlock_t p; COList_t d; CVar_t v; - for (d = defs; d; d = d->next) + for (d = func_ir->defs; d; d = d->next) { COpr_t opr = d->opr; assert(opr->par == opr); @@ -207,7 +208,7 @@ void mips_space_alloc(void) { tmp_size += calc_size(opr->type); } } - for (p = entry; p; p = p->next) + for (p = func_ir->entry; p; p = p->next) { CInst_t i, ih = p->insts; for (i = ih->next; i != ih; i = i->next) @@ -264,7 +265,7 @@ void mips_space_alloc(void) { } prev += save_size; /* adjust offset for spilled temporaries */ - for (d = defs; d; d = d->next) + for (d = func_ir->defs; d; d = d->next) { COpr_t opr = d->opr; assert(opr->par == opr); @@ -273,7 +274,7 @@ void mips_space_alloc(void) { } prev += tmp_size; prev += align_shift(prev); - for (p = entry; p; p = p->next) + for (p = func_ir->entry; p; p = p->next) { CInst_t i, ih = p->insts; for (i = ih->next; i != ih; i = i->next) @@ -316,7 +317,9 @@ void mips_func_end(void) { void mips_generate(void) { CBlock_t p; - CType_t rt = func->rec.func.ret; + CType_t rt; + func = func_ir->func; + rt = func->rec.func.ret; /* int arg_cnt = 0; */ mips_space_alloc(); if (strcmp(func->name, "main")) @@ -324,9 +327,9 @@ void mips_generate(void) { else printf("main:\n"); mips_func_begin(); - for (p = entry; p; p = p->next) + for (p = func_ir->entry; p; p = p->next) { - if (p->ref) printf("_L%d:\n", p->id + gbbase); + if (p->ref) printf("_L%d:\n", p->id + func_ir->gbbase); CInst_t i, ih = p->insts; const char *bop; for (i = ih->next; i != ih; i = i->next) @@ -520,16 +523,24 @@ void mips_generate(void) { int j; memset(used_reg, 0, sizeof used_reg); /* NOTE: bad hack */ - if (i->src1->kind == IMMF && !strcmp(i->src1->info.str, "__print_string")) + if (i->src1->kind == IMMF) { - printf( "\tlw $a0, 0($sp)\n" - "\tli $2, 4\n" - "\tsyscall\n"); - break; + char *fname = i->src1->info.str; + int flag = 0; + if (!strcmp(fname, "__print_int")) flag = 1; + else if (!strcmp(fname, "__print_char")) flag = 11; + else if (!strcmp(fname, "__print_string")) flag = 4; + if (flag) + { + printf( "\tlw $a0, 0($sp)\n" + "\tli $2, %d\n" + "\tsyscall\n", flag); + break; + } } if (rt->type == CSTRUCT || rt->type == CUNION) used_reg[30] = 1; /* save $fp */ - for (p = defs; p; p = p->next) + for (p = func_ir->defs; p; p = p->next) { COpr_t opr = p->opr; if (opr->reg != -1 && @@ -556,7 +567,7 @@ void mips_generate(void) { for (j = 0; j < 32; j++) if (used_reg[j]) printf("\tlw $%d, %d($sp) # load reg\n", j, save_pos[j]); - for (p = defs; p; p = p->next) + for (p = func_ir->defs; p; p = p->next) { COpr_t opr = p->opr; if (opr->reg != -1 && diff --git a/semantics.c b/semantics.c index a431e25..30088ca 100644 --- a/semantics.c +++ b/semantics.c @@ -63,7 +63,6 @@ static CType_t builtin_memcpy; static CType_t builtin_print_int; static CType_t builtin_print_char; static CType_t builtin_print_string; -static int scnt = 0; CTList_t funcs; CVList_t gvars; @@ -1253,9 +1252,10 @@ ExpType semantics_exp(CNode *p, CScope_t scope) { CSList_t cstr = NEW(CSList); cstr->str = p->rec.strval; - cstr->next = cstrs; - cstr->id = scnt++; - cstrs = cstr; + (cstr->prev = cstrs->prev)->next = cstr; + (cstr->next = cstrs)->prev = cstr; + cstr->id = cstr->prev->id + 1; + /* cstrs = cstr; */ type->rec.ref = basic_type_char; res.type = type; @@ -1885,7 +1885,9 @@ void semantics_check(CNode *p) { cscope_push_type(scope, builtin_print_char, NS_ID); cscope_push_type(scope, builtin_print_string, NS_ID); /* const string counter */ - scnt = 0; + cstrs = NEW(CSList); + cstrs->id = -1; + cstrs->prev = cstrs->next = cstrs; /* check all definitions and declarations */ for (p = p->chd; p; p = p->next) { diff --git a/semantics.h b/semantics.h index b77cf2e..a7712b6 100644 --- a/semantics.h +++ b/semantics.h @@ -33,7 +33,7 @@ struct CSList { char *str; int id; int start; - CSList_t next; + CSList_t prev, next; }; typedef struct CBList *CBList_t; @@ -203,6 +203,7 @@ void def_exit(void); int calc_size(CType_t type); int align_shift(int x); +extern int scnt; extern CTList_t funcs; extern CVList_t gvars; extern CSList_t cstrs; diff --git a/ssa.c b/ssa.c index b0ea04b..f92d4f3 100644 --- a/ssa.c +++ b/ssa.c @@ -14,16 +14,18 @@ static COList_t raw_defs; /* defintion of all vars and tmps */ static int bcnt; /* block counter */ static int tcnt; /* temporary counter */ +static int gbbase; +static CBlock_t entry; +static COList_t defs; /* all defintions that have actual effects */ + /* for code generation */ -int gbbase; -CBlock_t entry; -CType_t func; -COList_t defs; /* all defintions that have actual effects */ +CFuncIR_t func_ir; COpr_t copr_create(void) { COpr_t opr = NEW(COpr); opr->type = NULL; opr->cval = NULL; + opr->range = NULL; opr->same = opr; opr->dep = 0; opr->mod = 0; @@ -322,17 +324,27 @@ void ssa_func_print(CBlock_t p) { void ssa_func(CType_t); void ssa_generate(void) { CTList_t f; - mips_prologue(); + CFuncIR_t cf, cf_list = NULL; for (f = funcs; f; f = f->next) { - func = f->type; - fprintf(stderr, "%s:\n", func->name); - ssa_func(func); + cf = NEW(CFuncIR); + ssa_func(cf->func = f->type); + cf->gbbase = gbbase; + cf->defs = defs; + cf->entry = entry; + cf->next = cf_list; + cf_list = cf; + fprintf(stderr, "%s:\n", cf->func->name); ssa_func_print(entry); - mips_generate(); gbbase += bcnt; bcnt = 0; } + mips_prologue(); + for (cf = cf_list; cf; cf = cf->next) + { + func_ir = cf; + mips_generate(); + } } #define POINTER_CONV(inst) \ @@ -1597,7 +1609,6 @@ void renaming_dfs(CBlock_t blk) { COList_t n = NEW(COList), n2; dest->sub = var->cnt++; dest->def = ih->next; /* the first inst */ - dest->range = NULL; n->opr = dest; n->next = var->stack; var->stack = n; @@ -1635,7 +1646,6 @@ void renaming_dfs(CBlock_t blk) { COList_t n = NEW(COList), n2; dest->sub = var->cnt++; dest->def = i; - dest->range = NULL; n->opr = dest; n->next = var->stack; var->stack = n; @@ -2311,6 +2321,37 @@ void strength_reduction(void) { } \ } while (0) +#define PRINT_BARE_STRING \ + do { \ + if (bp != buff) \ + { \ + CInst_t print = cinst_create(); \ + print->op = CALL; \ + print->dest = copr_create(); \ + print->dest->kind = TMP; \ + print->dest->info.var = ctmp_create(); \ + print->dest->type = i->dest->type; \ + print->src1 = copr_create(); \ + print->src1->kind = IMMF; \ + CSList_t cstr = NEW(CSList); \ + *bp = '\0'; \ + print->src1->kind = IMMF; \ + cstr->str = strdup(buff); \ + (cstr->prev = cstrs->prev)->next = cstr; \ + (cstr->next = cstrs)->prev = cstr; \ + cstr->id = cstr->prev->id + 1; \ + inst = cinst_create(); \ + inst->op = PUSH; \ + inst->src1 = copr_create(); \ + inst->src1->kind = IMMS; \ + inst->src1->info.cstr = cstr; \ + cblock_append(ibuff, inst); \ + print->src1->info.str = "__print_string"; \ + cblock_append(ibuff, print); \ + bp = buff; \ + } \ + } while (0) + int i; int call_cnt = 0; for (i = bcnt - 1; i >= 0; i--) @@ -2365,12 +2406,122 @@ void strength_reduction(void) { call_cnt++; break; case CALL: + /* if (i->src1->kind == IMMF && call_cnt == 1 && !strcmp(i->src1->info.str, "printf")) { i->src1->info.str = "__print_string"; } + */ + if (i->src1->kind == IMMF && + !strcmp(i->src1->info.str, "printf")) + { + static char buff[1024]; + char *bp = buff, *sp; + CInst_t push = i, inst, phead, np; + CBlock_t ibuff; + CSList_t fmt; + /* move to the first push */ + while (call_cnt--) push = push->prev; + if (push->src1->kind != IMMS) break; /* not a const pattern */ + ibuff = cblock_create(0); + fmt = push->src1->info.cstr; + push->prev->next = i->next; + i->next->prev = push->prev; + phead = push->prev; + np = push->next; + free(push); + push = np; + for (sp = fmt->str; *sp != '\0'; sp++) + { + if (*sp == '%') + { + CInst_t print = cinst_create(); + print->op = CALL; + print->dest = copr_create(); + print->dest->kind = TMP; + print->dest->info.var = ctmp_create(); + print->dest->type = i->dest->type; + print->src1 = copr_create(); + print->src1->kind = IMMF; + + + PRINT_BARE_STRING; + switch (*(++sp)) + { + case 'd': + { + if (push != i) + { + np = push->next; + cblock_append(ibuff, push); + push = np; + } + print->src1->info.str = "__print_int"; + cblock_append(ibuff, print); + } + break; + case 'c': + { + if (push != i) + { + np = push->next; + cblock_append(ibuff, push); + push = np; + } + print->src1->info.str = "__print_char"; + cblock_append(ibuff, print); + } + break; + case 's': + { + + if (push != i) + { + np = push->next; + cblock_append(ibuff, push); + push = np; + } + print->src1->info.str = "__print_string"; + cblock_append(ibuff, print); + } + break; + default: + { + CSList_t cstr = NEW(CSList); + cstr->str = strdup(sp - 1); + (cstr->prev = cstrs->prev)->next = cstr; + (cstr->next = cstrs)->prev = cstr; + cstr->id = cstr->prev->id + 1; + inst = cinst_create(); + inst->op = PUSH; + inst->src1 = copr_create(); + inst->src1->kind = IMMS; + inst->src1->info.cstr = cstr; + cblock_append(ibuff, inst); + for (; push != i; push = np) + { + np = push->next; + cblock_append(ibuff, push); + } + print->src1->info.str = "printf"; + cblock_append(ibuff, print); + sp = fmt->str + strlen(fmt->str) - 1; + } + break; + } + } + else *bp++ = *sp; + } + PRINT_BARE_STRING; + fmt->prev->next = fmt->next; + fmt->next->prev = fmt->prev; + free(fmt); + (i->next->prev = ibuff->insts->prev)->next = i->next; + (phead->next = ibuff->insts->next)->prev = phead; + free(ibuff); + } call_cnt = 0; break; default: ; @@ -2516,7 +2667,6 @@ void subexp_elimination_(CBlock_t b, CExpMap_t cem) { (t->prev = i)->next = t; t->dest->def = t; t->dest->type = i->dest->type; - t->dest->range = NULL; cexpmap_insert(cem, t); } else diff --git a/ssa.h b/ssa.h index 0507a5c..a85e5c7 100644 --- a/ssa.h +++ b/ssa.h @@ -158,15 +158,22 @@ CInst_t cexpmap_lookup(CExpMap_t cem, CInst_t exp); void cexpmap_clear(CExpMap_t cem); void cexpmap_destroy(CExpMap_t cem); +typedef struct CFuncIR CFuncIR; +typedef CFuncIR *CFuncIR_t; +struct CFuncIR { + int gbbase; + CBlock_t entry; + COList_t defs; + CType_t func; + CFuncIR_t next; +}; + void ssa_generate(void); COpr_t cinterv_repr(COpr_t opr); void cinst_print(FILE *stream, CInst_t inst); int overlap_with_beg(COpr_t i, int beg); -extern int gbbase; -extern CBlock_t entry; -extern COList_t defs; -extern CType_t func; +extern CFuncIR_t func_ir; extern const int avail_regs[]; extern const int MAX_AVAIL_REGS; -- cgit v1.2.3