aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/9g/opt.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/9g/opt.h')
-rw-r--r--src/cmd/9g/opt.h49
1 files changed, 32 insertions, 17 deletions
diff --git a/src/cmd/9g/opt.h b/src/cmd/9g/opt.h
index d3cbcb9570..7f15b5a69f 100644
--- a/src/cmd/9g/opt.h
+++ b/src/cmd/9g/opt.h
@@ -70,24 +70,40 @@ struct Reg
{
Flow f;
- Bits set; // variables written by this instruction.
- Bits use1; // variables read by prog->from.
- Bits use2; // variables read by prog->to.
+ 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
+ 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;
@@ -104,7 +120,7 @@ EXTERN Rgn* rgp;
EXTERN int nregion;
EXTERN int nvar;
EXTERN int32 regbits;
-EXTERN int32 exregbits;
+EXTERN int32 exregbits; // TODO(austin) not used; remove
EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
@@ -118,10 +134,8 @@ EXTERN struct
{
int32 ncvtreg;
int32 nspill;
- int32 nreload;
int32 ndelmov;
int32 nvar;
- int32 naddr;
} ostats;
/*
@@ -133,10 +147,10 @@ void addmove(Reg*, int, int, int);
Bits mkvar(Reg*, Adr*);
void prop(Reg*, Bits, Bits);
void synch(Reg*, Bits);
-uint32 allreg(uint32, Rgn*);
+uint64 allreg(uint64, Rgn*);
void paint1(Reg*, int);
-uint32 paint2(Reg*, int);
-void paint3(Reg*, int, int32, 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);
@@ -160,8 +174,8 @@ typedef struct ProgInfo ProgInfo;
struct ProgInfo
{
uint32 flags; // the bits below
- uint64 reguse; // required registers used by this instruction
- uint64 regset; // required registers set by this instruction
+ uint64 reguse; // registers implicitly used by this instruction
+ uint64 regset; // registers implicitly set by this instruction
uint64 regindex; // registers used by addressing mode
};
@@ -182,20 +196,21 @@ enum
SizeF = 1<<7, // float aka float32
SizeD = 1<<8, // double aka float64
- // Left side: address taken, read, write.
+ // Left side (Prog.from): address taken, read, write.
LeftAddr = 1<<9,
LeftRead = 1<<10,
LeftWrite = 1<<11,
-
- // Register in middle; never written.
+
+ // Register in middle (Prog.reg); only ever read.
RegRead = 1<<12,
CanRegRead = 1<<13,
-
- // Right side: address taken, read, write.
+
+ // Right side (Prog.to): address taken, read, write.
RightAddr = 1<<14,
RightRead = 1<<15,
RightWrite = 1<<16,
+ // Instruction updates whichever of from/to is type D_OREG
PostInc = 1<<17,
// Instruction kinds