mirror of
https://github.com/golang/go
synced 2024-11-23 18:20:04 -07:00
cmd/gc: move reg.c into portable code
Now there is only one registerizer shared among all the systems. There are some unfortunate special cases based on arch.thechar in reg.c, to preserve bit-for-bit compatibility during the refactoring. Most are probably bugs one way or another and should be revisited. Change-Id: I153b435c0eaa05bbbeaf8876822eeb6dedaae3cf Reviewed-on: https://go-review.googlesource.com/3883 Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
b8a3e88ea7
commit
ad88fd1d4a
@ -66,14 +66,22 @@ main(int argc, char **argv)
|
|||||||
arch.ginscall = ginscall;
|
arch.ginscall = ginscall;
|
||||||
arch.igen = igen;
|
arch.igen = igen;
|
||||||
arch.linkarchinit = linkarchinit;
|
arch.linkarchinit = linkarchinit;
|
||||||
|
arch.peep = peep;
|
||||||
arch.proginfo = proginfo;
|
arch.proginfo = proginfo;
|
||||||
arch.regalloc = regalloc;
|
arch.regalloc = regalloc;
|
||||||
arch.regfree = regfree;
|
arch.regfree = regfree;
|
||||||
arch.regopt = regopt;
|
|
||||||
arch.regtyp = regtyp;
|
arch.regtyp = regtyp;
|
||||||
arch.sameaddr = sameaddr;
|
arch.sameaddr = sameaddr;
|
||||||
arch.smallindir = smallindir;
|
arch.smallindir = smallindir;
|
||||||
arch.stackaddr = stackaddr;
|
arch.stackaddr = stackaddr;
|
||||||
|
arch.excludedregs = excludedregs;
|
||||||
|
arch.RtoB = RtoB;
|
||||||
|
arch.FtoB = RtoB;
|
||||||
|
arch.BtoR = BtoR;
|
||||||
|
arch.BtoF = BtoF;
|
||||||
|
arch.optoas = optoas;
|
||||||
|
arch.doregbits = doregbits;
|
||||||
|
arch.regnames = regnames;
|
||||||
|
|
||||||
gcmain(argc, argv);
|
gcmain(argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -159,3 +159,19 @@ int sameaddr(Addr*, Addr*);
|
|||||||
int smallindir(Addr*, Addr*);
|
int smallindir(Addr*, Addr*);
|
||||||
int stackaddr(Addr*);
|
int stackaddr(Addr*);
|
||||||
Prog* unpatch(Prog*);
|
Prog* unpatch(Prog*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reg.c
|
||||||
|
*/
|
||||||
|
uint64 excludedregs(void);
|
||||||
|
uint64 RtoB(int);
|
||||||
|
uint64 FtoB(int);
|
||||||
|
int BtoR(uint64);
|
||||||
|
int BtoF(uint64);
|
||||||
|
uint64 doregbits(int);
|
||||||
|
char** regnames(int*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* peep.c
|
||||||
|
*/
|
||||||
|
void peep(Prog*);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
static Prog* appendpp(Prog*, int, int, int, int32, int, int, int32);
|
static Prog* appendpp(Prog*, int, int, int, int32, int, int, int32);
|
||||||
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0);
|
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0);
|
||||||
|
179
src/cmd/5g/opt.h
179
src/cmd/5g/opt.h
@ -1,179 +0,0 @@
|
|||||||
// Inferno utils/5c/gc.h
|
|
||||||
// http://code.google.com/p/inferno-os/source/browse/utils/5c/gc.h
|
|
||||||
//
|
|
||||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
||||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
||||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
||||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
||||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
|
||||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
#define Z N
|
|
||||||
#define Adr Addr
|
|
||||||
|
|
||||||
#define D_HI TYPE_NONE
|
|
||||||
#define D_LO TYPE_NONE
|
|
||||||
|
|
||||||
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
|
|
||||||
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
|
|
||||||
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
|
|
||||||
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
|
|
||||||
|
|
||||||
#define CLOAD 5
|
|
||||||
#define CREF 5
|
|
||||||
#define CINF 1000
|
|
||||||
#define LOOP 3
|
|
||||||
|
|
||||||
typedef struct Reg Reg;
|
|
||||||
typedef struct Rgn Rgn;
|
|
||||||
|
|
||||||
/*c2go
|
|
||||||
extern Node *Z;
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
D_HI = TYPE_NONE,
|
|
||||||
D_LO = TYPE_NONE,
|
|
||||||
CLOAD = 5,
|
|
||||||
CREF = 5,
|
|
||||||
CINF = 1000,
|
|
||||||
LOOP = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 BLOAD(Reg*);
|
|
||||||
uint32 BSTORE(Reg*);
|
|
||||||
uint64 LOAD(Reg*);
|
|
||||||
uint64 STORE(Reg*);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
|
||||||
// register optimization information while the optimizer runs.
|
|
||||||
// r->prog is the instruction.
|
|
||||||
// r->prog->opt points back to r.
|
|
||||||
struct Reg
|
|
||||||
{
|
|
||||||
Flow f;
|
|
||||||
|
|
||||||
Bits set; // regopt variables written by this instruction.
|
|
||||||
Bits use1; // regopt variables read by prog->from.
|
|
||||||
Bits use2; // regopt variables read by prog->to.
|
|
||||||
|
|
||||||
// refahead/refbehind are the regopt variables whose current
|
|
||||||
// value may be used in the following/preceding instructions
|
|
||||||
// up to a CALL (or the value is clobbered).
|
|
||||||
Bits refbehind;
|
|
||||||
Bits refahead;
|
|
||||||
// calahead/calbehind are similar, but for variables in
|
|
||||||
// instructions that are reachable after hitting at least one
|
|
||||||
// CALL.
|
|
||||||
Bits calbehind;
|
|
||||||
Bits calahead;
|
|
||||||
Bits regdiff;
|
|
||||||
Bits act;
|
|
||||||
|
|
||||||
int32 regu; // register used bitmap
|
|
||||||
};
|
|
||||||
#define R ((Reg*)0)
|
|
||||||
/*c2go extern Reg *R; */
|
|
||||||
|
|
||||||
#define NRGN 600
|
|
||||||
/*c2go enum { NRGN = 600 }; */
|
|
||||||
|
|
||||||
// A Rgn represents a single regopt variable over a region of code
|
|
||||||
// where a register could potentially be dedicated to that variable.
|
|
||||||
// The code encompassed by a Rgn is defined by the flow graph,
|
|
||||||
// starting at enter, flood-filling forward while varno is refahead
|
|
||||||
// and backward while varno is refbehind, and following branches. A
|
|
||||||
// single variable may be represented by multiple disjoint Rgns and
|
|
||||||
// each Rgn may choose a different register for that variable.
|
|
||||||
// Registers are allocated to regions greedily in order of descending
|
|
||||||
// cost.
|
|
||||||
struct Rgn
|
|
||||||
{
|
|
||||||
Reg* enter;
|
|
||||||
short cost;
|
|
||||||
short varno;
|
|
||||||
short regno;
|
|
||||||
};
|
|
||||||
|
|
||||||
EXTERN Reg zreg;
|
|
||||||
EXTERN Reg* freer;
|
|
||||||
EXTERN Reg** rpo2r;
|
|
||||||
EXTERN Rgn region[NRGN];
|
|
||||||
EXTERN Rgn* rgp;
|
|
||||||
EXTERN int nregion;
|
|
||||||
EXTERN int nvar;
|
|
||||||
EXTERN int32 regbits;
|
|
||||||
EXTERN Bits externs;
|
|
||||||
EXTERN Bits params;
|
|
||||||
EXTERN Bits consts;
|
|
||||||
EXTERN Bits addrs;
|
|
||||||
EXTERN Bits ivar;
|
|
||||||
EXTERN Bits ovar;
|
|
||||||
EXTERN int change;
|
|
||||||
EXTERN int32 maxnr;
|
|
||||||
EXTERN int32* idom;
|
|
||||||
|
|
||||||
EXTERN struct
|
|
||||||
{
|
|
||||||
int32 ncvtreg;
|
|
||||||
int32 nspill;
|
|
||||||
int32 nreload;
|
|
||||||
int32 ndelmov;
|
|
||||||
int32 nvar;
|
|
||||||
int32 naddr;
|
|
||||||
} ostats;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* reg.c
|
|
||||||
*/
|
|
||||||
Reg* rega(void);
|
|
||||||
int rcmp(const void*, const void*);
|
|
||||||
void regopt(Prog*);
|
|
||||||
void addmove(Reg*, int, int, int);
|
|
||||||
Bits mkvar(Reg *r, Adr *a);
|
|
||||||
void prop(Reg*, Bits, Bits);
|
|
||||||
void synch(Reg*, Bits);
|
|
||||||
uint32 allreg(uint32, Rgn*);
|
|
||||||
void paint1(Reg*, int);
|
|
||||||
uint32 paint2(Reg*, int, int);
|
|
||||||
void paint3(Reg*, int, uint32, int);
|
|
||||||
void addreg(Adr*, int);
|
|
||||||
void dumpit(char *str, Flow *r0, int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* peep.c
|
|
||||||
*/
|
|
||||||
void peep(Prog*);
|
|
||||||
void excise(Flow*);
|
|
||||||
int copyu(Prog*, Adr*, Adr*);
|
|
||||||
|
|
||||||
uint32 RtoB(int);
|
|
||||||
uint32 FtoB(int);
|
|
||||||
int BtoR(uint32);
|
|
||||||
int BtoF(uint32);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* prog.c
|
|
||||||
*/
|
|
||||||
void proginfo(ProgInfo*, Prog*);
|
|
@ -32,7 +32,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
static int xtramodes(Graph*, Flow*, Adr*);
|
static int xtramodes(Graph*, Flow*, Adr*);
|
||||||
static int shortprop(Flow *r);
|
static int shortprop(Flow *r);
|
||||||
@ -47,6 +47,7 @@ static Flow* findpre(Flow *r, Adr *v);
|
|||||||
static int copyau1(Prog *p, Adr *v);
|
static int copyau1(Prog *p, Adr *v);
|
||||||
static int isdconst(Addr *a);
|
static int isdconst(Addr *a);
|
||||||
static int isfloatreg(Addr*);
|
static int isfloatreg(Addr*);
|
||||||
|
static int copyu(Prog *p, Adr *v, Adr *s);
|
||||||
|
|
||||||
static uint32 gactive;
|
static uint32 gactive;
|
||||||
|
|
||||||
@ -941,7 +942,7 @@ xtramodes(Graph *g, Flow *r, Adr *a)
|
|||||||
* 4 if set and used
|
* 4 if set and used
|
||||||
* 0 otherwise (not touched)
|
* 0 otherwise (not touched)
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
copyu(Prog *p, Adr *v, Adr *s)
|
copyu(Prog *p, Adr *v, Adr *s)
|
||||||
{
|
{
|
||||||
switch(p->as) {
|
switch(p->as) {
|
||||||
@ -1572,3 +1573,12 @@ smallindir(Addr *a, Addr *reg)
|
|||||||
a->reg == reg->reg &&
|
a->reg == reg->reg &&
|
||||||
0 <= a->offset && a->offset < 4096;
|
0 <= a->offset && a->offset < 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
excise(Flow *r)
|
||||||
|
{
|
||||||
|
Prog *p;
|
||||||
|
|
||||||
|
p = r->prog;
|
||||||
|
nopout(p);
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -148,4 +148,13 @@ proginfo(ProgInfo *info, Prog *p)
|
|||||||
|
|
||||||
if(((p->scond & C_SCOND) != C_SCOND_NONE) && (info->flags & RightWrite))
|
if(((p->scond & C_SCOND) != C_SCOND_NONE) && (info->flags & RightWrite))
|
||||||
info->flags |= RightRead;
|
info->flags |= RightRead;
|
||||||
|
|
||||||
|
switch(p->as) {
|
||||||
|
case ADIV:
|
||||||
|
case ADIVU:
|
||||||
|
case AMOD:
|
||||||
|
case AMODU:
|
||||||
|
info->regset |= RtoB(REG_R12);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1329
src/cmd/5g/reg.c
1329
src/cmd/5g/reg.c
File diff suppressed because it is too large
Load Diff
@ -89,14 +89,22 @@ main(int argc, char **argv)
|
|||||||
arch.ginscall = ginscall;
|
arch.ginscall = ginscall;
|
||||||
arch.igen = igen;
|
arch.igen = igen;
|
||||||
arch.linkarchinit = linkarchinit;
|
arch.linkarchinit = linkarchinit;
|
||||||
|
arch.peep = peep;
|
||||||
arch.proginfo = proginfo;
|
arch.proginfo = proginfo;
|
||||||
arch.regalloc = regalloc;
|
arch.regalloc = regalloc;
|
||||||
arch.regfree = regfree;
|
arch.regfree = regfree;
|
||||||
arch.regopt = regopt;
|
|
||||||
arch.regtyp = regtyp;
|
arch.regtyp = regtyp;
|
||||||
arch.sameaddr = sameaddr;
|
arch.sameaddr = sameaddr;
|
||||||
arch.smallindir = smallindir;
|
arch.smallindir = smallindir;
|
||||||
arch.stackaddr = stackaddr;
|
arch.stackaddr = stackaddr;
|
||||||
|
arch.excludedregs = excludedregs;
|
||||||
|
arch.RtoB = RtoB;
|
||||||
|
arch.FtoB = FtoB;
|
||||||
|
arch.BtoR = BtoR;
|
||||||
|
arch.BtoF = BtoF;
|
||||||
|
arch.optoas = optoas;
|
||||||
|
arch.doregbits = doregbits;
|
||||||
|
arch.regnames = regnames;
|
||||||
|
|
||||||
gcmain(argc, argv);
|
gcmain(argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -159,3 +159,18 @@ int smallindir(Addr*, Addr*);
|
|||||||
int stackaddr(Addr*);
|
int stackaddr(Addr*);
|
||||||
Prog* unpatch(Prog*);
|
Prog* unpatch(Prog*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reg.c
|
||||||
|
*/
|
||||||
|
uint64 excludedregs(void);
|
||||||
|
uint64 RtoB(int);
|
||||||
|
uint64 FtoB(int);
|
||||||
|
int BtoR(uint64);
|
||||||
|
int BtoF(uint64);
|
||||||
|
uint64 doregbits(int);
|
||||||
|
char** regnames(int*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* peep.c
|
||||||
|
*/
|
||||||
|
void peep(Prog*);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
|
static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
|
||||||
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
|
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
static void conprop(Flow *r);
|
static void conprop(Flow *r);
|
||||||
static void elimshortmov(Graph *g);
|
static void elimshortmov(Graph *g);
|
||||||
@ -44,9 +44,15 @@ static int copy1(Adr*, Adr*, Flow*, int);
|
|||||||
static int copyas(Adr*, Adr*);
|
static int copyas(Adr*, Adr*);
|
||||||
static int copyau(Adr*, Adr*);
|
static int copyau(Adr*, Adr*);
|
||||||
static int copysub(Adr*, Adr*, Adr*, int);
|
static int copysub(Adr*, Adr*, Adr*, int);
|
||||||
|
static int copyu(Prog*, Adr*, Adr*);
|
||||||
|
|
||||||
static uint32 gactive;
|
static uint32 gactive;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
exregoffset = REG_R15,
|
||||||
|
};
|
||||||
|
|
||||||
// do we need the carry bit
|
// do we need the carry bit
|
||||||
static int
|
static int
|
||||||
needc(Prog *p)
|
needc(Prog *p)
|
||||||
@ -737,7 +743,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||||||
* 4 if set and used
|
* 4 if set and used
|
||||||
* 0 otherwise (not touched)
|
* 0 otherwise (not touched)
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
copyu(Prog *p, Adr *v, Adr *s)
|
copyu(Prog *p, Adr *v, Adr *s)
|
||||||
{
|
{
|
||||||
ProgInfo info;
|
ProgInfo info;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
// Matches real RtoB but can be used in global initializer.
|
// Matches real RtoB but can be used in global initializer.
|
||||||
#define RtoB(r) (1<<((r)-REG_AX))
|
#define RtoB(r) (1<<((r)-REG_AX))
|
||||||
|
1176
src/cmd/6g/reg.c
1176
src/cmd/6g/reg.c
File diff suppressed because it is too large
Load Diff
@ -66,14 +66,22 @@ main(int argc, char **argv)
|
|||||||
arch.ginscall = ginscall;
|
arch.ginscall = ginscall;
|
||||||
arch.igen = igen;
|
arch.igen = igen;
|
||||||
arch.linkarchinit = linkarchinit;
|
arch.linkarchinit = linkarchinit;
|
||||||
|
arch.peep = peep;
|
||||||
arch.proginfo = proginfo;
|
arch.proginfo = proginfo;
|
||||||
arch.regalloc = regalloc;
|
arch.regalloc = regalloc;
|
||||||
arch.regfree = regfree;
|
arch.regfree = regfree;
|
||||||
arch.regopt = regopt;
|
|
||||||
arch.regtyp = regtyp;
|
arch.regtyp = regtyp;
|
||||||
arch.sameaddr = sameaddr;
|
arch.sameaddr = sameaddr;
|
||||||
arch.smallindir = smallindir;
|
arch.smallindir = smallindir;
|
||||||
arch.stackaddr = stackaddr;
|
arch.stackaddr = stackaddr;
|
||||||
|
arch.excludedregs = excludedregs;
|
||||||
|
arch.RtoB = RtoB;
|
||||||
|
arch.FtoB = FtoB;
|
||||||
|
arch.BtoR = BtoR;
|
||||||
|
arch.BtoF = BtoF;
|
||||||
|
arch.optoas = optoas;
|
||||||
|
arch.doregbits = doregbits;
|
||||||
|
arch.regnames = regnames;
|
||||||
|
|
||||||
gcmain(argc, argv);
|
gcmain(argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -171,3 +171,19 @@ int sameaddr(Addr*, Addr*);
|
|||||||
int smallindir(Addr*, Addr*);
|
int smallindir(Addr*, Addr*);
|
||||||
int stackaddr(Addr*);
|
int stackaddr(Addr*);
|
||||||
Prog* unpatch(Prog*);
|
Prog* unpatch(Prog*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reg.c
|
||||||
|
*/
|
||||||
|
uint64 excludedregs(void);
|
||||||
|
uint64 RtoB(int);
|
||||||
|
uint64 FtoB(int);
|
||||||
|
int BtoR(uint64);
|
||||||
|
int BtoF(uint64);
|
||||||
|
uint64 doregbits(int);
|
||||||
|
char** regnames(int*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* peep.c
|
||||||
|
*/
|
||||||
|
void peep(Prog*);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
|
static Prog *appendpp(Prog*, int, int, int, vlong, int, int, vlong);
|
||||||
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
|
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
|
||||||
|
@ -187,6 +187,14 @@ optoas(int op, Type *t)
|
|||||||
case CASE(OAS, TPTR32):
|
case CASE(OAS, TPTR32):
|
||||||
a = AMOVL;
|
a = AMOVL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CASE(OAS, TFLOAT32):
|
||||||
|
a = AMOVSS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CASE(OAS, TFLOAT64):
|
||||||
|
a = AMOVSD;
|
||||||
|
break;
|
||||||
|
|
||||||
case CASE(OADD, TINT8):
|
case CASE(OADD, TINT8):
|
||||||
case CASE(OADD, TUINT8):
|
case CASE(OADD, TUINT8):
|
||||||
|
192
src/cmd/8g/opt.h
192
src/cmd/8g/opt.h
@ -1,192 +0,0 @@
|
|||||||
// Derived from Inferno utils/6c/gc.h
|
|
||||||
// http://code.google.com/p/inferno-os/source/browse/utils/6c/gc.h
|
|
||||||
//
|
|
||||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
||||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
||||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
||||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
||||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
|
||||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
#define Z N
|
|
||||||
#define Adr Addr
|
|
||||||
|
|
||||||
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
|
|
||||||
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
|
|
||||||
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
|
|
||||||
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
|
|
||||||
|
|
||||||
#define CLOAD 5
|
|
||||||
#define CREF 5
|
|
||||||
#define CINF 1000
|
|
||||||
#define LOOP 3
|
|
||||||
|
|
||||||
typedef struct Reg Reg;
|
|
||||||
typedef struct Rgn Rgn;
|
|
||||||
|
|
||||||
/*c2go
|
|
||||||
extern Node *Z;
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
CLOAD = 5,
|
|
||||||
CREF = 5,
|
|
||||||
CINF = 1000,
|
|
||||||
LOOP = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 BLOAD(Reg*);
|
|
||||||
uint32 BSTORE(Reg*);
|
|
||||||
uint64 LOAD(Reg*);
|
|
||||||
uint64 STORE(Reg*);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
|
||||||
// register optimization information while the optimizer runs.
|
|
||||||
// r->prog is the instruction.
|
|
||||||
// r->prog->opt points back to r.
|
|
||||||
struct Reg
|
|
||||||
{
|
|
||||||
Flow f;
|
|
||||||
|
|
||||||
Bits set; // regopt variables written by this instruction.
|
|
||||||
Bits use1; // regopt variables read by prog->from.
|
|
||||||
Bits use2; // regopt variables read by prog->to.
|
|
||||||
|
|
||||||
// refahead/refbehind are the regopt variables whose current
|
|
||||||
// value may be used in the following/preceding instructions
|
|
||||||
// up to a CALL (or the value is clobbered).
|
|
||||||
Bits refbehind;
|
|
||||||
Bits refahead;
|
|
||||||
// calahead/calbehind are similar, but for variables in
|
|
||||||
// instructions that are reachable after hitting at least one
|
|
||||||
// CALL.
|
|
||||||
Bits calbehind;
|
|
||||||
Bits calahead;
|
|
||||||
Bits regdiff;
|
|
||||||
Bits act;
|
|
||||||
|
|
||||||
int32 regu; // register used bitmap
|
|
||||||
int32 rpo; // reverse post ordering
|
|
||||||
int32 active;
|
|
||||||
|
|
||||||
uint16 loop; // x5 for every loop
|
|
||||||
uchar refset; // diagnostic generated
|
|
||||||
|
|
||||||
Reg* p1; // predecessors of this instruction: p1,
|
|
||||||
Reg* p2; // and then p2 linked though p2link.
|
|
||||||
Reg* p2link;
|
|
||||||
Reg* s1; // successors of this instruction (at most two: s1 and s2).
|
|
||||||
Reg* s2;
|
|
||||||
Reg* link; // next instruction in function code
|
|
||||||
Prog* prog; // actual instruction
|
|
||||||
};
|
|
||||||
#define R ((Reg*)0)
|
|
||||||
/*c2go extern Reg *R; */
|
|
||||||
|
|
||||||
#define NRGN 600
|
|
||||||
/*c2go enum { NRGN = 600 }; */
|
|
||||||
|
|
||||||
// A Rgn represents a single regopt variable over a region of code
|
|
||||||
// where a register could potentially be dedicated to that variable.
|
|
||||||
// The code encompassed by a Rgn is defined by the flow graph,
|
|
||||||
// starting at enter, flood-filling forward while varno is refahead
|
|
||||||
// and backward while varno is refbehind, and following branches. A
|
|
||||||
// single variable may be represented by multiple disjoint Rgns and
|
|
||||||
// each Rgn may choose a different register for that variable.
|
|
||||||
// Registers are allocated to regions greedily in order of descending
|
|
||||||
// cost.
|
|
||||||
struct Rgn
|
|
||||||
{
|
|
||||||
Reg* enter;
|
|
||||||
short cost;
|
|
||||||
short varno;
|
|
||||||
short regno;
|
|
||||||
};
|
|
||||||
|
|
||||||
EXTERN int32 exregoffset; // not set
|
|
||||||
EXTERN int32 exfregoffset; // not set
|
|
||||||
EXTERN Reg zreg;
|
|
||||||
EXTERN Reg* freer;
|
|
||||||
EXTERN Reg** rpo2r;
|
|
||||||
EXTERN Rgn region[NRGN];
|
|
||||||
EXTERN Rgn* rgp;
|
|
||||||
EXTERN int nregion;
|
|
||||||
EXTERN int nvar;
|
|
||||||
EXTERN int32 regbits;
|
|
||||||
EXTERN int32 exregbits;
|
|
||||||
EXTERN Bits externs;
|
|
||||||
EXTERN Bits params;
|
|
||||||
EXTERN Bits consts;
|
|
||||||
EXTERN Bits addrs;
|
|
||||||
EXTERN Bits ivar;
|
|
||||||
EXTERN Bits ovar;
|
|
||||||
EXTERN int change;
|
|
||||||
EXTERN int32 maxnr;
|
|
||||||
EXTERN int32* idom;
|
|
||||||
|
|
||||||
EXTERN struct
|
|
||||||
{
|
|
||||||
int32 ncvtreg;
|
|
||||||
int32 nspill;
|
|
||||||
int32 nreload;
|
|
||||||
int32 ndelmov;
|
|
||||||
int32 nvar;
|
|
||||||
int32 naddr;
|
|
||||||
} ostats;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* reg.c
|
|
||||||
*/
|
|
||||||
Reg* rega(void);
|
|
||||||
int rcmp(const void*, const void*);
|
|
||||||
void regopt(Prog*);
|
|
||||||
void addmove(Reg*, int, int, int);
|
|
||||||
Bits mkvar(Reg*, Adr*);
|
|
||||||
void prop(Reg*, Bits, Bits);
|
|
||||||
void loopit(Reg*, int32);
|
|
||||||
void synch(Reg*, Bits);
|
|
||||||
uint32 allreg(uint32, Rgn*);
|
|
||||||
void paint1(Reg*, int);
|
|
||||||
uint32 paint2(Reg*, int, int);
|
|
||||||
void paint3(Reg*, int, uint32, int);
|
|
||||||
void addreg(Adr*, int);
|
|
||||||
void dumpone(Flow*, int);
|
|
||||||
void dumpit(char*, Flow*, int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* peep.c
|
|
||||||
*/
|
|
||||||
void peep(Prog*);
|
|
||||||
void excise(Flow*);
|
|
||||||
int copyu(Prog*, Adr*, Adr*);
|
|
||||||
|
|
||||||
uint32 RtoB(int);
|
|
||||||
uint32 FtoB(int);
|
|
||||||
int BtoR(uint32);
|
|
||||||
int BtoF(uint32);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* prog.c
|
|
||||||
*/
|
|
||||||
void proginfo(ProgInfo*, Prog*);
|
|
@ -31,10 +31,11 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REGEXT = 0,
|
REGEXT = 0,
|
||||||
|
exregoffset = REG_DI,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void conprop(Flow *r);
|
static void conprop(Flow *r);
|
||||||
@ -45,6 +46,7 @@ static int copy1(Adr*, Adr*, Flow*, int);
|
|||||||
static int copyas(Adr*, Adr*);
|
static int copyas(Adr*, Adr*);
|
||||||
static int copyau(Adr*, Adr*);
|
static int copyau(Adr*, Adr*);
|
||||||
static int copysub(Adr*, Adr*, Adr*, int);
|
static int copysub(Adr*, Adr*, Adr*, int);
|
||||||
|
static int copyu(Prog*, Adr*, Adr*);
|
||||||
|
|
||||||
static uint32 gactive;
|
static uint32 gactive;
|
||||||
|
|
||||||
@ -535,7 +537,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||||||
* 4 if set and used
|
* 4 if set and used
|
||||||
* 0 otherwise (not touched)
|
* 0 otherwise (not touched)
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
copyu(Prog *p, Adr *v, Adr *s)
|
copyu(Prog *p, Adr *v, Adr *s)
|
||||||
{
|
{
|
||||||
ProgInfo info;
|
ProgInfo info;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
// Matches real RtoB but can be used in global initializer.
|
// Matches real RtoB but can be used in global initializer.
|
||||||
#define RtoB(r) (1<<((r)-REG_AX))
|
#define RtoB(r) (1<<((r)-REG_AX))
|
||||||
|
1187
src/cmd/8g/reg.c
1187
src/cmd/8g/reg.c
File diff suppressed because it is too large
Load Diff
@ -73,14 +73,22 @@ main(int argc, char **argv)
|
|||||||
arch.ginscall = ginscall;
|
arch.ginscall = ginscall;
|
||||||
arch.igen = igen;
|
arch.igen = igen;
|
||||||
arch.linkarchinit = linkarchinit;
|
arch.linkarchinit = linkarchinit;
|
||||||
|
arch.peep = peep;
|
||||||
arch.proginfo = proginfo;
|
arch.proginfo = proginfo;
|
||||||
arch.regalloc = regalloc;
|
arch.regalloc = regalloc;
|
||||||
arch.regfree = regfree;
|
arch.regfree = regfree;
|
||||||
arch.regopt = regopt;
|
|
||||||
arch.regtyp = regtyp;
|
arch.regtyp = regtyp;
|
||||||
arch.sameaddr = sameaddr;
|
arch.sameaddr = sameaddr;
|
||||||
arch.smallindir = smallindir;
|
arch.smallindir = smallindir;
|
||||||
arch.stackaddr = stackaddr;
|
arch.stackaddr = stackaddr;
|
||||||
|
arch.excludedregs = excludedregs;
|
||||||
|
arch.RtoB = RtoB;
|
||||||
|
arch.FtoB = RtoB;
|
||||||
|
arch.BtoR = BtoR;
|
||||||
|
arch.BtoF = BtoF;
|
||||||
|
arch.optoas = optoas;
|
||||||
|
arch.doregbits = doregbits;
|
||||||
|
arch.regnames = regnames;
|
||||||
|
|
||||||
gcmain(argc, argv);
|
gcmain(argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -154,3 +154,19 @@ int smallindir(Addr*, Addr*);
|
|||||||
int stackaddr(Addr*);
|
int stackaddr(Addr*);
|
||||||
Prog* unpatch(Prog*);
|
Prog* unpatch(Prog*);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reg.c
|
||||||
|
*/
|
||||||
|
uint64 excludedregs(void);
|
||||||
|
uint64 RtoB(int);
|
||||||
|
uint64 FtoB(int);
|
||||||
|
int BtoR(uint64);
|
||||||
|
int BtoF(uint64);
|
||||||
|
uint64 doregbits(int);
|
||||||
|
char** regnames(int*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* peep.c
|
||||||
|
*/
|
||||||
|
void peep(Prog*);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
#include "opt.h"
|
#include "../gc/popt.h"
|
||||||
|
|
||||||
static Prog *appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset);
|
static Prog *appendpp(Prog *p, int as, int ftype, int freg, vlong foffset, int ttype, int treg, vlong toffset);
|
||||||
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi);
|
static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi);
|
||||||
|
175
src/cmd/9g/opt.h
175
src/cmd/9g/opt.h
@ -1,175 +1,6 @@
|
|||||||
// Derived from Inferno utils/6c/gc.h
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// http://code.google.com/p/inferno-os/source/browse/utils/6c/gc.h
|
// Use of this source code is governed by a BSD-style
|
||||||
//
|
// license that can be found in the LICENSE file.
|
||||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
||||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
||||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
||||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
||||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
|
||||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
#define Z N
|
|
||||||
#define Adr Addr
|
|
||||||
|
|
||||||
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
|
|
||||||
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
|
|
||||||
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
|
|
||||||
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
|
|
||||||
|
|
||||||
#define CLOAD 5
|
|
||||||
#define CREF 5
|
|
||||||
#define CINF 1000
|
|
||||||
#define LOOP 3
|
|
||||||
|
|
||||||
typedef struct Reg Reg;
|
|
||||||
typedef struct Rgn Rgn;
|
|
||||||
|
|
||||||
/*c2go
|
|
||||||
extern Node *Z;
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
CLOAD = 5,
|
|
||||||
CREF = 5,
|
|
||||||
CINF = 1000,
|
|
||||||
LOOP = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 BLOAD(Reg*);
|
|
||||||
uint32 BSTORE(Reg*);
|
|
||||||
uint32 LOAD(Reg*);
|
|
||||||
uint32 STORE(Reg*);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
|
||||||
// register optimization information while the optimizer runs.
|
|
||||||
// r->prog is the instruction.
|
|
||||||
// r->prog->opt points back to r.
|
|
||||||
struct Reg
|
|
||||||
{
|
|
||||||
Flow f;
|
|
||||||
|
|
||||||
Bits set; // regopt variables written by this instruction.
|
|
||||||
Bits use1; // regopt variables read by prog->from.
|
|
||||||
Bits use2; // regopt variables read by prog->to.
|
|
||||||
|
|
||||||
// refahead/refbehind are the regopt variables whose current
|
|
||||||
// value may be used in the following/preceding instructions
|
|
||||||
// up to a CALL (or the value is clobbered).
|
|
||||||
Bits refbehind;
|
|
||||||
Bits refahead;
|
|
||||||
// calahead/calbehind are similar, but for variables in
|
|
||||||
// instructions that are reachable after hitting at least one
|
|
||||||
// CALL.
|
|
||||||
Bits calbehind;
|
|
||||||
Bits calahead;
|
|
||||||
Bits regdiff;
|
|
||||||
Bits act;
|
|
||||||
|
|
||||||
uint64 regu; // register used bitmap
|
|
||||||
};
|
|
||||||
#define R ((Reg*)0)
|
|
||||||
/*c2go extern Reg *R; */
|
|
||||||
|
|
||||||
#define NRGN 600
|
|
||||||
/*c2go enum { NRGN = 600 }; */
|
|
||||||
|
|
||||||
// A Rgn represents a single regopt variable over a region of code
|
|
||||||
// where a register could potentially be dedicated to that variable.
|
|
||||||
// The code encompassed by a Rgn is defined by the flow graph,
|
|
||||||
// starting at enter, flood-filling forward while varno is refahead
|
|
||||||
// and backward while varno is refbehind, and following branches. A
|
|
||||||
// single variable may be represented by multiple disjoint Rgns and
|
|
||||||
// each Rgn may choose a different register for that variable.
|
|
||||||
// Registers are allocated to regions greedily in order of descending
|
|
||||||
// cost.
|
|
||||||
struct Rgn
|
|
||||||
{
|
|
||||||
Reg* enter;
|
|
||||||
short cost;
|
|
||||||
short varno;
|
|
||||||
short regno;
|
|
||||||
};
|
|
||||||
|
|
||||||
EXTERN int32 exregoffset; // not set
|
|
||||||
EXTERN int32 exfregoffset; // not set
|
|
||||||
EXTERN Reg zreg;
|
|
||||||
EXTERN Rgn region[NRGN];
|
|
||||||
EXTERN Rgn* rgp;
|
|
||||||
EXTERN int nregion;
|
|
||||||
EXTERN int nvar;
|
|
||||||
EXTERN int32 regbits;
|
|
||||||
EXTERN int32 exregbits; // TODO(austin) not used; remove
|
|
||||||
EXTERN Bits externs;
|
|
||||||
EXTERN Bits params;
|
|
||||||
EXTERN Bits consts;
|
|
||||||
EXTERN Bits addrs;
|
|
||||||
EXTERN Bits ivar;
|
|
||||||
EXTERN Bits ovar;
|
|
||||||
EXTERN int change;
|
|
||||||
EXTERN int32 maxnr;
|
|
||||||
|
|
||||||
EXTERN struct
|
|
||||||
{
|
|
||||||
int32 ncvtreg;
|
|
||||||
int32 nspill;
|
|
||||||
int32 ndelmov;
|
|
||||||
int32 nvar;
|
|
||||||
} ostats;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* reg.c
|
|
||||||
*/
|
|
||||||
int rcmp(const void*, const void*);
|
|
||||||
void regopt(Prog*);
|
|
||||||
void addmove(Reg*, int, int, int);
|
|
||||||
Bits mkvar(Reg*, Adr*);
|
|
||||||
void prop(Reg*, Bits, Bits);
|
|
||||||
void synch(Reg*, Bits);
|
|
||||||
uint64 allreg(uint64, Rgn*);
|
|
||||||
void paint1(Reg*, int);
|
|
||||||
uint64 paint2(Reg*, int, int);
|
|
||||||
void paint3(Reg*, int, uint64, int);
|
|
||||||
void addreg(Adr*, int);
|
|
||||||
void dumpone(Flow*, int);
|
|
||||||
void dumpit(char*, Flow*, int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* peep.c
|
|
||||||
*/
|
|
||||||
void peep(Prog*);
|
|
||||||
void excise(Flow*);
|
|
||||||
int copyu(Prog*, Adr*, Adr*);
|
|
||||||
|
|
||||||
uint64 RtoB(int);
|
|
||||||
uint64 FtoB(int);
|
|
||||||
int BtoR(uint64);
|
|
||||||
int BtoF(uint64);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* prog.c
|
|
||||||
*/
|
|
||||||
void proginfo(ProgInfo*, Prog*);
|
|
||||||
|
|
||||||
// Many Power ISA arithmetic and logical instructions come in four
|
// Many Power ISA arithmetic and logical instructions come in four
|
||||||
// standard variants. These bits let us map between variants.
|
// standard variants. These bits let us map between variants.
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
|
#include "../gc/popt.h"
|
||||||
#include "opt.h"
|
#include "opt.h"
|
||||||
|
|
||||||
static int regzer(Addr *a);
|
static int regzer(Addr *a);
|
||||||
@ -42,6 +43,7 @@ static int copyau(Addr*, Addr*);
|
|||||||
static int copysub(Addr*, Addr*, Addr*, int);
|
static int copysub(Addr*, Addr*, Addr*, int);
|
||||||
static int copysub1(Prog*, Addr*, Addr*, int);
|
static int copysub1(Prog*, Addr*, Addr*, int);
|
||||||
static int copyau1(Prog *p, Addr *v);
|
static int copyau1(Prog *p, Addr *v);
|
||||||
|
static int copyu(Prog *p, Addr *v, Addr *s);
|
||||||
|
|
||||||
static uint32 gactive;
|
static uint32 gactive;
|
||||||
|
|
||||||
@ -568,7 +570,7 @@ copy1(Addr *v1, Addr *v2, Flow *r, int f)
|
|||||||
// 4 if v is set in one address and used in another (so addresses
|
// 4 if v is set in one address and used in another (so addresses
|
||||||
// can be rewritten independently)
|
// can be rewritten independently)
|
||||||
// 0 otherwise (not touched)
|
// 0 otherwise (not touched)
|
||||||
int
|
static int
|
||||||
copyu(Prog *p, Addr *v, Addr *s)
|
copyu(Prog *p, Addr *v, Addr *s)
|
||||||
{
|
{
|
||||||
if(p->from3.type != TYPE_NONE)
|
if(p->from3.type != TYPE_NONE)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "gg.h"
|
#include "gg.h"
|
||||||
|
#include "../gc/popt.h"
|
||||||
#include "opt.h"
|
#include "opt.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
1176
src/cmd/9g/reg.c
1176
src/cmd/9g/reg.c
File diff suppressed because it is too large
Load Diff
@ -1679,14 +1679,22 @@ struct Arch
|
|||||||
void (*ginscall)(Node*, int);
|
void (*ginscall)(Node*, int);
|
||||||
void (*igen)(Node*, Node*, Node*);
|
void (*igen)(Node*, Node*, Node*);
|
||||||
void (*linkarchinit)(void);
|
void (*linkarchinit)(void);
|
||||||
|
void (*peep)(Prog*);
|
||||||
void (*proginfo)(ProgInfo*, Prog*);
|
void (*proginfo)(ProgInfo*, Prog*);
|
||||||
void (*regalloc)(Node*, Type*, Node*);
|
void (*regalloc)(Node*, Type*, Node*);
|
||||||
void (*regfree)(Node*);
|
void (*regfree)(Node*);
|
||||||
void (*regopt)(Prog*);
|
|
||||||
int (*regtyp)(Addr*);
|
int (*regtyp)(Addr*);
|
||||||
int (*sameaddr)(Addr*, Addr*);
|
int (*sameaddr)(Addr*, Addr*);
|
||||||
int (*smallindir)(Addr*, Addr*);
|
int (*smallindir)(Addr*, Addr*);
|
||||||
int (*stackaddr)(Addr*);
|
int (*stackaddr)(Addr*);
|
||||||
|
uint64 (*excludedregs)(void);
|
||||||
|
uint64 (*RtoB)(int);
|
||||||
|
uint64 (*FtoB)(int);
|
||||||
|
int (*BtoR)(uint64);
|
||||||
|
int (*BtoF)(uint64);
|
||||||
|
int (*optoas)(int, Type*);
|
||||||
|
uint64 (*doregbits)(int);
|
||||||
|
char **(*regnames)(int*);
|
||||||
};
|
};
|
||||||
|
|
||||||
void afunclit(Addr*, Node*);
|
void afunclit(Addr*, Node*);
|
||||||
@ -1716,6 +1724,7 @@ Prog* unpatch(Prog*);
|
|||||||
void datagostring(Strlit *sval, Addr *a);
|
void datagostring(Strlit *sval, Addr *a);
|
||||||
int ismem(Node*);
|
int ismem(Node*);
|
||||||
int samereg(Node*, Node*);
|
int samereg(Node*, Node*);
|
||||||
|
void regopt(Prog*);
|
||||||
|
|
||||||
EXTERN int32 pcloc;
|
EXTERN int32 pcloc;
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ compile(Node *fn)
|
|||||||
|
|
||||||
fixjmp(ptxt);
|
fixjmp(ptxt);
|
||||||
if(!debug['N'] || debug['R'] || debug['P']) {
|
if(!debug['N'] || debug['R'] || debug['P']) {
|
||||||
arch.regopt(ptxt);
|
regopt(ptxt);
|
||||||
nilopt(ptxt);
|
nilopt(ptxt);
|
||||||
}
|
}
|
||||||
arch.expandchecks(ptxt);
|
arch.expandchecks(ptxt);
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
#define Z N
|
#define Z N
|
||||||
#define Adr Addr
|
#define Adr Addr
|
||||||
|
|
||||||
@ -91,7 +90,7 @@ struct Reg
|
|||||||
Bits regdiff;
|
Bits regdiff;
|
||||||
Bits act;
|
Bits act;
|
||||||
|
|
||||||
int32 regu; // register used bitmap
|
uint64 regu; // register used bitmap
|
||||||
};
|
};
|
||||||
#define R ((Reg*)0)
|
#define R ((Reg*)0)
|
||||||
/*c2go extern Reg *R; */
|
/*c2go extern Reg *R; */
|
||||||
@ -116,15 +115,12 @@ struct Rgn
|
|||||||
short regno;
|
short regno;
|
||||||
};
|
};
|
||||||
|
|
||||||
EXTERN int32 exregoffset; // not set
|
|
||||||
EXTERN int32 exfregoffset; // not set
|
|
||||||
EXTERN Reg zreg;
|
EXTERN Reg zreg;
|
||||||
EXTERN Rgn region[NRGN];
|
EXTERN Rgn region[NRGN];
|
||||||
EXTERN Rgn* rgp;
|
EXTERN Rgn* rgp;
|
||||||
EXTERN int nregion;
|
EXTERN int nregion;
|
||||||
EXTERN int nvar;
|
EXTERN int nvar;
|
||||||
EXTERN int32 regbits;
|
EXTERN uint64 regbits;
|
||||||
EXTERN int32 exregbits;
|
|
||||||
EXTERN Bits externs;
|
EXTERN Bits externs;
|
||||||
EXTERN Bits params;
|
EXTERN Bits params;
|
||||||
EXTERN Bits consts;
|
EXTERN Bits consts;
|
||||||
@ -153,28 +149,23 @@ void addmove(Reg*, int, int, int);
|
|||||||
Bits mkvar(Reg*, Adr*);
|
Bits mkvar(Reg*, Adr*);
|
||||||
void prop(Reg*, Bits, Bits);
|
void prop(Reg*, Bits, Bits);
|
||||||
void synch(Reg*, Bits);
|
void synch(Reg*, Bits);
|
||||||
uint32 allreg(uint32, Rgn*);
|
uint64 allreg(uint64, Rgn*);
|
||||||
void paint1(Reg*, int);
|
void paint1(Reg*, int);
|
||||||
uint32 paint2(Reg*, int, int);
|
uint64 paint2(Reg*, int, int);
|
||||||
void paint3(Reg*, int, uint32, int);
|
void paint3(Reg*, int, uint64, int);
|
||||||
void addreg(Adr*, int);
|
void addreg(Adr*, int);
|
||||||
void dumpone(Flow*, int);
|
void dumpone(Flow*, int);
|
||||||
void dumpit(char*, Flow*, int);
|
void dumpit(char*, Flow*, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* peep.c
|
* peep.c
|
||||||
*/
|
|
||||||
void peep(Prog*);
|
void peep(Prog*);
|
||||||
void excise(Flow*);
|
void excise(Flow*);
|
||||||
int copyu(Prog*, Adr*, Adr*);
|
int copyu(Prog*, Adr*, Adr*);
|
||||||
|
*/
|
||||||
uint32 RtoB(int);
|
|
||||||
uint32 FtoB(int);
|
|
||||||
int BtoR(uint32);
|
|
||||||
int BtoF(uint32);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prog.c
|
* prog.c
|
||||||
*/
|
|
||||||
|
|
||||||
void proginfo(ProgInfo*, Prog*);
|
void proginfo(ProgInfo*, Prog*);
|
||||||
|
*/
|
1193
src/cmd/gc/reg.c
Normal file
1193
src/cmd/gc/reg.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user