delete unused code and data from 6.outs.
cuts simple test binary by 7%.
would be more except for reflection.
R=r
DELTA=126 (117 added, 4 deleted, 5 changed)
OCL=23163
CL=23237
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index 68e7ec5..f1972f8 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -708,8 +708,10 @@
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 07a0f21..a1a515f 100644
--- a/src/cmd/6l/go.c
+++ b/src/cmd/6l/go.c
@@ -514,10 +514,107 @@
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 4a2c456..6382203 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -88,6 +88,7 @@
Adr to;
Prog *forwd;
Prog* link;
+ Prog* dlink;
Prog* pcond; /* work on this */
vlong pc;
int32 line;
@@ -120,6 +121,7 @@
int32 sig;
Sym* link;
Prog* text;
+ Prog* data;
};
struct Optab
{
@@ -385,9 +387,9 @@
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* 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 0d85d38..000c6fa 100644
--- a/src/cmd/6l/list.c
+++ b/src/cmd/6l/list.c
@@ -50,6 +50,9 @@
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 @@
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 d6af049..076809a 100644
--- a/src/cmd/6l/obj.c
+++ b/src/cmd/6l/obj.c
@@ -369,9 +369,9 @@
objfile(a);
}
ignoreoptfuncs();
- // TODO(rsc): remove unused code and data
definetypestrings();
definetypesigs();
+ deadcode();
firstp = firstp->link;
if(firstp == P)
@@ -1068,11 +1068,16 @@
// 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 45617ac..6e0fd58 100644
--- a/src/cmd/6l/pass.c
+++ b/src/cmd/6l/pass.c
@@ -42,6 +42,7 @@
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 @@
p->from.sym = s;
p->from.offset = o;
p->to.type = D_CONST;
+ p->dlink = s->data;
+ s->data = p;
return p;
}