github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/cmd/9g/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	BLOAD(r)	band(bnot(r->refbehind), r->refahead)
    37  #define	BSTORE(r)	band(bnot(r->calbehind), r->calahead)
    38  #define	LOAD(r)		(~r->refbehind.b[z] & r->refahead.b[z])
    39  #define	STORE(r)	(~r->calbehind.b[z] & r->calahead.b[z])
    40  
    41  #define	CLOAD	5
    42  #define	CREF	5
    43  #define	CINF	1000
    44  #define	LOOP	3
    45  
    46  typedef	struct	Reg	Reg;
    47  typedef	struct	Rgn	Rgn;
    48  
    49  /*c2go
    50  extern Node *Z;
    51  enum
    52  {
    53  	CLOAD = 5,
    54  	CREF = 5,
    55  	CINF = 1000,
    56  	LOOP = 3,
    57  };
    58  
    59  uint32 BLOAD(Reg*);
    60  uint32 BSTORE(Reg*);
    61  uint32 LOAD(Reg*);
    62  uint32 STORE(Reg*);
    63  */
    64  
    65  // A Reg is a wrapper around a single Prog (one instruction) that holds
    66  // register optimization information while the optimizer runs.
    67  // r->prog is the instruction.
    68  // r->prog->opt points back to r.
    69  struct	Reg
    70  {
    71  	Flow	f;
    72  
    73  	Bits	set;  		// regopt variables written by this instruction.
    74  	Bits	use1; 		// regopt variables read by prog->from.
    75  	Bits	use2; 		// regopt variables read by prog->to.
    76  
    77  	// refahead/refbehind are the regopt variables whose current
    78  	// value may be used in the following/preceding instructions
    79  	// up to a CALL (or the value is clobbered).
    80  	Bits	refbehind;
    81  	Bits	refahead;
    82  	// calahead/calbehind are similar, but for variables in
    83  	// instructions that are reachable after hitting at least one
    84  	// CALL.
    85  	Bits	calbehind;
    86  	Bits	calahead;
    87  	Bits	regdiff;
    88  	Bits	act;
    89  
    90  	uint64	regu;		// register used bitmap
    91  };
    92  #define	R	((Reg*)0)
    93  /*c2go extern Reg *R; */
    94  
    95  #define	NRGN	600
    96  /*c2go enum { NRGN = 600 }; */
    97  
    98  // A Rgn represents a single regopt variable over a region of code
    99  // where a register could potentially be dedicated to that variable.
   100  // The code encompassed by a Rgn is defined by the flow graph,
   101  // starting at enter, flood-filling forward while varno is refahead
   102  // and backward while varno is refbehind, and following branches.  A
   103  // single variable may be represented by multiple disjoint Rgns and
   104  // each Rgn may choose a different register for that variable.
   105  // Registers are allocated to regions greedily in order of descending
   106  // cost.
   107  struct	Rgn
   108  {
   109  	Reg*	enter;
   110  	short	cost;
   111  	short	varno;
   112  	short	regno;
   113  };
   114  
   115  EXTERN	int32	exregoffset;		// not set
   116  EXTERN	int32	exfregoffset;		// not set
   117  EXTERN	Reg	zreg;
   118  EXTERN	Rgn	region[NRGN];
   119  EXTERN	Rgn*	rgp;
   120  EXTERN	int	nregion;
   121  EXTERN	int	nvar;
   122  EXTERN	int32	regbits;
   123  EXTERN	int32	exregbits;		// TODO(austin) not used; remove
   124  EXTERN	Bits	externs;
   125  EXTERN	Bits	params;
   126  EXTERN	Bits	consts;
   127  EXTERN	Bits	addrs;
   128  EXTERN	Bits	ivar;
   129  EXTERN	Bits	ovar;
   130  EXTERN	int	change;
   131  EXTERN	int32	maxnr;
   132  
   133  EXTERN	struct
   134  {
   135  	int32	ncvtreg;
   136  	int32	nspill;
   137  	int32	ndelmov;
   138  	int32	nvar;
   139  } ostats;
   140  
   141  /*
   142   * reg.c
   143   */
   144  int	rcmp(const void*, const void*);
   145  void	regopt(Prog*);
   146  void	addmove(Reg*, int, int, int);
   147  Bits	mkvar(Reg*, Adr*);
   148  void	prop(Reg*, Bits, Bits);
   149  void	synch(Reg*, Bits);
   150  uint64	allreg(uint64, Rgn*);
   151  void	paint1(Reg*, int);
   152  uint64	paint2(Reg*, int, int);
   153  void	paint3(Reg*, int, uint64, int);
   154  void	addreg(Adr*, int);
   155  void	dumpone(Flow*, int);
   156  void	dumpit(char*, Flow*, int);
   157  
   158  /*
   159   * peep.c
   160   */
   161  void	peep(Prog*);
   162  void	excise(Flow*);
   163  int	copyu(Prog*, Adr*, Adr*);
   164  
   165  uint64	RtoB(int);
   166  uint64	FtoB(int);
   167  int	BtoR(uint64);
   168  int	BtoF(uint64);
   169  
   170  /*
   171   * prog.c
   172   */
   173  typedef struct ProgInfo ProgInfo;
   174  struct ProgInfo
   175  {
   176  	uint32 flags; // the bits below
   177  	uint64 reguse; // registers implicitly used by this instruction
   178  	uint64 regset; // registers implicitly set by this instruction
   179  	uint64 regindex; // registers used by addressing mode
   180  };
   181  
   182  enum
   183  {
   184  	// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
   185  	Pseudo = 1<<1,
   186  	
   187  	// There's nothing to say about the instruction,
   188  	// but it's still okay to see.
   189  	OK = 1<<2,
   190  
   191  	// Size of right-side write, or right-side read if no write.
   192  	SizeB = 1<<3,
   193  	SizeW = 1<<4,
   194  	SizeL = 1<<5,
   195  	SizeQ = 1<<6,
   196  	SizeF = 1<<7, // float aka float32
   197  	SizeD = 1<<8, // double aka float64
   198  
   199  	// Left side (Prog.from): address taken, read, write.
   200  	LeftAddr = 1<<9,
   201  	LeftRead = 1<<10,
   202  	LeftWrite = 1<<11,
   203  
   204  	// Register in middle (Prog.reg); only ever read.
   205  	RegRead = 1<<12,
   206  	CanRegRead = 1<<13,
   207  
   208  	// Right side (Prog.to): address taken, read, write.
   209  	RightAddr = 1<<14,
   210  	RightRead = 1<<15,
   211  	RightWrite = 1<<16,
   212  
   213  	// Instruction updates whichever of from/to is type D_OREG
   214  	PostInc = 1<<17,
   215  
   216  	// Instruction kinds
   217  	Move = 1<<18, // straight move
   218  	Conv = 1<<19, // size conversion
   219  	Cjmp = 1<<20, // conditional jump
   220  	Break = 1<<21, // breaks control flow (no fallthrough)
   221  	Call = 1<<22, // function call
   222  	Jump = 1<<23, // jump
   223  	Skip = 1<<24, // data instruction
   224  };
   225  
   226  void proginfo(ProgInfo*, Prog*);
   227  
   228  // Many Power ISA arithmetic and logical instructions come in four
   229  // standard variants.  These bits let us map between variants.
   230  enum {
   231  	V_CC = 1<<0,		// xCC (affect CR field 0 flags)
   232  	V_V  = 1<<1,		// xV (affect SO and OV flags)
   233  };
   234  
   235  int as2variant(int);
   236  int variant2as(int, int);
   237  
   238  // To allow use of AJMP, ACALL, ARET in ../gc/popt.c.
   239  enum
   240  {
   241  	AJMP = ABR,
   242  	ACALL = ABL,
   243  	ARET = ARETURN,
   244  };