diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/6l/asm.c | 4 | ||||
-rw-r--r-- | src/cmd/6l/go.c | 103 | ||||
-rw-r--r-- | src/cmd/6l/l.h | 7 | ||||
-rw-r--r-- | src/cmd/6l/list.c | 5 | ||||
-rw-r--r-- | src/cmd/6l/obj.c | 11 | ||||
-rw-r--r-- | src/cmd/6l/pass.c | 3 |
6 files changed, 123 insertions, 10 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 68e7ec54c..f1972f820 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -708,8 +708,10 @@ datblk(int32 s, int32 n) if(p->to.sym) { if(p->to.sym->type == SUNDEF) ckoff(p->to.sym, o); - if(p->to.sym->type == Sxxx) + if(p->to.sym->type == Sxxx) { + curtext = p; // show useful name in diag's output diag("missing symbol %s", p->to.sym->name); + } o += p->to.sym->value; if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF) o += INITDAT; diff --git a/src/cmd/6l/go.c b/src/cmd/6l/go.c index 07a0f21d5..a1a515fb3 100644 --- a/src/cmd/6l/go.c +++ b/src/cmd/6l/go.c @@ -514,10 +514,107 @@ ignoreoptfuncs(void) if(p->to.sym != S && p->to.sym->type == SOPT) { if(p->as != ACALL) diag("bad use of optional function: %P", p); - p->as = ANOP; - p->from.type = D_NONE; - p->to.type = D_NONE; + nopout(p); } } } +static void mark(Sym*); +static int markdepth; + +static void +markdata(Prog *p, Sym *s) +{ + markdepth++; + if(p != P && debug['v'] > 1) + Bprint(&bso, "%d markdata %s\n", markdepth, s->name); + for(; p != P; p=p->dlink) + if(p->to.sym) + mark(p->to.sym); + markdepth--; +} + +static void +marktext(Prog *p) +{ + if(p == P) + return; + if(p->as != ATEXT) { + diag("marktext: %P", p); + return; + } + markdepth++; + if(debug['v'] > 1) + Bprint(&bso, "%d marktext %s\n", markdepth, p->from.sym->name); + for(p=p->link; p != P; p=p->link) { + if(p->as == ATEXT || p->as == ADATA || p->as == AGLOBL) + break; + if(p->from.sym) + mark(p->from.sym); + if(p->to.sym) + mark(p->to.sym); + } + markdepth--; +} + +static void +mark(Sym *s) +{ + if(s == S || s->reachable) + return; + s->reachable = 1; + if(s->text) + marktext(s->text); + if(s->data) + markdata(s->data, s); +} + +static void +sweeplist(Prog **first, Prog **last) +{ + int reachable; + Prog *p, *q; + + reachable = 1; + q = P; + for(p=*first; p != P; p=p->link) { + switch(p->as) { + case ATEXT: + case ADATA: + case AGLOBL: + reachable = p->from.sym->reachable; + if(!reachable) { + if(debug['v'] > 1) + Bprint(&bso, "discard %s\n", p->from.sym->name); + p->from.sym->type = Sxxx; + } + break; + } + if(reachable) { + if(q == P) + *first = p; + else + q->link = p; + q = p; + } + } + if(q == P) + *first = P; + else + q->link = P; + *last = q; +} + +void +deadcode(void) +{ + if(debug['v']) + Bprint(&bso, "%5.2f deadcode\n", cputime()); + + mark(lookup(INITENTRY, 0)); + mark(lookup("sys·morestack", 0)); + + sweeplist(&firstp, &lastp); + sweeplist(&datap, &edatap); +} + diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h index 4a2c456f2..6382203a5 100644 --- a/src/cmd/6l/l.h +++ b/src/cmd/6l/l.h @@ -88,6 +88,7 @@ struct Prog Adr to; Prog *forwd; Prog* link; + Prog* dlink; Prog* pcond; /* work on this */ vlong pc; int32 line; @@ -120,6 +121,7 @@ struct Sym int32 sig; Sym* link; Prog* text; + Prog* data; }; struct Optab { @@ -385,9 +387,9 @@ Prog* copyp(Prog*); double cputime(void); void datblk(int32, int32); void ignoreoptfuncs(void); -void definetypestrings(void); -void definetypesigs(void); void deadcode(void); +void definetypestrings(void); +void definetypesigs(void); void diag(char*, ...); void dodata(void); void doinit(void); @@ -421,6 +423,7 @@ void mkfwd(void); void* mysbrk(uint32); Prog* newdata(Sym*, int, int, int); Prog* newtext(Prog*, Sym*); +void nopout(Prog*); void nuxiinit(void); void objfile(char*); int opsize(Prog*); diff --git a/src/cmd/6l/list.c b/src/cmd/6l/list.c index 0d85d3817..000c6fa37 100644 --- a/src/cmd/6l/list.c +++ b/src/cmd/6l/list.c @@ -50,6 +50,9 @@ Pconv(Fmt *fp) Prog *p; p = va_arg(fp->args, Prog*); + if(p == P) + return fmtstrcpy(fp, "<P>"); + bigP = p; snprint(str1, sizeof(str1), "(%ld)", p->line); @@ -421,7 +424,7 @@ parsetextconst(vlong arg) textstksiz = arg & 0xffffffffLL; if(textstksiz & 0x80000000LL) textstksiz = -(-textstksiz & 0xffffffffLL); - + textarg = (arg >> 32) & 0xffffffffLL; if(textarg & 0x80000000LL) textarg = 0; diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c index d6af049d9..076809aa2 100644 --- a/src/cmd/6l/obj.c +++ b/src/cmd/6l/obj.c @@ -369,9 +369,9 @@ main(int argc, char *argv[]) objfile(a); } ignoreoptfuncs(); - // TODO(rsc): remove unused code and data definetypestrings(); definetypesigs(); + deadcode(); firstp = firstp->link; if(firstp == P) @@ -1068,11 +1068,16 @@ loop: // If we've seen an AGLOBL that said this sym was DUPOK, // ignore any more ADATA we see, which must be // redefinitions. - if(p->from.sym != S && p->from.sym->dupok) { + s = p->from.sym; + if(s != S && s->dupok) { if(debug['v']) - Bprint(&bso, "skipping %s in %s: dupok", p->from.sym->name, pn); + Bprint(&bso, "skipping %s in %s: dupok", s->name, pn); goto loop; } + if(s != S) { + p->dlink = s->data; + s->data = p; + } if(edatap == P) datap = p; else diff --git a/src/cmd/6l/pass.c b/src/cmd/6l/pass.c index 45617ac56..6e0fd5896 100644 --- a/src/cmd/6l/pass.c +++ b/src/cmd/6l/pass.c @@ -42,6 +42,7 @@ dodata(void) Bprint(&bso, "%5.2f dodata\n", cputime()); Bflush(&bso); for(p = datap; p != P; p = p->link) { + curtext = p; // for diag messages s = p->from.sym; if(p->as == ADYNT || p->as == AINIT) s->value = dtype; @@ -851,6 +852,8 @@ newdata(Sym *s, int o, int w, int t) p->from.sym = s; p->from.offset = o; p->to.type = D_CONST; + p->dlink = s->data; + s->data = p; return p; } |