Commit 743bdf61 authored by Austin Clements's avatar Austin Clements

[dev.power64] 9g: implement regopt

This adds registerization support to 9g equivalent to what the
other compilers have.

LGTM=rsc
R=rsc, dave
CC=golang-codereviews
https://golang.org/cl/174980043
parent 231b8d61
...@@ -70,24 +70,40 @@ struct Reg ...@@ -70,24 +70,40 @@ struct Reg
{ {
Flow f; Flow f;
Bits set; // variables written by this instruction. Bits set; // regopt variables written by this instruction.
Bits use1; // variables read by prog->from. Bits use1; // regopt variables read by prog->from.
Bits use2; // variables read by prog->to. 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 refbehind;
Bits refahead; Bits refahead;
// calahead/calbehind are similar, but for variables in
// instructions that are reachable after hitting at least one
// CALL.
Bits calbehind; Bits calbehind;
Bits calahead; Bits calahead;
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; */
#define NRGN 600 #define NRGN 600
/*c2go enum { 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 struct Rgn
{ {
Reg* enter; Reg* enter;
...@@ -104,7 +120,7 @@ EXTERN Rgn* rgp; ...@@ -104,7 +120,7 @@ EXTERN Rgn* rgp;
EXTERN int nregion; EXTERN int nregion;
EXTERN int nvar; EXTERN int nvar;
EXTERN int32 regbits; EXTERN int32 regbits;
EXTERN int32 exregbits; EXTERN int32 exregbits; // TODO(austin) not used; remove
EXTERN Bits externs; EXTERN Bits externs;
EXTERN Bits params; EXTERN Bits params;
EXTERN Bits consts; EXTERN Bits consts;
...@@ -118,10 +134,8 @@ EXTERN struct ...@@ -118,10 +134,8 @@ EXTERN struct
{ {
int32 ncvtreg; int32 ncvtreg;
int32 nspill; int32 nspill;
int32 nreload;
int32 ndelmov; int32 ndelmov;
int32 nvar; int32 nvar;
int32 naddr;
} ostats; } ostats;
/* /*
...@@ -133,10 +147,10 @@ void addmove(Reg*, int, int, int); ...@@ -133,10 +147,10 @@ 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); uint64 paint2(Reg*, int, int);
void paint3(Reg*, int, int32, 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);
...@@ -160,8 +174,8 @@ typedef struct ProgInfo ProgInfo; ...@@ -160,8 +174,8 @@ typedef struct ProgInfo ProgInfo;
struct ProgInfo struct ProgInfo
{ {
uint32 flags; // the bits below uint32 flags; // the bits below
uint64 reguse; // required registers used by this instruction uint64 reguse; // registers implicitly used by this instruction
uint64 regset; // required registers set by this instruction uint64 regset; // registers implicitly set by this instruction
uint64 regindex; // registers used by addressing mode uint64 regindex; // registers used by addressing mode
}; };
...@@ -182,20 +196,21 @@ enum ...@@ -182,20 +196,21 @@ enum
SizeF = 1<<7, // float aka float32 SizeF = 1<<7, // float aka float32
SizeD = 1<<8, // double aka float64 SizeD = 1<<8, // double aka float64
// Left side: address taken, read, write. // Left side (Prog.from): address taken, read, write.
LeftAddr = 1<<9, LeftAddr = 1<<9,
LeftRead = 1<<10, LeftRead = 1<<10,
LeftWrite = 1<<11, LeftWrite = 1<<11,
// Register in middle; never written. // Register in middle (Prog.reg); only ever read.
RegRead = 1<<12, RegRead = 1<<12,
CanRegRead = 1<<13, CanRegRead = 1<<13,
// Right side: address taken, read, write. // Right side (Prog.to): address taken, read, write.
RightAddr = 1<<14, RightAddr = 1<<14,
RightRead = 1<<15, RightRead = 1<<15,
RightWrite = 1<<16, RightWrite = 1<<16,
// Instruction updates whichever of from/to is type D_OREG
PostInc = 1<<17, PostInc = 1<<17,
// Instruction kinds // Instruction kinds
......
This diff is collapsed.
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