2015-02-13 14:40:36 -05:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package gc
|
|
|
|
|
|
|
|
|
|
import (
|
2016-04-08 19:30:41 +10:00
|
|
|
"bufio"
|
2016-03-12 14:07:40 -08:00
|
|
|
"cmd/compile/internal/ssa"
|
2016-04-06 21:45:29 -07:00
|
|
|
"cmd/internal/bio"
|
2015-02-13 14:40:36 -05:00
|
|
|
"cmd/internal/obj"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
2015-03-05 10:39:23 -08:00
|
|
|
UINF = 100
|
|
|
|
|
BADWIDTH = -1000000000
|
|
|
|
|
MaxStackVarSize = 10 * 1024 * 1024
|
|
|
|
|
)
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
type Pkg struct {
|
2016-03-11 00:10:52 -05:00
|
|
|
Name string // package name, e.g. "sys"
|
|
|
|
|
Path string // string literal used in import statement, e.g. "runtime/internal/sys"
|
2016-03-31 10:02:10 -04:00
|
|
|
Pathsym *obj.LSym
|
2015-03-05 13:57:36 -05:00
|
|
|
Prefix string // escaped path for use in symbol table
|
2015-09-08 05:46:31 +02:00
|
|
|
Imported bool // export data of this package was parsed
|
|
|
|
|
Exported bool // import line written in export data
|
|
|
|
|
Direct bool // imported directly
|
2015-03-05 13:57:36 -05:00
|
|
|
Safe bool // whether the package is marked as safe
|
2015-03-02 16:21:15 -05:00
|
|
|
Syms map[string]*Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// Sym represents an object name. Most commonly, this is a Go identifier naming
|
|
|
|
|
// an object declared within a package, but Syms are also used to name internal
|
|
|
|
|
// synthesized objects.
|
|
|
|
|
//
|
|
|
|
|
// As a special exception, field and method names that are exported use the Sym
|
|
|
|
|
// associated with localpkg instead of the package that declared them. This
|
|
|
|
|
// allows using Sym pointer equality to test for Go identifier uniqueness when
|
|
|
|
|
// handling selector expressions.
|
2015-02-13 14:40:36 -05:00
|
|
|
type Sym struct {
|
2016-03-01 16:37:20 -08:00
|
|
|
Flags SymFlags
|
2016-02-26 01:37:28 -08:00
|
|
|
Link *Sym
|
2015-03-05 13:57:36 -05:00
|
|
|
Importdef *Pkg // where imported definition was found
|
|
|
|
|
Linkname string // link name
|
|
|
|
|
|
|
|
|
|
// saved and restored by dcopy
|
2015-02-13 14:40:36 -05:00
|
|
|
Pkg *Pkg
|
2015-03-05 13:57:36 -05:00
|
|
|
Name string // variable name
|
|
|
|
|
Def *Node // definition: ONAME OTYPE OPACK or OLITERAL
|
|
|
|
|
Block int32 // blocknumber to catch redeclaration
|
|
|
|
|
Lastlineno int32 // last declaration for diagnostic
|
2016-03-10 15:07:08 -08:00
|
|
|
|
|
|
|
|
Label *Label // corresponding label (ephemeral)
|
|
|
|
|
Origpkg *Pkg // original package for . import
|
|
|
|
|
Lsym *obj.LSym
|
|
|
|
|
Fsym *Sym // funcsym
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Label struct {
|
2016-03-10 20:35:27 -08:00
|
|
|
Sym *Sym
|
|
|
|
|
Def *Node
|
|
|
|
|
Use []*Node
|
2015-03-05 13:57:36 -05:00
|
|
|
|
|
|
|
|
// for use during gen
|
|
|
|
|
Gotopc *obj.Prog // pointer to unresolved gotos
|
|
|
|
|
Labelpc *obj.Prog // pointer to code
|
|
|
|
|
Breakpc *obj.Prog // pointer to code
|
|
|
|
|
Continpc *obj.Prog // pointer to code
|
2015-09-07 11:11:14 +10:00
|
|
|
|
|
|
|
|
Used bool
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 16:37:20 -08:00
|
|
|
type SymFlags uint8
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
const (
|
2016-03-01 16:37:20 -08:00
|
|
|
SymExport SymFlags = 1 << iota // to be exported
|
|
|
|
|
SymPackage
|
|
|
|
|
SymExported // already written out by export
|
|
|
|
|
SymUniq
|
|
|
|
|
SymSiggen
|
|
|
|
|
SymAsm
|
|
|
|
|
SymAlgGen
|
2015-02-13 14:40:36 -05:00
|
|
|
)
|
|
|
|
|
|
2015-10-26 14:57:36 -07:00
|
|
|
// The Class of a variable/function describes the "storage class"
|
|
|
|
|
// of a variable or function. During parsing, storage classes are
|
|
|
|
|
// called declaration contexts.
|
|
|
|
|
type Class uint8
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
const (
|
2015-10-26 14:57:36 -07:00
|
|
|
Pxxx Class = iota
|
|
|
|
|
PEXTERN // global variable
|
|
|
|
|
PAUTO // local variables
|
|
|
|
|
PPARAM // input arguments
|
|
|
|
|
PPARAMOUT // output results
|
|
|
|
|
PPARAMREF // closure variable reference
|
|
|
|
|
PFUNC // global function
|
2015-03-05 13:57:36 -05:00
|
|
|
|
|
|
|
|
PDISCARD // discard during parse of duplicate import
|
|
|
|
|
|
2015-10-26 14:57:36 -07:00
|
|
|
PHEAP = 1 << 7 // an extra bit to identify an escaped variable
|
2015-02-13 14:40:36 -05:00
|
|
|
)
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// note this is the runtime representation
|
|
|
|
|
// of the compilers arrays.
|
|
|
|
|
//
|
|
|
|
|
// typedef struct
|
|
|
|
|
// { // must not move anything
|
|
|
|
|
// uchar array[8]; // pointer to data
|
|
|
|
|
// uchar nel[4]; // number of elements
|
|
|
|
|
// uchar cap[4]; // allocated number of elements
|
|
|
|
|
// } Array;
|
2015-02-13 14:40:36 -05:00
|
|
|
var Array_array int // runtime offsetof(Array,array) - same for String
|
|
|
|
|
|
|
|
|
|
var Array_nel int // runtime offsetof(Array,nel) - same for String
|
|
|
|
|
|
|
|
|
|
var Array_cap int // runtime offsetof(Array,cap)
|
|
|
|
|
|
|
|
|
|
var sizeof_Array int // runtime sizeof(Array)
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// note this is the runtime representation
|
|
|
|
|
// of the compilers strings.
|
|
|
|
|
//
|
|
|
|
|
// typedef struct
|
|
|
|
|
// { // must not move anything
|
|
|
|
|
// uchar array[8]; // pointer to data
|
|
|
|
|
// uchar nel[4]; // number of elements
|
|
|
|
|
// } String;
|
2015-02-13 14:40:36 -05:00
|
|
|
var sizeof_String int // runtime sizeof(String)
|
|
|
|
|
|
|
|
|
|
var pragcgobuf string
|
|
|
|
|
|
|
|
|
|
var infile string
|
|
|
|
|
|
|
|
|
|
var outfile string
|
|
|
|
|
|
2016-04-08 19:14:03 +10:00
|
|
|
var bout *bio.Writer
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var nerrors int
|
|
|
|
|
|
|
|
|
|
var nsavederrors int
|
|
|
|
|
|
|
|
|
|
var nsyntaxerrors int
|
|
|
|
|
|
2015-05-14 19:33:31 -07:00
|
|
|
var decldepth int32
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var safemode int
|
|
|
|
|
|
|
|
|
|
var nolocalimports int
|
|
|
|
|
|
|
|
|
|
var Debug [256]int
|
|
|
|
|
|
|
|
|
|
var debugstr string
|
|
|
|
|
|
|
|
|
|
var Debug_checknil int
|
2015-03-20 00:06:10 -04:00
|
|
|
var Debug_typeassert int
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var localpkg *Pkg // package being compiled
|
|
|
|
|
|
|
|
|
|
var importpkg *Pkg // package being imported
|
|
|
|
|
|
2016-03-18 17:21:33 -07:00
|
|
|
var itabpkg *Pkg // fake pkg for itab entries
|
2016-03-17 06:18:13 -07:00
|
|
|
|
|
|
|
|
var itablinkpkg *Pkg // fake package for runtime itab entries
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
var Runtimepkg *Pkg // package runtime
|
|
|
|
|
|
|
|
|
|
var racepkg *Pkg // package runtime/race
|
|
|
|
|
|
2015-10-21 07:04:10 -07:00
|
|
|
var msanpkg *Pkg // package runtime/msan
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
var typepkg *Pkg // fake package for runtime type info (headers)
|
|
|
|
|
|
|
|
|
|
var unsafepkg *Pkg // package unsafe
|
|
|
|
|
|
|
|
|
|
var trackpkg *Pkg // fake package for field tracking
|
|
|
|
|
|
2015-09-24 23:21:18 +02:00
|
|
|
var Tptr EType // either TPTR32 or TPTR64
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var myimportpath string
|
|
|
|
|
|
|
|
|
|
var localimport string
|
|
|
|
|
|
|
|
|
|
var asmhdr string
|
|
|
|
|
|
2015-09-24 23:21:18 +02:00
|
|
|
var Simtype [NTYPE]EType
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-03-01 07:54:01 +00:00
|
|
|
var (
|
|
|
|
|
isforw [NTYPE]bool
|
|
|
|
|
Isint [NTYPE]bool
|
|
|
|
|
Isfloat [NTYPE]bool
|
|
|
|
|
Iscomplex [NTYPE]bool
|
|
|
|
|
issimple [NTYPE]bool
|
|
|
|
|
)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-03-01 07:54:01 +00:00
|
|
|
var (
|
|
|
|
|
okforeq [NTYPE]bool
|
|
|
|
|
okforadd [NTYPE]bool
|
|
|
|
|
okforand [NTYPE]bool
|
|
|
|
|
okfornone [NTYPE]bool
|
|
|
|
|
okforcmp [NTYPE]bool
|
|
|
|
|
okforbool [NTYPE]bool
|
|
|
|
|
okforcap [NTYPE]bool
|
|
|
|
|
okforlen [NTYPE]bool
|
|
|
|
|
okforarith [NTYPE]bool
|
|
|
|
|
okforconst [NTYPE]bool
|
|
|
|
|
)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-03-01 07:54:01 +00:00
|
|
|
var (
|
|
|
|
|
okfor [OEND][]bool
|
|
|
|
|
iscmp [OEND]bool
|
|
|
|
|
)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var Minintval [NTYPE]*Mpint
|
|
|
|
|
|
|
|
|
|
var Maxintval [NTYPE]*Mpint
|
|
|
|
|
|
|
|
|
|
var minfltval [NTYPE]*Mpflt
|
|
|
|
|
|
|
|
|
|
var maxfltval [NTYPE]*Mpflt
|
|
|
|
|
|
2016-03-09 20:29:21 -08:00
|
|
|
var xtop []*Node
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-08-12 14:29:50 -07:00
|
|
|
var exportlist []*Node
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-09-06 22:38:49 +02:00
|
|
|
var importlist []*Node // imported functions and methods with inlinable bodies
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-10-05 16:33:53 -07:00
|
|
|
var funcsyms []*Node
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-10-26 14:57:36 -07:00
|
|
|
var dclcontext Class // PEXTERN/PAUTO
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var incannedimport int
|
|
|
|
|
|
|
|
|
|
var statuniqgen int // name generator for static temps
|
|
|
|
|
|
|
|
|
|
var iota_ int32
|
|
|
|
|
|
2016-03-09 20:29:21 -08:00
|
|
|
var lastconst []*Node
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var lasttype *Node
|
|
|
|
|
|
|
|
|
|
var Maxarg int64
|
|
|
|
|
|
|
|
|
|
var Stksize int64 // stack size for current frame
|
|
|
|
|
|
|
|
|
|
var stkptrsize int64 // prefix of stack containing pointers
|
|
|
|
|
|
2015-09-07 22:19:30 +02:00
|
|
|
var hasdefer bool // flag that curfn has defer statement
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var Curfn *Node
|
|
|
|
|
|
|
|
|
|
var Widthptr int
|
|
|
|
|
|
|
|
|
|
var Widthint int
|
|
|
|
|
|
|
|
|
|
var Widthreg int
|
|
|
|
|
|
|
|
|
|
var nblank *Node
|
|
|
|
|
|
2015-03-10 09:58:01 +11:00
|
|
|
var Funcdepth int32
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-08-30 23:56:40 +02:00
|
|
|
var typecheckok bool
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var compiling_runtime int
|
|
|
|
|
|
|
|
|
|
var compiling_wrappers int
|
|
|
|
|
|
|
|
|
|
var use_writebarrier int
|
|
|
|
|
|
|
|
|
|
var pure_go int
|
|
|
|
|
|
|
|
|
|
var flag_installsuffix string
|
|
|
|
|
|
|
|
|
|
var flag_race int
|
|
|
|
|
|
2015-10-21 07:04:10 -07:00
|
|
|
var flag_msan int
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
var flag_largemodel int
|
|
|
|
|
|
2015-10-20 10:00:07 -07:00
|
|
|
// Whether we are adding any sort of code instrumentation, such as
|
|
|
|
|
// when the race detector is enabled.
|
|
|
|
|
var instrumenting bool
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
var debuglive int
|
|
|
|
|
|
|
|
|
|
var Ctxt *obj.Link
|
|
|
|
|
|
|
|
|
|
var writearchive int
|
|
|
|
|
|
2016-04-08 19:30:41 +10:00
|
|
|
var bstdout *bufio.Writer
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var Nacl bool
|
|
|
|
|
|
|
|
|
|
var continpc *obj.Prog
|
|
|
|
|
|
|
|
|
|
var breakpc *obj.Prog
|
|
|
|
|
|
|
|
|
|
var Pc *obj.Prog
|
|
|
|
|
|
|
|
|
|
var nodfp *Node
|
|
|
|
|
|
|
|
|
|
var Disable_checknil int
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// interface to back end
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
const (
|
2015-03-05 13:57:36 -05:00
|
|
|
// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
|
|
|
|
|
Pseudo = 1 << 1
|
|
|
|
|
|
|
|
|
|
// There's nothing to say about the instruction,
|
|
|
|
|
// but it's still okay to see.
|
|
|
|
|
OK = 1 << 2
|
|
|
|
|
|
|
|
|
|
// Size of right-side write, or right-side read if no write.
|
|
|
|
|
SizeB = 1 << 3
|
|
|
|
|
SizeW = 1 << 4
|
|
|
|
|
SizeL = 1 << 5
|
|
|
|
|
SizeQ = 1 << 6
|
|
|
|
|
SizeF = 1 << 7
|
|
|
|
|
SizeD = 1 << 8
|
|
|
|
|
|
|
|
|
|
// Left side (Prog.from): address taken, read, write.
|
|
|
|
|
LeftAddr = 1 << 9
|
|
|
|
|
LeftRead = 1 << 10
|
|
|
|
|
LeftWrite = 1 << 11
|
|
|
|
|
|
|
|
|
|
// Register in middle (Prog.reg); only ever read. (arm, ppc64)
|
2015-02-13 14:40:36 -05:00
|
|
|
RegRead = 1 << 12
|
|
|
|
|
CanRegRead = 1 << 13
|
2015-03-05 13:57:36 -05:00
|
|
|
|
|
|
|
|
// Right side (Prog.to): address taken, read, write.
|
2015-02-13 14:40:36 -05:00
|
|
|
RightAddr = 1 << 14
|
|
|
|
|
RightRead = 1 << 15
|
|
|
|
|
RightWrite = 1 << 16
|
2015-03-05 13:57:36 -05:00
|
|
|
|
|
|
|
|
// Instruction kinds
|
|
|
|
|
Move = 1 << 17 // straight move
|
|
|
|
|
Conv = 1 << 18 // size conversion
|
|
|
|
|
Cjmp = 1 << 19 // conditional jump
|
|
|
|
|
Break = 1 << 20 // breaks control flow (no fallthrough)
|
|
|
|
|
Call = 1 << 21 // function call
|
|
|
|
|
Jump = 1 << 22 // jump
|
|
|
|
|
Skip = 1 << 23 // data instruction
|
|
|
|
|
|
|
|
|
|
// Set, use, or kill of carry bit.
|
|
|
|
|
// Kill means we never look at the carry bit after this kind of instruction.
|
2016-03-11 00:10:52 -05:00
|
|
|
// Originally for understanding ADC, RCR, and so on, but now also
|
|
|
|
|
// tracks set, use, and kill of the zero and overflow bits as well.
|
|
|
|
|
// TODO rename to {Set,Use,Kill}Flags
|
2015-03-05 13:57:36 -05:00
|
|
|
SetCarry = 1 << 24
|
|
|
|
|
UseCarry = 1 << 25
|
|
|
|
|
KillCarry = 1 << 26
|
|
|
|
|
|
|
|
|
|
// Special cases for register use. (amd64, 386)
|
|
|
|
|
ShiftCX = 1 << 27 // possible shift by CX
|
|
|
|
|
ImulAXDX = 1 << 28 // possible multiply into DX:AX
|
|
|
|
|
|
|
|
|
|
// Instruction updates whichever of from/to is type D_OREG. (ppc64)
|
|
|
|
|
PostInc = 1 << 29
|
2015-02-13 14:40:36 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Arch struct {
|
2016-04-06 12:01:40 -07:00
|
|
|
LinkArch *obj.LinkArch
|
|
|
|
|
|
2015-03-18 17:26:36 -04:00
|
|
|
REGSP int
|
|
|
|
|
REGCTXT int
|
|
|
|
|
REGCALLX int // BX
|
|
|
|
|
REGCALLX2 int // AX
|
|
|
|
|
REGRETURN int // AX
|
|
|
|
|
REGMIN int
|
|
|
|
|
REGMAX int
|
2015-04-09 21:25:48 +10:00
|
|
|
REGZERO int // architectural zero register, if available
|
2015-03-18 17:26:36 -04:00
|
|
|
FREGMIN int
|
|
|
|
|
FREGMAX int
|
|
|
|
|
MAXWIDTH int64
|
|
|
|
|
ReservedRegs []int
|
|
|
|
|
|
|
|
|
|
AddIndex func(*Node, int64, *Node) bool // optional
|
|
|
|
|
Betypeinit func()
|
2015-04-06 19:36:36 -07:00
|
|
|
Bgen_float func(*Node, bool, int, *obj.Prog) // optional
|
|
|
|
|
Cgen64 func(*Node, *Node) // only on 32-bit systems
|
2015-03-18 17:26:36 -04:00
|
|
|
Cgenindex func(*Node, *Node, bool) *obj.Prog
|
2015-09-24 23:21:18 +02:00
|
|
|
Cgen_bmul func(Op, *Node, *Node, *Node) bool
|
2015-03-18 17:26:36 -04:00
|
|
|
Cgen_float func(*Node, *Node) // optional
|
|
|
|
|
Cgen_hmul func(*Node, *Node, *Node)
|
2015-09-24 23:21:18 +02:00
|
|
|
Cgen_shift func(Op, bool, *Node, *Node, *Node)
|
2015-03-18 17:26:36 -04:00
|
|
|
Clearfat func(*Node)
|
2015-09-24 23:21:18 +02:00
|
|
|
Cmp64 func(*Node, *Node, Op, int, *obj.Prog) // only on 32-bit systems
|
2015-03-18 17:26:36 -04:00
|
|
|
Defframe func(*obj.Prog)
|
2015-09-24 23:21:18 +02:00
|
|
|
Dodiv func(Op, *Node, *Node, *Node)
|
2015-03-18 17:26:36 -04:00
|
|
|
Excise func(*Flow)
|
|
|
|
|
Expandchecks func(*obj.Prog)
|
2015-04-03 12:23:28 -04:00
|
|
|
Getg func(*Node)
|
2016-03-07 18:00:08 -08:00
|
|
|
Gins func(obj.As, *Node, *Node) *obj.Prog
|
2015-05-06 12:28:19 -04:00
|
|
|
|
|
|
|
|
// Ginscmp generates code comparing n1 to n2 and jumping away if op is satisfied.
|
|
|
|
|
// The returned prog should be Patch'ed with the jump target.
|
|
|
|
|
// If op is not satisfied, code falls through to the next emitted instruction.
|
|
|
|
|
// Likely is the branch prediction hint: +1 for likely, -1 for unlikely, 0 for no opinion.
|
|
|
|
|
//
|
|
|
|
|
// Ginscmp must be able to handle all kinds of arguments for n1 and n2,
|
|
|
|
|
// not just simple registers, although it can assume that there are no
|
2015-05-15 16:11:25 -04:00
|
|
|
// function calls needed during the evaluation, and on 32-bit systems
|
|
|
|
|
// the values are guaranteed not to be 64-bit values, so no in-memory
|
|
|
|
|
// temporaries are necessary.
|
2015-09-24 23:21:18 +02:00
|
|
|
Ginscmp func(op Op, t *Type, n1, n2 *Node, likely int) *obj.Prog
|
2015-05-06 12:28:19 -04:00
|
|
|
|
cmd/internal/gc, cmd/6g: generate boolean values without jumps
Use SETcc instructions instead of Jcc to generate boolean values.
This generates shorter, jump-free code, which may in turn enable other
peephole optimizations.
For example, given
func f(i, j int) bool {
return i == j
}
Before
"".f t=1 size=32 value=0 args=0x18 locals=0x0
0x0000 00000 (x.go:3) TEXT "".f(SB), $0-24
0x0000 00000 (x.go:3) FUNCDATA $0, gclocals·b4c25e9b09fd0cf9bb429dcefe91c353(SB)
0x0000 00000 (x.go:3) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (x.go:4) MOVQ "".i+8(FP), BX
0x0005 00005 (x.go:4) MOVQ "".j+16(FP), BP
0x000a 00010 (x.go:4) CMPQ BX, BP
0x000d 00013 (x.go:4) JEQ 21
0x000f 00015 (x.go:4) MOVB $0, "".~r2+24(FP)
0x0014 00020 (x.go:4) RET
0x0015 00021 (x.go:4) MOVB $1, "".~r2+24(FP)
0x001a 00026 (x.go:4) JMP 20
After
"".f t=1 size=32 value=0 args=0x18 locals=0x0
0x0000 00000 (x.go:3) TEXT "".f(SB), $0-24
0x0000 00000 (x.go:3) FUNCDATA $0, gclocals·b4c25e9b09fd0cf9bb429dcefe91c353(SB)
0x0000 00000 (x.go:3) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (x.go:4) MOVQ "".i+8(FP), BX
0x0005 00005 (x.go:4) MOVQ "".j+16(FP), BP
0x000a 00010 (x.go:4) CMPQ BX, BP
0x000d 00013 (x.go:4) SETEQ "".~r2+24(FP)
0x0012 00018 (x.go:4) RET
regexp benchmarks, best of 12 runs:
benchmark old ns/op new ns/op delta
BenchmarkNotOnePassShortB 782 733 -6.27%
BenchmarkLiteral 180 171 -5.00%
BenchmarkNotLiteral 2855 2721 -4.69%
BenchmarkMatchHard_32 2672 2557 -4.30%
BenchmarkMatchHard_1K 80182 76732 -4.30%
BenchmarkMatchEasy1_32M 76440180 73304748 -4.10%
BenchmarkMatchEasy1_32K 68798 66350 -3.56%
BenchmarkAnchoredLongMatch 482 465 -3.53%
BenchmarkMatchEasy1_1M 2373042 2292692 -3.39%
BenchmarkReplaceAll 2776 2690 -3.10%
BenchmarkNotOnePassShortA 1397 1360 -2.65%
BenchmarkMatchClass_InRange 3842 3742 -2.60%
BenchmarkMatchEasy0_32 125 122 -2.40%
BenchmarkMatchEasy0_32K 11414 11164 -2.19%
BenchmarkMatchEasy0_1K 668 654 -2.10%
BenchmarkAnchoredShortMatch 260 255 -1.92%
BenchmarkAnchoredLiteralShortNonMatch 164 161 -1.83%
BenchmarkOnePassShortB 623 612 -1.77%
BenchmarkOnePassShortA 801 788 -1.62%
BenchmarkMatchClass 4094 4033 -1.49%
BenchmarkMatchEasy0_32M 14078800 13890704 -1.34%
BenchmarkMatchHard_32K 4095844 4045820 -1.22%
BenchmarkMatchEasy1_1K 1663 1643 -1.20%
BenchmarkMatchHard_1M 131261708 129708215 -1.18%
BenchmarkMatchHard_32M 4210112412 4169292003 -0.97%
BenchmarkMatchMedium_32K 2460752 2438611 -0.90%
BenchmarkMatchEasy0_1M 422914 419672 -0.77%
BenchmarkMatchMedium_1M 78581121 78040160 -0.69%
BenchmarkMatchMedium_32M 2515287278 2498464906 -0.67%
BenchmarkMatchMedium_32 1754 1746 -0.46%
BenchmarkMatchMedium_1K 52105 52106 +0.00%
BenchmarkAnchoredLiteralLongNonMatch 185 185 +0.00%
BenchmarkMatchEasy1_32 107 107 +0.00%
BenchmarkOnePassLongNotPrefix 505 505 +0.00%
BenchmarkOnePassLongPrefix 147 147 +0.00%
The godoc binary is ~0.12% smaller after this CL.
Updates #5729.
toolstash -cmp passes for all architectures other than amd64 and amd64p32.
Other architectures can be done in follow-up CLs.
Change-Id: I0e167e259274b722958567fc0af83a17ca002da7
Reviewed-on: https://go-review.googlesource.com/2284
Reviewed-by: Russ Cox <rsc@golang.org>
2015-04-08 09:54:15 -07:00
|
|
|
// Ginsboolval inserts instructions to convert the result
|
|
|
|
|
// of a just-completed comparison to a boolean value.
|
|
|
|
|
// The first argument is the conditional jump instruction
|
|
|
|
|
// corresponding to the desired value.
|
|
|
|
|
// The second argument is the destination.
|
|
|
|
|
// If not present, Ginsboolval will be emulated with jumps.
|
2016-03-07 18:00:08 -08:00
|
|
|
Ginsboolval func(obj.As, *Node)
|
2015-05-06 12:28:19 -04:00
|
|
|
|
2016-03-07 18:00:08 -08:00
|
|
|
Ginscon func(obj.As, int64, *Node)
|
2015-03-18 17:26:36 -04:00
|
|
|
Ginsnop func()
|
|
|
|
|
Gmove func(*Node, *Node)
|
|
|
|
|
Igenindex func(*Node, *Node, bool) *obj.Prog
|
|
|
|
|
Peep func(*obj.Prog)
|
|
|
|
|
Proginfo func(*obj.Prog) // fills in Prog.Info
|
|
|
|
|
Regtyp func(*obj.Addr) bool
|
|
|
|
|
Sameaddr func(*obj.Addr, *obj.Addr) bool
|
|
|
|
|
Smallindir func(*obj.Addr, *obj.Addr) bool
|
|
|
|
|
Stackaddr func(*obj.Addr) bool
|
2015-04-08 13:34:42 -04:00
|
|
|
Blockcopy func(*Node, *Node, int64, int64, int64)
|
2016-03-07 18:00:08 -08:00
|
|
|
Sudoaddable func(obj.As, *Node, *obj.Addr) bool
|
2015-03-18 17:26:36 -04:00
|
|
|
Sudoclean func()
|
|
|
|
|
Excludedregs func() uint64
|
|
|
|
|
RtoB func(int) uint64
|
|
|
|
|
FtoB func(int) uint64
|
|
|
|
|
BtoR func(uint64) int
|
|
|
|
|
BtoF func(uint64) int
|
2016-03-07 18:00:08 -08:00
|
|
|
Optoas func(Op, *Type) obj.As
|
2015-03-18 17:26:36 -04:00
|
|
|
Doregbits func(int) uint64
|
|
|
|
|
Regnames func(*int) []string
|
2015-03-25 09:17:09 +11:00
|
|
|
Use387 bool // should 8g use 387 FP instructions instead of sse2.
|
2016-03-12 14:07:40 -08:00
|
|
|
|
|
|
|
|
// SSARegToReg maps ssa register numbers to obj register numbers.
|
|
|
|
|
SSARegToReg []int16
|
|
|
|
|
|
|
|
|
|
// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
|
|
|
|
|
SSAMarkMoves func(*SSAGenState, *ssa.Block)
|
|
|
|
|
|
|
|
|
|
// SSAGenValue emits Prog(s) for the Value.
|
|
|
|
|
SSAGenValue func(*SSAGenState, *ssa.Value)
|
|
|
|
|
|
|
|
|
|
// SSAGenBlock emits end-of-block Progs. SSAGenValue should be called
|
|
|
|
|
// for all values in the block before SSAGenBlock.
|
|
|
|
|
SSAGenBlock func(s *SSAGenState, b, next *ssa.Block)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var pcloc int32
|
|
|
|
|
|
|
|
|
|
var Thearch Arch
|
|
|
|
|
|
|
|
|
|
var Newproc *Node
|
|
|
|
|
|
|
|
|
|
var Deferproc *Node
|
|
|
|
|
|
|
|
|
|
var Deferreturn *Node
|
|
|
|
|
|
|
|
|
|
var Panicindex *Node
|
|
|
|
|
|
|
|
|
|
var panicslice *Node
|
|
|
|
|
|
2015-10-28 13:55:46 -04:00
|
|
|
var panicdivide *Node
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
var throwreturn *Node
|
2015-09-18 15:11:30 -07:00
|
|
|
|
|
|
|
|
var growslice *Node
|
|
|
|
|
|
2016-01-25 17:06:54 -08:00
|
|
|
var writebarrierptr *Node
|
|
|
|
|
var typedmemmove *Node
|
2015-09-18 15:11:30 -07:00
|
|
|
|
|
|
|
|
var panicdottype *Node
|