github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/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  uint32 LOAD(Reg*);
    67  uint32 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;  		// variables written by this instruction.
    79  	Bits	use1; 		// variables read by prog->from.
    80  	Bits	use2; 		// variables read by prog->to.
    81  
    82  	Bits	refbehind;
    83  	Bits	refahead;
    84  	Bits	calbehind;
    85  	Bits	calahead;
    86  	Bits	regdiff;
    87  	Bits	act;
    88  
    89  	int32	regu;		// register used bitmap
    90  	int32	rpo;		// reverse post ordering
    91  	int32	active;
    92  
    93  	uint16	loop;		// x5 for every loop
    94  	uchar	refset;		// diagnostic generated
    95  
    96  	Reg*	p1;     	// predecessors of this instruction: p1,
    97  	Reg*	p2;     	// and then p2 linked though p2link.
    98  	Reg*	p2link;
    99  	Reg*	s1;     	// successors of this instruction (at most two: s1 and s2).
   100  	Reg*	s2;
   101  	Reg*	link;   	// next instruction in function code
   102  	Prog*	prog;   	// actual instruction
   103  };
   104  #define	R	((Reg*)0)
   105  /*c2go extern Reg *R; */
   106  
   107  #define	NRGN	600
   108  /*c2go enum { NRGN = 600 }; */
   109  struct	Rgn
   110  {
   111  	Reg*	enter;
   112  	short	cost;
   113  	short	varno;
   114  	short	regno;
   115  };
   116  
   117  EXTERN	int32	exregoffset;		// not set
   118  EXTERN	int32	exfregoffset;		// not set
   119  EXTERN	Reg	zreg;
   120  EXTERN	Reg*	freer;
   121  EXTERN	Reg**	rpo2r;
   122  EXTERN	Rgn	region[NRGN];
   123  EXTERN	Rgn*	rgp;
   124  EXTERN	int	nregion;
   125  EXTERN	int	nvar;
   126  EXTERN	int32	regbits;
   127  EXTERN	int32	exregbits;
   128  EXTERN	Bits	externs;
   129  EXTERN	Bits	params;
   130  EXTERN	Bits	consts;
   131  EXTERN	Bits	addrs;
   132  EXTERN	Bits	ivar;
   133  EXTERN	Bits	ovar;
   134  EXTERN	int	change;
   135  EXTERN	int32	maxnr;
   136  EXTERN	int32*	idom;
   137  
   138  EXTERN	struct
   139  {
   140  	int32	ncvtreg;
   141  	int32	nspill;
   142  	int32	nreload;
   143  	int32	ndelmov;
   144  	int32	nvar;
   145  	int32	naddr;
   146  } ostats;
   147  
   148  /*
   149   * reg.c
   150   */
   151  Reg*	rega(void);
   152  int	rcmp(const void*, const void*);
   153  void	regopt(Prog*);
   154  void	addmove(Reg*, int, int, int);
   155  Bits	mkvar(Reg*, Adr*);
   156  void	prop(Reg*, Bits, Bits);
   157  void	loopit(Reg*, int32);
   158  void	synch(Reg*, Bits);
   159  uint32	allreg(uint32, Rgn*);
   160  void	paint1(Reg*, int);
   161  uint32	paint2(Reg*, int);
   162  void	paint3(Reg*, int, int32, int);
   163  void	addreg(Adr*, int);
   164  void	dumpone(Flow*, int);
   165  void	dumpit(char*, Flow*, int);
   166  
   167  /*
   168   * peep.c
   169   */
   170  void	peep(Prog*);
   171  void	excise(Flow*);
   172  int	copyu(Prog*, Adr*, Adr*);
   173  
   174  int32	RtoB(int);
   175  int32	FtoB(int);
   176  int	BtoR(int32);
   177  int	BtoF(int32);
   178  
   179  /*
   180   * prog.c
   181   */
   182  typedef struct ProgInfo ProgInfo;
   183  struct ProgInfo
   184  {
   185  	uint32 flags; // the bits below
   186  	uint32 reguse; // required registers used by this instruction
   187  	uint32 regset; // required registers set by this instruction
   188  	uint32 regindex; // registers used by addressing mode
   189  };
   190  
   191  enum
   192  {
   193  	// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
   194  	Pseudo = 1<<1,
   195  	
   196  	// There's nothing to say about the instruction,
   197  	// but it's still okay to see.
   198  	OK = 1<<2,
   199  
   200  	// Size of right-side write, or right-side read if no write.
   201  	SizeB = 1<<3,
   202  	SizeW = 1<<4,
   203  	SizeL = 1<<5,
   204  	SizeQ = 1<<6,
   205  	SizeF = 1<<7, // float aka float32
   206  	SizeD = 1<<8, // double aka float64
   207  
   208  	// Left side: address taken, read, write.
   209  	LeftAddr = 1<<9,
   210  	LeftRead = 1<<10,
   211  	LeftWrite = 1<<11,
   212  	
   213  	// Right side: address taken, read, write.
   214  	RightAddr = 1<<12,
   215  	RightRead = 1<<13,
   216  	RightWrite = 1<<14,
   217  
   218  	// Set, use, or kill of carry bit.
   219  	// Kill means we never look at the carry bit after this kind of instruction.
   220  	SetCarry = 1<<15,
   221  	UseCarry = 1<<16,
   222  	KillCarry = 1<<17,
   223  
   224  	// Instruction kinds
   225  	Move = 1<<18, // straight move
   226  	Conv = 1<<19, // size conversion
   227  	Cjmp = 1<<20, // conditional jump
   228  	Break = 1<<21, // breaks control flow (no fallthrough)
   229  	Call = 1<<22, // function call
   230  	Jump = 1<<23, // jump
   231  	Skip = 1<<24, // data instruction
   232  
   233  	// Special cases for register use.
   234  	ShiftCX = 1<<25, // possible shift by CX
   235  	ImulAXDX = 1<<26, // possible multiply into DX:AX
   236  };
   237  
   238  void proginfo(ProgInfo*, Prog*);