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
/* internal only */
#define D_SIZE (D_NONE+40)
#define D_PCREL (D_NONE+41)
/*
* this is the ranlib header
......
......@@ -824,6 +824,7 @@ enum
D_INDIR, /* additive */
D_SIZE = D_INDIR + D_INDIR, /* 6l internal */
D_PCREL,
T_TYPE = 1<<0,
T_INDEX = 1<<1,
......
......@@ -344,10 +344,8 @@ phsh(ElfPhdr *ph, ElfShdr *sh)
void
asmb(void)
{
Prog *p;
int32 v, magic;
int a, dynsym;
uchar *op1;
vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink;
vlong symdatva = SYMDATVA;
ElfEhdr *eh;
......@@ -366,35 +364,8 @@ asmb(void)
elfsymo = 0;
seek(cout, HEADR, 0);
pc = INITTEXT;
for(cursym = textp; cursym != nil; cursym = cursym->next) {
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();
codeblk(pc, segtext.sect->len);
pc += segtext.sect->len;
/* output read-only data in text segment */
sect = segtext.sect->next;
......
......@@ -94,8 +94,8 @@ struct Prog
Adr from;
Adr to;
Prog* forwd;
Prog* comefrom;
Prog* link;
Prog* dlink;
Prog* pcond; /* work on this */
vlong pc;
int32 spadj;
......
This diff is collapsed.
......@@ -499,6 +499,7 @@ enum
D_CONST2 = D_INDIR+D_INDIR,
D_SIZE, /* 8l internal */
D_PCREL,
T_TYPE = 1<<0,
T_INDEX = 1<<1,
......
......@@ -156,6 +156,9 @@ relocsym(Sym *s)
case D_ADDR:
o = symaddr(r->sym);
break;
case D_PCREL:
o = symaddr(r->sym) - (s->value + r->off + r->siz);
break;
case D_SIZE:
o = r->sym->size;
break;
......@@ -190,11 +193,8 @@ reloc(void)
for(s=textp; s!=S; s=s->next)
relocsym(s);
for(s=datap; s!=S; s=s->next) {
if(!s->reachable)
diag("unerachable? %s", s->name);
for(s=datap; s!=S; s=s->next)
relocsym(s);
}
}
void
......@@ -341,6 +341,70 @@ blk(Sym *allsym, int32 addr, int32 size)
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
datblk(int32 addr, int32 size)
{
......@@ -348,6 +412,9 @@ datblk(int32 addr, int32 size)
int32 eaddr;
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);
/* again for printing */
......@@ -363,10 +430,8 @@ datblk(int32 addr, int32 size)
if(sym->value >= eaddr)
break;
if(addr < sym->value) {
Bprint(&bso, "%-20s %.8ux|", "(pre-pad)", addr);
for(; addr < sym->value; addr++)
Bprint(&bso, " %.2ux", 0);
Bprint(&bso, "\n");
Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(pre-pad)", addr);
addr = sym->value;
}
Bprint(&bso, "%-20s %.8ux|", sym->name, addr);
p = sym->p;
......@@ -379,11 +444,9 @@ datblk(int32 addr, int32 size)
Bprint(&bso, "\n");
}
if(addr < eaddr) {
Bprint(&bso, "%-20s %.8ux|", "(post-pad)", addr);
for(; addr < eaddr; addr++)
Bprint(&bso, " %.2ux", 0);
}
if(addr < eaddr)
Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(post-pad)", addr);
Bprint(&bso, "%-20s %.8ux|\n", "", eaddr);
}
void
......
......@@ -132,6 +132,7 @@ char* expandpkg(char*, char*);
void deadcode(void);
void ewrite(int, void*, int);
Reloc* addrel(Sym*);
void codeblk(int32, int32);
void datblk(int32, int32);
Sym* datsort(Sym*);
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