github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/cmd/8g/opt.h (about) 1 // Derived from Inferno utils/6c/gc.h 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/gc.h 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 #include "../gc/popt.h" 32 33 #define Z N 34 #define Adr Addr 35 36 #define D_HI D_NONE 37 #define D_LO D_NONE 38 39 #define BLOAD(r) band(bnot(r->refbehind), r->refahead) 40 #define BSTORE(r) band(bnot(r->calbehind), r->calahead) 41 #define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z]) 42 #define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z]) 43 44 #define CLOAD 5 45 #define CREF 5 46 #define CINF 1000 47 #define LOOP 3 48 49 typedef struct Reg Reg; 50 typedef struct Rgn Rgn; 51 52 /*c2go 53 extern Node *Z; 54 enum 55 { 56 D_HI = D_NONE, 57 D_LO = D_NONE, 58 CLOAD = 5, 59 CREF = 5, 60 CINF = 1000, 61 LOOP = 3, 62 }; 63 64 uint32 BLOAD(Reg*); 65 uint32 BSTORE(Reg*); 66 uint64 LOAD(Reg*); 67 uint64 STORE(Reg*); 68 */ 69 70 // A Reg is a wrapper around a single Prog (one instruction) that holds 71 // register optimization information while the optimizer runs. 72 // r->prog is the instruction. 73 // r->prog->opt points back to r. 74 struct Reg 75 { 76 Flow f; 77 78 Bits set; // regopt variables written by this instruction. 79 Bits use1; // regopt variables read by prog->from. 80 Bits use2; // regopt variables read by prog->to. 81 82 // refahead/refbehind are the regopt variables whose current 83 // value may be used in the following/preceding instructions 84 // up to a CALL (or the value is clobbered). 85 Bits refbehind; 86 Bits refahead; 87 // calahead/calbehind are similar, but for variables in 88 // instructions that are reachable after hitting at least one 89 // CALL. 90 Bits calbehind; 91 Bits calahead; 92 Bits regdiff; 93 Bits act; 94 95 int32 regu; // register used bitmap 96 int32 rpo; // reverse post ordering 97 int32 active; 98 99 uint16 loop; // x5 for every loop 100 uchar refset; // diagnostic generated 101 102 Reg* p1; // predecessors of this instruction: p1, 103 Reg* p2; // and then p2 linked though p2link. 104 Reg* p2link; 105 Reg* s1; // successors of this instruction (at most two: s1 and s2). 106 Reg* s2; 107 Reg* link; // next instruction in function code 108 Prog* prog; // actual instruction 109 }; 110 #define R ((Reg*)0) 111 /*c2go extern Reg *R; */ 112 113 #define NRGN 600 114 /*c2go enum { NRGN = 600 }; */ 115 116 // A Rgn represents a single regopt variable over a region of code 117 // where a register could potentially be dedicated to that variable. 118 // The code encompassed by a Rgn is defined by the flow graph, 119 // starting at enter, flood-filling forward while varno is refahead 120 // and backward while varno is refbehind, and following branches. A 121 // single variable may be represented by multiple disjoint Rgns and 122 // each Rgn may choose a different register for that variable. 123 // Registers are allocated to regions greedily in order of descending 124 // cost. 125 struct Rgn 126 { 127 Reg* enter; 128 short cost; 129 short varno; 130 short regno; 131 }; 132 133 EXTERN int32 exregoffset; // not set 134 EXTERN int32 exfregoffset; // not set 135 EXTERN Reg zreg; 136 EXTERN Reg* freer; 137 EXTERN Reg** rpo2r; 138 EXTERN Rgn region[NRGN]; 139 EXTERN Rgn* rgp; 140 EXTERN int nregion; 141 EXTERN int nvar; 142 EXTERN int32 regbits; 143 EXTERN int32 exregbits; 144 EXTERN Bits externs; 145 EXTERN Bits params; 146 EXTERN Bits consts; 147 EXTERN Bits addrs; 148 EXTERN Bits ivar; 149 EXTERN Bits ovar; 150 EXTERN int change; 151 EXTERN int32 maxnr; 152 EXTERN int32* idom; 153 154 EXTERN struct 155 { 156 int32 ncvtreg; 157 int32 nspill; 158 int32 nreload; 159 int32 ndelmov; 160 int32 nvar; 161 int32 naddr; 162 } ostats; 163 164 /* 165 * reg.c 166 */ 167 Reg* rega(void); 168 int rcmp(const void*, const void*); 169 void regopt(Prog*); 170 void addmove(Reg*, int, int, int); 171 Bits mkvar(Reg*, Adr*); 172 void prop(Reg*, Bits, Bits); 173 void loopit(Reg*, int32); 174 void synch(Reg*, Bits); 175 uint32 allreg(uint32, Rgn*); 176 void paint1(Reg*, int); 177 uint32 paint2(Reg*, int, int); 178 void paint3(Reg*, int, uint32, int); 179 void addreg(Adr*, int); 180 void dumpone(Flow*, int); 181 void dumpit(char*, Flow*, int); 182 183 /* 184 * peep.c 185 */ 186 void peep(Prog*); 187 void excise(Flow*); 188 int copyu(Prog*, Adr*, Adr*); 189 190 uint32 RtoB(int); 191 uint32 FtoB(int); 192 int BtoR(uint32); 193 int BtoF(uint32); 194 195 /* 196 * prog.c 197 */ 198 typedef struct ProgInfo ProgInfo; 199 struct ProgInfo 200 { 201 uint32 flags; // the bits below 202 uint32 reguse; // registers implicitly used by this instruction 203 uint32 regset; // registers implicitly set by this instruction 204 uint32 regindex; // registers used by addressing mode 205 }; 206 207 enum 208 { 209 // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA. 210 Pseudo = 1<<1, 211 212 // There's nothing to say about the instruction, 213 // but it's still okay to see. 214 OK = 1<<2, 215 216 // Size of right-side write, or right-side read if no write. 217 SizeB = 1<<3, 218 SizeW = 1<<4, 219 SizeL = 1<<5, 220 SizeQ = 1<<6, 221 SizeF = 1<<7, // float aka float32 222 SizeD = 1<<8, // double aka float64 223 224 // Left side (Prog.from): address taken, read, write. 225 LeftAddr = 1<<9, 226 LeftRead = 1<<10, 227 LeftWrite = 1<<11, 228 229 // Right side (Prog.to): address taken, read, write. 230 RightAddr = 1<<12, 231 RightRead = 1<<13, 232 RightWrite = 1<<14, 233 234 // Set, use, or kill of carry bit. 235 // Kill means we never look at the carry bit after this kind of instruction. 236 SetCarry = 1<<15, 237 UseCarry = 1<<16, 238 KillCarry = 1<<17, 239 240 // Instruction kinds 241 Move = 1<<18, // straight move 242 Conv = 1<<19, // size conversion 243 Cjmp = 1<<20, // conditional jump 244 Break = 1<<21, // breaks control flow (no fallthrough) 245 Call = 1<<22, // function call 246 Jump = 1<<23, // jump 247 Skip = 1<<24, // data instruction 248 249 // Special cases for register use. 250 ShiftCX = 1<<25, // possible shift by CX 251 ImulAXDX = 1<<26, // possible multiply into DX:AX 252 }; 253 254 void proginfo(ProgInfo*, Prog*);