Commit 9c204852 authored by Russ Cox's avatar Russ Cox

6l: function at a time code layout

Also change the span-dependent jump algorithm
to use fewer iterations:

* resolve forward jumps at their targets (comefrom list)
* mark jumps as small or big and only do small->big
* record whether a jump failed to be encodable

These changes mean that a function with only small
jumps can be laid out in a single iteration, and the
vast majority of functions take just two iterations.
I was seeing a maximum of 5 iterations before; the
max now is 3 and there are fewer that get even that far.

R=ken2
CC=golang-dev
https://golang.org/cl/2537041
parent 837c204a
...@@ -246,6 +246,7 @@ enum as ...@@ -246,6 +246,7 @@ enum as
/* internal only */ /* internal only */
#define D_SIZE (D_NONE+40) #define D_SIZE (D_NONE+40)
#define D_PCREL (D_NONE+41)
/* /*
* this is the ranlib header * this is the ranlib header
......
...@@ -824,6 +824,7 @@ enum ...@@ -824,6 +824,7 @@ enum
D_INDIR, /* additive */ D_INDIR, /* additive */
D_SIZE = D_INDIR + D_INDIR, /* 6l internal */ D_SIZE = D_INDIR + D_INDIR, /* 6l internal */
D_PCREL,
T_TYPE = 1<<0, T_TYPE = 1<<0,
T_INDEX = 1<<1, T_INDEX = 1<<1,
......
...@@ -344,10 +344,8 @@ phsh(ElfPhdr *ph, ElfShdr *sh) ...@@ -344,10 +344,8 @@ phsh(ElfPhdr *ph, ElfShdr *sh)
void void
asmb(void) asmb(void)
{ {
Prog *p;
int32 v, magic; int32 v, magic;
int a, dynsym; int a, dynsym;
uchar *op1;
vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink; vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink;
vlong symdatva = SYMDATVA; vlong symdatva = SYMDATVA;
ElfEhdr *eh; ElfEhdr *eh;
...@@ -366,35 +364,8 @@ asmb(void) ...@@ -366,35 +364,8 @@ asmb(void)
elfsymo = 0; elfsymo = 0;
seek(cout, HEADR, 0); seek(cout, HEADR, 0);
pc = INITTEXT; pc = INITTEXT;
codeblk(pc, segtext.sect->len);
for(cursym = textp; cursym != nil; cursym = cursym->next) { pc += segtext.sect->len;
for(p = cursym->text; p != P; p = p->link) {
if(p->pc != pc) {
if(!debug['a'])
print("%P\n", curp);
diag("phase error %llux sb %llux in %s", p->pc, pc, TNAME);
pc = p->pc;
}
curp = p;
asmins(p);
a = (andptr - and);
if(cbc < a)
cflush();
if(debug['a']) {
Bprint(&bso, pcstr, pc);
for(op1 = and; op1 < andptr; op1++)
Bprint(&bso, "%.2ux", *op1);
for(; op1 < and+Maxand; op1++)
Bprint(&bso, " ");
Bprint(&bso, "%P\n", curp);
}
memmove(cbp, and, a);
cbp += a;
pc += a;
cbc -= a;
}
}
cflush();
/* output read-only data in text segment */ /* output read-only data in text segment */
sect = segtext.sect->next; sect = segtext.sect->next;
......
...@@ -94,8 +94,8 @@ struct Prog ...@@ -94,8 +94,8 @@ struct Prog
Adr from; Adr from;
Adr to; Adr to;
Prog* forwd; Prog* forwd;
Prog* comefrom;
Prog* link; Prog* link;
Prog* dlink;
Prog* pcond; /* work on this */ Prog* pcond; /* work on this */
vlong pc; vlong pc;
int32 spadj; int32 spadj;
......
This diff is collapsed.
...@@ -499,6 +499,7 @@ enum ...@@ -499,6 +499,7 @@ enum
D_CONST2 = D_INDIR+D_INDIR, D_CONST2 = D_INDIR+D_INDIR,
D_SIZE, /* 8l internal */ D_SIZE, /* 8l internal */
D_PCREL,
T_TYPE = 1<<0, T_TYPE = 1<<0,
T_INDEX = 1<<1, T_INDEX = 1<<1,
......
...@@ -156,6 +156,9 @@ relocsym(Sym *s) ...@@ -156,6 +156,9 @@ relocsym(Sym *s)
case D_ADDR: case D_ADDR:
o = symaddr(r->sym); o = symaddr(r->sym);
break; break;
case D_PCREL:
o = symaddr(r->sym) - (s->value + r->off + r->siz);
break;
case D_SIZE: case D_SIZE:
o = r->sym->size; o = r->sym->size;
break; break;
...@@ -190,11 +193,8 @@ reloc(void) ...@@ -190,11 +193,8 @@ reloc(void)
for(s=textp; s!=S; s=s->next) for(s=textp; s!=S; s=s->next)
relocsym(s); relocsym(s);
for(s=datap; s!=S; s=s->next) { for(s=datap; s!=S; s=s->next)
if(!s->reachable)
diag("unerachable? %s", s->name);
relocsym(s); relocsym(s);
}
} }
void void
...@@ -341,6 +341,70 @@ blk(Sym *allsym, int32 addr, int32 size) ...@@ -341,6 +341,70 @@ blk(Sym *allsym, int32 addr, int32 size)
cflush(); cflush();
} }
void
codeblk(int32 addr, int32 size)
{
Sym *sym;
int32 eaddr, i, n, epc;
Prog *p;
uchar *q;
if(debug['a'])
Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, seek(cout, 0, 1));
blk(textp, addr, size);
/* again for printing */
if(!debug['a'])
return;
for(sym = textp; sym != nil; sym = sym->next) {
if(!sym->reachable)
continue;
if(sym->value >= addr)
break;
}
eaddr = addr + size;
for(; sym != nil; sym = sym->next) {
if(!sym->reachable)
continue;
if(sym->value >= eaddr)
break;
if(addr < sym->value) {
Bprint(&bso, "%-20s %.8llux|", "_", addr);
for(; addr < sym->value; addr++)
Bprint(&bso, " %.2ux", 0);
Bprint(&bso, "\n");
}
p = sym->text;
Bprint(&bso, "%-20s %.8llux| %P\n", sym->name, addr, p);
for(p = p->link; p != P; p = p->link) {
if(p->link != P)
epc = p->link->pc;
else
epc = sym->value + sym->size;
Bprint(&bso, "%.6ux\t", p->pc);
q = sym->p + p->pc - sym->value;
n = epc - p->pc;
for(i=0; i<n; i++)
Bprint(&bso, "%.2ux", *q++);
for(; i < 10; i++)
Bprint(&bso, " ");
Bprint(&bso, " | %P\n", p);
addr += n;
}
}
if(addr < eaddr) {
Bprint(&bso, "%-20s %.8llux|", "_", addr);
for(; addr < eaddr; addr++)
Bprint(&bso, " %.2ux", 0);
}
Bflush(&bso);
}
void void
datblk(int32 addr, int32 size) datblk(int32 addr, int32 size)
{ {
...@@ -348,6 +412,9 @@ datblk(int32 addr, int32 size) ...@@ -348,6 +412,9 @@ datblk(int32 addr, int32 size)
int32 eaddr; int32 eaddr;
uchar *p, *ep; uchar *p, *ep;
if(debug['a'])
Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, seek(cout, 0, 1));
blk(datap, addr, size); blk(datap, addr, size);
/* again for printing */ /* again for printing */
...@@ -363,10 +430,8 @@ datblk(int32 addr, int32 size) ...@@ -363,10 +430,8 @@ datblk(int32 addr, int32 size)
if(sym->value >= eaddr) if(sym->value >= eaddr)
break; break;
if(addr < sym->value) { if(addr < sym->value) {
Bprint(&bso, "%-20s %.8ux|", "(pre-pad)", addr); Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(pre-pad)", addr);
for(; addr < sym->value; addr++) addr = sym->value;
Bprint(&bso, " %.2ux", 0);
Bprint(&bso, "\n");
} }
Bprint(&bso, "%-20s %.8ux|", sym->name, addr); Bprint(&bso, "%-20s %.8ux|", sym->name, addr);
p = sym->p; p = sym->p;
...@@ -379,11 +444,9 @@ datblk(int32 addr, int32 size) ...@@ -379,11 +444,9 @@ datblk(int32 addr, int32 size)
Bprint(&bso, "\n"); Bprint(&bso, "\n");
} }
if(addr < eaddr) { if(addr < eaddr)
Bprint(&bso, "%-20s %.8ux|", "(post-pad)", addr); Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(post-pad)", addr);
for(; addr < eaddr; addr++) Bprint(&bso, "%-20s %.8ux|\n", "", eaddr);
Bprint(&bso, " %.2ux", 0);
}
} }
void void
......
...@@ -132,6 +132,7 @@ char* expandpkg(char*, char*); ...@@ -132,6 +132,7 @@ char* expandpkg(char*, char*);
void deadcode(void); void deadcode(void);
void ewrite(int, void*, int); void ewrite(int, void*, int);
Reloc* addrel(Sym*); Reloc* addrel(Sym*);
void codeblk(int32, int32);
void datblk(int32, int32); void datblk(int32, int32);
Sym* datsort(Sym*); Sym* datsort(Sym*);
void reloc(void); void reloc(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment