2016-03-01 22:57:46 +00:00
|
|
|
// Copyright 2012 The Go Authors. All rights reserved.
|
2015-02-13 14:40:36 -05:00
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
2020-12-23 01:05:16 -05:00
|
|
|
package walk
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
import (
|
2020-12-23 01:05:16 -05:00
|
|
|
"fmt"
|
2021-04-12 16:12:20 -04:00
|
|
|
"go/constant"
|
2020-12-23 01:05:16 -05:00
|
|
|
|
2020-11-19 20:49:23 -05:00
|
|
|
"cmd/compile/internal/base"
|
2020-12-23 00:51:28 -05:00
|
|
|
"cmd/compile/internal/escape"
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
"cmd/compile/internal/ir"
|
2020-12-23 00:55:38 -05:00
|
|
|
"cmd/compile/internal/reflectdata"
|
2020-12-23 01:05:16 -05:00
|
|
|
"cmd/compile/internal/staticinit"
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
"cmd/compile/internal/typecheck"
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
"cmd/compile/internal/types"
|
2021-02-24 12:55:52 -05:00
|
|
|
"cmd/internal/objabi"
|
2016-12-07 16:02:42 -08:00
|
|
|
"cmd/internal/src"
|
2015-02-13 14:40:36 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Rewrite tree to use separate statements to enforce
|
2016-03-01 23:21:55 +00:00
|
|
|
// order of evaluation. Makes walk easier, because it
|
2015-02-13 14:40:36 -05:00
|
|
|
// can (after this runs) reorder at will within an expression.
|
|
|
|
|
//
|
cmd/compile: avoid extra mapaccess in "m[k] op= r"
Currently, order desugars map assignment operations like
m[k] op= r
into
m[k] = m[k] op r
which in turn is transformed during walk into:
tmp := *mapaccess(m, k)
tmp = tmp op r
*mapassign(m, k) = tmp
However, this is suboptimal, as we could instead produce just:
*mapassign(m, k) op= r
One complication though is if "r == 0", then "m[k] /= r" and "m[k] %=
r" will panic, and they need to do so *before* calling mapassign,
otherwise we may insert a new zero-value element into the map.
It would be spec compliant to just emit the "r != 0" check before
calling mapassign (see #23735), but currently these checks aren't
generated until SSA construction. For now, it's simpler to continue
desugaring /= and %= into two map indexing operations.
Fixes #23661.
Change-Id: I46e3739d9adef10e92b46fdd78b88d5aabe68952
Reviewed-on: https://go-review.googlesource.com/91557
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
2018-02-01 21:33:56 -08:00
|
|
|
// Rewrite m[k] op= r into m[k] = m[k] op r if op is / or %.
|
2015-02-13 14:40:36 -05:00
|
|
|
//
|
|
|
|
|
// Introduce temporaries as needed by runtime routines.
|
|
|
|
|
// For example, the map runtime routines take the map key
|
|
|
|
|
// by reference, so make sure all map keys are addressable
|
|
|
|
|
// by copying them to temporaries as needed.
|
|
|
|
|
// The same is true for channel operations.
|
|
|
|
|
//
|
|
|
|
|
// Arrange that map index expressions only appear in direct
|
|
|
|
|
// assignments x = m[k] or m[k] = x, never in larger expressions.
|
|
|
|
|
//
|
|
|
|
|
// Arrange that receive expressions only appear in direct assignments
|
|
|
|
|
// x = <-c or as standalone statements <-c, never in larger expressions.
|
|
|
|
|
|
|
|
|
|
// TODO(rsc): The temporary introduction during multiple assignments
|
|
|
|
|
// should be moved into this file, so that the temporaries can be cleaned
|
|
|
|
|
// and so that conversions implicit in the OAS2FUNC and OAS2RECV
|
|
|
|
|
// nodes can be made explicit and then have their temporaries cleaned.
|
|
|
|
|
|
|
|
|
|
// TODO(rsc): Goto and multilevel break/continue can jump over
|
|
|
|
|
// inserted VARKILL annotations. Work out a way to handle these.
|
|
|
|
|
// The current implementation is safe, in that it will execute correctly.
|
|
|
|
|
// But it won't reuse temporaries as aggressively as it might, and
|
|
|
|
|
// it can result in unnecessary zeroing of those variables in the function
|
|
|
|
|
// prologue.
|
|
|
|
|
|
2020-12-23 01:05:16 -05:00
|
|
|
// orderState holds state during the ordering process.
|
|
|
|
|
type orderState struct {
|
2020-12-04 11:38:47 +07:00
|
|
|
out []ir.Node // list of generated statements
|
|
|
|
|
temp []*ir.Name // stack of temporary variables
|
|
|
|
|
free map[string][]*ir.Name // free list of unused temporaries, by type.LongString().
|
2020-12-07 16:07:38 -05:00
|
|
|
edit func(ir.Node) ir.Node // cached closure of o.exprNoLHS
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// Order rewrites fn.Nbody to apply the ordering constraints
|
2015-02-13 14:40:36 -05:00
|
|
|
// described in the comment at the top of the file.
|
2020-11-28 07:31:18 -05:00
|
|
|
func order(fn *ir.Func) {
|
2020-11-19 20:49:23 -05:00
|
|
|
if base.Flag.W > 1 {
|
2020-11-28 07:31:18 -05:00
|
|
|
s := fmt.Sprintf("\nbefore order %v", fn.Sym())
|
2020-12-23 00:02:08 -05:00
|
|
|
ir.DumpList(s, fn.Body)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
orderBlock(&fn.Body, map[string][]*ir.Name{})
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-12-07 14:56:49 -05:00
|
|
|
// append typechecks stmt and appends it to out.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) append(stmt ir.Node) {
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
o.out = append(o.out, typecheck.Stmt(stmt))
|
2020-12-07 14:56:49 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// newTemp allocates a new temporary with the given type,
|
2015-02-13 14:40:36 -05:00
|
|
|
// pushes it onto the temp stack, and returns it.
|
2018-03-04 17:17:55 -08:00
|
|
|
// If clear is true, newTemp emits code to zero the temporary.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) newTemp(t *types.Type, clear bool) *ir.Name {
|
2020-12-04 11:38:47 +07:00
|
|
|
var v *ir.Name
|
2018-10-05 08:54:50 -07:00
|
|
|
// Note: LongString is close to the type equality we want,
|
2019-08-23 00:15:40 +07:00
|
|
|
// but not exactly. We still need to double-check with types.Identical.
|
2018-10-05 08:54:50 -07:00
|
|
|
key := t.LongString()
|
|
|
|
|
a := o.free[key]
|
|
|
|
|
for i, n := range a {
|
2020-11-22 09:59:15 -05:00
|
|
|
if types.Identical(t, n.Type()) {
|
2018-10-05 08:54:50 -07:00
|
|
|
v = a[i]
|
|
|
|
|
a[i] = a[len(a)-1]
|
|
|
|
|
a = a[:len(a)-1]
|
|
|
|
|
o.free[key] = a
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if v == nil {
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
v = typecheck.Temp(t)
|
2018-10-05 08:54:50 -07:00
|
|
|
}
|
2015-02-17 22:13:49 -05:00
|
|
|
if clear {
|
[dev.regabi] cmd/compile: remove ir.Nod [generated]
Rewrite all uses of ir.Nod and friends to call the IR constructors directly.
This gives the results a more specific type and will play nicely with
introduction of more specific types throughout the code in a followup CL.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/compile/internal/syntax"
import "cmd/internal/src"
var p *noder
var orig syntax.Node
var op ir.Op
var l, r ir.Node
var sym *types.Sym
p.nod(orig, op, l, r) -> ir.NodAt(p.pos(orig), op, l, r)
p.nodSym(orig, op, l, sym) -> nodlSym(p.pos(orig), op, l, sym)
var xpos src.XPos
var ns ir.Nodes
npos(xpos, nodSym(op, l, sym)) -> nodlSym(xpos, op, l, sym)
npos(xpos, liststmt(ns)) -> ir.NewBlockStmt(xpos, ns)
}
ex . ../ir {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
var op ir.Op
var l, r ir.Node
ir.Nod(op, l, r) -> ir.NodAt(base.Pos, op, l, r)
var sym *types.Sym
nodSym(op, l, sym) -> nodlSym(base.Pos, op, l, sym)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/internal/src"
# rf overlapping match handling is not quite good enough
# for certain nested rewrites, so handle these two - which often contain other ir.NodAt calls - early.
var l, r ir.Node
var xpos src.XPos
ir.NodAt(xpos, ir.OAS, l, r) -> ir.NewAssignStmt(xpos, l, r)
ir.NodAt(xpos, ir.OIF, l, nil) -> ir.NewIfStmt(xpos, l, nil, nil)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var l, r ir.Node
var sym *types.Sym
var xpos src.XPos
nodlSym(xpos, ir.ODOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, sym)
nodlSym(xpos, ir.OXDOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, sym)
nodlSym(xpos, ir.ODOTPTR, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, sym)
nodlSym(xpos, ir.OGOTO, nil, sym) -> ir.NewBranchStmt(xpos, ir.OGOTO, sym)
nodlSym(xpos, ir.ORETJMP, nil, sym) -> ir.NewBranchStmt(xpos, ir.ORETJMP, sym)
nodlSym(xpos, ir.OLABEL, nil, sym) -> ir.NewLabelStmt(xpos, sym)
nodlSym(xpos, ir.OSTRUCTKEY, l, sym) -> ir.NewStructKeyExpr(xpos, sym, l)
ir.NodAt(xpos, ir.OADD, l, r) -> ir.NewBinaryExpr(xpos, ir.OADD, l, r)
ir.NodAt(xpos, ir.OAND, l, r) -> ir.NewBinaryExpr(xpos, ir.OAND, l, r)
ir.NodAt(xpos, ir.OANDNOT, l, r) -> ir.NewBinaryExpr(xpos, ir.OANDNOT, l, r)
ir.NodAt(xpos, ir.ODIV, l, r) -> ir.NewBinaryExpr(xpos, ir.ODIV, l, r)
ir.NodAt(xpos, ir.OEQ, l, r) -> ir.NewBinaryExpr(xpos, ir.OEQ, l, r)
ir.NodAt(xpos, ir.OGE, l, r) -> ir.NewBinaryExpr(xpos, ir.OGE, l, r)
ir.NodAt(xpos, ir.OGT, l, r) -> ir.NewBinaryExpr(xpos, ir.OGT, l, r)
ir.NodAt(xpos, ir.OLE, l, r) -> ir.NewBinaryExpr(xpos, ir.OLE, l, r)
ir.NodAt(xpos, ir.OLSH, l, r) -> ir.NewBinaryExpr(xpos, ir.OLSH, l, r)
ir.NodAt(xpos, ir.OLT, l, r) -> ir.NewBinaryExpr(xpos, ir.OLT, l, r)
ir.NodAt(xpos, ir.OMOD, l, r) -> ir.NewBinaryExpr(xpos, ir.OMOD, l, r)
ir.NodAt(xpos, ir.OMUL, l, r) -> ir.NewBinaryExpr(xpos, ir.OMUL, l, r)
ir.NodAt(xpos, ir.ONE, l, r) -> ir.NewBinaryExpr(xpos, ir.ONE, l, r)
ir.NodAt(xpos, ir.OOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OOR, l, r)
ir.NodAt(xpos, ir.ORSH, l, r) -> ir.NewBinaryExpr(xpos, ir.ORSH, l, r)
ir.NodAt(xpos, ir.OSUB, l, r) -> ir.NewBinaryExpr(xpos, ir.OSUB, l, r)
ir.NodAt(xpos, ir.OXOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OXOR, l, r)
ir.NodAt(xpos, ir.OCOPY, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOPY, l, r)
ir.NodAt(xpos, ir.OCOMPLEX, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOMPLEX, l, r)
ir.NodAt(xpos, ir.OEFACE, l, r) -> ir.NewBinaryExpr(xpos, ir.OEFACE, l, r)
ir.NodAt(xpos, ir.OADDR, l, nil) -> ir.NewAddrExpr(xpos, l)
ir.NodAt(xpos, ir.OADDSTR, nil, nil) -> ir.NewAddStringExpr(xpos, nil)
ir.NodAt(xpos, ir.OANDAND, l, r) -> ir.NewLogicalExpr(xpos, ir.OANDAND, l, r)
ir.NodAt(xpos, ir.OOROR, l, r) -> ir.NewLogicalExpr(xpos, ir.OOROR, l, r)
ir.NodAt(xpos, ir.OARRAYLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, nil, nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, nil, nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, nil, nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, nil, nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, nil, nil)
ir.NodAt(xpos, ir.OARRAYLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OAS2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2, nil, nil)
ir.NodAt(xpos, ir.OAS2DOTTYPE, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2DOTTYPE, nil, nil)
ir.NodAt(xpos, ir.OAS2FUNC, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2FUNC, nil, nil)
ir.NodAt(xpos, ir.OAS2MAPR, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2MAPR, nil, nil)
ir.NodAt(xpos, ir.OAS2RECV, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2RECV, nil, nil)
ir.NodAt(xpos, ir.OSELRECV2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OSELRECV2, nil, nil)
ir.NodAt(xpos, ir.OASOP, l, r) -> ir.NewAssignOpStmt(xpos, ir.OXXX, l, r)
ir.NodAt(xpos, ir.OBITNOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.OBITNOT, l)
ir.NodAt(xpos, ir.ONEG, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEG, l)
ir.NodAt(xpos, ir.ONOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONOT, l)
ir.NodAt(xpos, ir.OPLUS, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPLUS, l)
ir.NodAt(xpos, ir.ORECV, l, nil) -> ir.NewUnaryExpr(xpos, ir.ORECV, l)
ir.NodAt(xpos, ir.OALIGNOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OALIGNOF, l)
ir.NodAt(xpos, ir.OCAP, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCAP, l)
ir.NodAt(xpos, ir.OCLOSE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCLOSE, l)
ir.NodAt(xpos, ir.OIMAG, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIMAG, l)
ir.NodAt(xpos, ir.OLEN, l, nil) -> ir.NewUnaryExpr(xpos, ir.OLEN, l)
ir.NodAt(xpos, ir.ONEW, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEW, l)
ir.NodAt(xpos, ir.ONEWOBJ, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEWOBJ, l)
ir.NodAt(xpos, ir.OOFFSETOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OOFFSETOF, l)
ir.NodAt(xpos, ir.OPANIC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPANIC, l)
ir.NodAt(xpos, ir.OREAL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OREAL, l)
ir.NodAt(xpos, ir.OSIZEOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSIZEOF, l)
ir.NodAt(xpos, ir.OCHECKNIL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCHECKNIL, l)
ir.NodAt(xpos, ir.OCFUNC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCFUNC, l)
ir.NodAt(xpos, ir.OIDATA, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIDATA, l)
ir.NodAt(xpos, ir.OITAB, l, nil) -> ir.NewUnaryExpr(xpos, ir.OITAB, l)
ir.NodAt(xpos, ir.OSPTR, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSPTR, l)
ir.NodAt(xpos, ir.OVARDEF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARDEF, l)
ir.NodAt(xpos, ir.OVARKILL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARKILL, l)
ir.NodAt(xpos, ir.OVARLIVE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARLIVE, l)
ir.NodAt(xpos, ir.OBLOCK, nil, nil) -> ir.NewBlockStmt(xpos, nil)
ir.NodAt(xpos, ir.OBREAK, nil, nil) -> ir.NewBranchStmt(xpos, ir.OBREAK, nil)
ir.NodAt(xpos, ir.OCONTINUE, nil, nil) -> ir.NewBranchStmt(xpos, ir.OCONTINUE, nil)
ir.NodAt(xpos, ir.OFALL, nil, nil) -> ir.NewBranchStmt(xpos, ir.OFALL, nil)
ir.NodAt(xpos, ir.OGOTO, nil, nil) -> ir.NewBranchStmt(xpos, ir.OGOTO, nil)
ir.NodAt(xpos, ir.ORETJMP, nil, nil) -> ir.NewBranchStmt(xpos, ir.ORETJMP, nil)
ir.NodAt(xpos, ir.OCALL, l, nil) -> ir.NewCallExpr(xpos, ir.OCALL, l, nil)
ir.NodAt(xpos, ir.OCALLFUNC, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLFUNC, l, nil)
ir.NodAt(xpos, ir.OCALLINTER, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLINTER, l, nil)
ir.NodAt(xpos, ir.OCALLMETH, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLMETH, l, nil)
ir.NodAt(xpos, ir.OAPPEND, l, nil) -> ir.NewCallExpr(xpos, ir.OAPPEND, l, nil)
ir.NodAt(xpos, ir.ODELETE, l, nil) -> ir.NewCallExpr(xpos, ir.ODELETE, l, nil)
ir.NodAt(xpos, ir.OGETG, l, nil) -> ir.NewCallExpr(xpos, ir.OGETG, l, nil)
ir.NodAt(xpos, ir.OMAKE, l, nil) -> ir.NewCallExpr(xpos, ir.OMAKE, l, nil)
ir.NodAt(xpos, ir.OPRINT, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINT, l, nil)
ir.NodAt(xpos, ir.OPRINTN, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINTN, l, nil)
ir.NodAt(xpos, ir.ORECOVER, l, nil) -> ir.NewCallExpr(xpos, ir.ORECOVER, l, nil)
ir.NodAt(xpos, ir.OCASE, nil, nil) -> ir.NewCaseStmt(xpos, nil, nil)
ir.NodAt(xpos, ir.OCONV, l, nil) -> ir.NewConvExpr(xpos, ir.OCONV, nil, l)
ir.NodAt(xpos, ir.OCONVIFACE, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVIFACE, nil, l)
ir.NodAt(xpos, ir.OCONVNOP, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVNOP, nil, l)
ir.NodAt(xpos, ir.ORUNESTR, l, nil) -> ir.NewConvExpr(xpos, ir.ORUNESTR, nil, l)
ir.NodAt(xpos, ir.ODCL, l, nil) -> ir.NewDecl(xpos, ir.ODCL, l)
ir.NodAt(xpos, ir.ODCLCONST, l, nil) -> ir.NewDecl(xpos, ir.ODCLCONST, l)
ir.NodAt(xpos, ir.ODCLTYPE, l, nil) -> ir.NewDecl(xpos, ir.ODCLTYPE, l)
ir.NodAt(xpos, ir.ODCLFUNC, nil, nil) -> ir.NewFunc(xpos)
ir.NodAt(xpos, ir.ODEFER, l, nil) -> ir.NewGoDeferStmt(xpos, ir.ODEFER, l)
ir.NodAt(xpos, ir.OGO, l, nil) -> ir.NewGoDeferStmt(xpos, ir.OGO, l)
ir.NodAt(xpos, ir.ODEREF, l, nil) -> ir.NewStarExpr(xpos, l)
ir.NodAt(xpos, ir.ODOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, nil)
ir.NodAt(xpos, ir.ODOTPTR, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, nil)
ir.NodAt(xpos, ir.ODOTMETH, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTMETH, l, nil)
ir.NodAt(xpos, ir.ODOTINTER, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTINTER, l, nil)
ir.NodAt(xpos, ir.OXDOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, nil) -> ir.NewTypeAssertExpr(xpos, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, r) -> ir.NewTypeAssertExpr(xpos, l, r.(ir.Ntype))
ir.NodAt(xpos, ir.OFOR, l, r) -> ir.NewForStmt(xpos, nil, l, r, nil)
ir.NodAt(xpos, ir.OINDEX, l, r) -> ir.NewIndexExpr(xpos, l, r)
ir.NodAt(xpos, ir.OINLMARK, nil, nil) -> ir.NewInlineMarkStmt(xpos, types.BADWIDTH)
ir.NodAt(xpos, ir.OKEY, l, r) -> ir.NewKeyExpr(xpos, l, r)
ir.NodAt(xpos, ir.OLABEL, nil, nil) -> ir.NewLabelStmt(xpos, nil)
ir.NodAt(xpos, ir.OMAKECHAN, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKECHAN, l, r)
ir.NodAt(xpos, ir.OMAKEMAP, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKEMAP, l, r)
ir.NodAt(xpos, ir.OMAKESLICE, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICE, l, r)
ir.NodAt(xpos, ir.OMAKESLICECOPY, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICECOPY, l, r)
ir.NodAt(xpos, ir.ONIL, nil, nil) -> ir.NewNilExpr(xpos)
ir.NodAt(xpos, ir.OPACK, nil, nil) -> ir.NewPkgName(xpos, nil, nil)
ir.NodAt(xpos, ir.OPAREN, l, nil) -> ir.NewParenExpr(xpos, l)
ir.NodAt(xpos, ir.ORANGE, nil, r) -> ir.NewRangeStmt(xpos, nil, r, nil)
ir.NodAt(xpos, ir.ORESULT, nil, nil) -> ir.NewResultExpr(xpos, nil, types.BADWIDTH)
ir.NodAt(xpos, ir.ORETURN, nil, nil) -> ir.NewReturnStmt(xpos, nil)
ir.NodAt(xpos, ir.OSELECT, nil, nil) -> ir.NewSelectStmt(xpos, nil)
ir.NodAt(xpos, ir.OSEND, l, r) -> ir.NewSendStmt(xpos, l, r)
ir.NodAt(xpos, ir.OSLICE, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE, l)
ir.NodAt(xpos, ir.OSLICEARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICEARR, l)
ir.NodAt(xpos, ir.OSLICESTR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICESTR, l)
ir.NodAt(xpos, ir.OSLICE3, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3, l)
ir.NodAt(xpos, ir.OSLICE3ARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3ARR, l)
ir.NodAt(xpos, ir.OSLICEHEADER, l, nil) -> ir.NewSliceHeaderExpr(xpos, nil, l, nil, nil)
ir.NodAt(xpos, ir.OSWITCH, l, nil) -> ir.NewSwitchStmt(xpos, l, nil)
ir.NodAt(xpos, ir.OINLCALL, nil, nil) -> ir.NewInlinedCallExpr(xpos, nil, nil)
}
rm noder.nod noder.nodSym nodSym nodlSym ir.NodAt ir.Nod
'
Change-Id: Ibf1eb708de8463ae74ccc47d7966cc263a18295e
Reviewed-on: https://go-review.googlesource.com/c/go/+/277933
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:55:29 -05:00
|
|
|
o.append(ir.NewAssignStmt(base.Pos, v, nil))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
o.temp = append(o.temp, v)
|
|
|
|
|
return v
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2019-10-05 00:00:38 +07:00
|
|
|
// copyExpr behaves like newTemp but also emits
|
2015-02-13 14:40:36 -05:00
|
|
|
// code to initialize the temporary to the value n.
|
2020-12-31 16:51:12 +07:00
|
|
|
func (o *orderState) copyExpr(n ir.Node) *ir.Name {
|
2020-11-29 11:16:20 -05:00
|
|
|
return o.copyExpr1(n, false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// copyExprClear is like copyExpr but clears the temp before assignment.
|
|
|
|
|
// It is provided for use when the evaluation of tmp = n turns into
|
|
|
|
|
// a function call that is passed a pointer to the temporary as the output space.
|
|
|
|
|
// If the call blocks before tmp has been written,
|
|
|
|
|
// the garbage collector will still treat the temporary as live,
|
|
|
|
|
// so we must zero it before entering that call.
|
2015-02-13 14:40:36 -05:00
|
|
|
// Today, this only happens for channel receive operations.
|
|
|
|
|
// (The other candidate would be map access, but map access
|
|
|
|
|
// returns a pointer to the result data instead of taking a pointer
|
|
|
|
|
// to be filled in.)
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) copyExprClear(n ir.Node) *ir.Name {
|
2020-11-29 11:16:20 -05:00
|
|
|
return o.copyExpr1(n, true)
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) copyExpr1(n ir.Node, clear bool) *ir.Name {
|
2020-11-29 11:16:20 -05:00
|
|
|
t := n.Type()
|
2018-03-04 17:17:55 -08:00
|
|
|
v := o.newTemp(t, clear)
|
[dev.regabi] cmd/compile: remove ir.Nod [generated]
Rewrite all uses of ir.Nod and friends to call the IR constructors directly.
This gives the results a more specific type and will play nicely with
introduction of more specific types throughout the code in a followup CL.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/compile/internal/syntax"
import "cmd/internal/src"
var p *noder
var orig syntax.Node
var op ir.Op
var l, r ir.Node
var sym *types.Sym
p.nod(orig, op, l, r) -> ir.NodAt(p.pos(orig), op, l, r)
p.nodSym(orig, op, l, sym) -> nodlSym(p.pos(orig), op, l, sym)
var xpos src.XPos
var ns ir.Nodes
npos(xpos, nodSym(op, l, sym)) -> nodlSym(xpos, op, l, sym)
npos(xpos, liststmt(ns)) -> ir.NewBlockStmt(xpos, ns)
}
ex . ../ir {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
var op ir.Op
var l, r ir.Node
ir.Nod(op, l, r) -> ir.NodAt(base.Pos, op, l, r)
var sym *types.Sym
nodSym(op, l, sym) -> nodlSym(base.Pos, op, l, sym)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/internal/src"
# rf overlapping match handling is not quite good enough
# for certain nested rewrites, so handle these two - which often contain other ir.NodAt calls - early.
var l, r ir.Node
var xpos src.XPos
ir.NodAt(xpos, ir.OAS, l, r) -> ir.NewAssignStmt(xpos, l, r)
ir.NodAt(xpos, ir.OIF, l, nil) -> ir.NewIfStmt(xpos, l, nil, nil)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var l, r ir.Node
var sym *types.Sym
var xpos src.XPos
nodlSym(xpos, ir.ODOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, sym)
nodlSym(xpos, ir.OXDOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, sym)
nodlSym(xpos, ir.ODOTPTR, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, sym)
nodlSym(xpos, ir.OGOTO, nil, sym) -> ir.NewBranchStmt(xpos, ir.OGOTO, sym)
nodlSym(xpos, ir.ORETJMP, nil, sym) -> ir.NewBranchStmt(xpos, ir.ORETJMP, sym)
nodlSym(xpos, ir.OLABEL, nil, sym) -> ir.NewLabelStmt(xpos, sym)
nodlSym(xpos, ir.OSTRUCTKEY, l, sym) -> ir.NewStructKeyExpr(xpos, sym, l)
ir.NodAt(xpos, ir.OADD, l, r) -> ir.NewBinaryExpr(xpos, ir.OADD, l, r)
ir.NodAt(xpos, ir.OAND, l, r) -> ir.NewBinaryExpr(xpos, ir.OAND, l, r)
ir.NodAt(xpos, ir.OANDNOT, l, r) -> ir.NewBinaryExpr(xpos, ir.OANDNOT, l, r)
ir.NodAt(xpos, ir.ODIV, l, r) -> ir.NewBinaryExpr(xpos, ir.ODIV, l, r)
ir.NodAt(xpos, ir.OEQ, l, r) -> ir.NewBinaryExpr(xpos, ir.OEQ, l, r)
ir.NodAt(xpos, ir.OGE, l, r) -> ir.NewBinaryExpr(xpos, ir.OGE, l, r)
ir.NodAt(xpos, ir.OGT, l, r) -> ir.NewBinaryExpr(xpos, ir.OGT, l, r)
ir.NodAt(xpos, ir.OLE, l, r) -> ir.NewBinaryExpr(xpos, ir.OLE, l, r)
ir.NodAt(xpos, ir.OLSH, l, r) -> ir.NewBinaryExpr(xpos, ir.OLSH, l, r)
ir.NodAt(xpos, ir.OLT, l, r) -> ir.NewBinaryExpr(xpos, ir.OLT, l, r)
ir.NodAt(xpos, ir.OMOD, l, r) -> ir.NewBinaryExpr(xpos, ir.OMOD, l, r)
ir.NodAt(xpos, ir.OMUL, l, r) -> ir.NewBinaryExpr(xpos, ir.OMUL, l, r)
ir.NodAt(xpos, ir.ONE, l, r) -> ir.NewBinaryExpr(xpos, ir.ONE, l, r)
ir.NodAt(xpos, ir.OOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OOR, l, r)
ir.NodAt(xpos, ir.ORSH, l, r) -> ir.NewBinaryExpr(xpos, ir.ORSH, l, r)
ir.NodAt(xpos, ir.OSUB, l, r) -> ir.NewBinaryExpr(xpos, ir.OSUB, l, r)
ir.NodAt(xpos, ir.OXOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OXOR, l, r)
ir.NodAt(xpos, ir.OCOPY, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOPY, l, r)
ir.NodAt(xpos, ir.OCOMPLEX, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOMPLEX, l, r)
ir.NodAt(xpos, ir.OEFACE, l, r) -> ir.NewBinaryExpr(xpos, ir.OEFACE, l, r)
ir.NodAt(xpos, ir.OADDR, l, nil) -> ir.NewAddrExpr(xpos, l)
ir.NodAt(xpos, ir.OADDSTR, nil, nil) -> ir.NewAddStringExpr(xpos, nil)
ir.NodAt(xpos, ir.OANDAND, l, r) -> ir.NewLogicalExpr(xpos, ir.OANDAND, l, r)
ir.NodAt(xpos, ir.OOROR, l, r) -> ir.NewLogicalExpr(xpos, ir.OOROR, l, r)
ir.NodAt(xpos, ir.OARRAYLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, nil, nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, nil, nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, nil, nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, nil, nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, nil, nil)
ir.NodAt(xpos, ir.OARRAYLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OAS2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2, nil, nil)
ir.NodAt(xpos, ir.OAS2DOTTYPE, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2DOTTYPE, nil, nil)
ir.NodAt(xpos, ir.OAS2FUNC, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2FUNC, nil, nil)
ir.NodAt(xpos, ir.OAS2MAPR, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2MAPR, nil, nil)
ir.NodAt(xpos, ir.OAS2RECV, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2RECV, nil, nil)
ir.NodAt(xpos, ir.OSELRECV2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OSELRECV2, nil, nil)
ir.NodAt(xpos, ir.OASOP, l, r) -> ir.NewAssignOpStmt(xpos, ir.OXXX, l, r)
ir.NodAt(xpos, ir.OBITNOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.OBITNOT, l)
ir.NodAt(xpos, ir.ONEG, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEG, l)
ir.NodAt(xpos, ir.ONOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONOT, l)
ir.NodAt(xpos, ir.OPLUS, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPLUS, l)
ir.NodAt(xpos, ir.ORECV, l, nil) -> ir.NewUnaryExpr(xpos, ir.ORECV, l)
ir.NodAt(xpos, ir.OALIGNOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OALIGNOF, l)
ir.NodAt(xpos, ir.OCAP, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCAP, l)
ir.NodAt(xpos, ir.OCLOSE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCLOSE, l)
ir.NodAt(xpos, ir.OIMAG, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIMAG, l)
ir.NodAt(xpos, ir.OLEN, l, nil) -> ir.NewUnaryExpr(xpos, ir.OLEN, l)
ir.NodAt(xpos, ir.ONEW, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEW, l)
ir.NodAt(xpos, ir.ONEWOBJ, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEWOBJ, l)
ir.NodAt(xpos, ir.OOFFSETOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OOFFSETOF, l)
ir.NodAt(xpos, ir.OPANIC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPANIC, l)
ir.NodAt(xpos, ir.OREAL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OREAL, l)
ir.NodAt(xpos, ir.OSIZEOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSIZEOF, l)
ir.NodAt(xpos, ir.OCHECKNIL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCHECKNIL, l)
ir.NodAt(xpos, ir.OCFUNC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCFUNC, l)
ir.NodAt(xpos, ir.OIDATA, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIDATA, l)
ir.NodAt(xpos, ir.OITAB, l, nil) -> ir.NewUnaryExpr(xpos, ir.OITAB, l)
ir.NodAt(xpos, ir.OSPTR, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSPTR, l)
ir.NodAt(xpos, ir.OVARDEF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARDEF, l)
ir.NodAt(xpos, ir.OVARKILL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARKILL, l)
ir.NodAt(xpos, ir.OVARLIVE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARLIVE, l)
ir.NodAt(xpos, ir.OBLOCK, nil, nil) -> ir.NewBlockStmt(xpos, nil)
ir.NodAt(xpos, ir.OBREAK, nil, nil) -> ir.NewBranchStmt(xpos, ir.OBREAK, nil)
ir.NodAt(xpos, ir.OCONTINUE, nil, nil) -> ir.NewBranchStmt(xpos, ir.OCONTINUE, nil)
ir.NodAt(xpos, ir.OFALL, nil, nil) -> ir.NewBranchStmt(xpos, ir.OFALL, nil)
ir.NodAt(xpos, ir.OGOTO, nil, nil) -> ir.NewBranchStmt(xpos, ir.OGOTO, nil)
ir.NodAt(xpos, ir.ORETJMP, nil, nil) -> ir.NewBranchStmt(xpos, ir.ORETJMP, nil)
ir.NodAt(xpos, ir.OCALL, l, nil) -> ir.NewCallExpr(xpos, ir.OCALL, l, nil)
ir.NodAt(xpos, ir.OCALLFUNC, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLFUNC, l, nil)
ir.NodAt(xpos, ir.OCALLINTER, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLINTER, l, nil)
ir.NodAt(xpos, ir.OCALLMETH, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLMETH, l, nil)
ir.NodAt(xpos, ir.OAPPEND, l, nil) -> ir.NewCallExpr(xpos, ir.OAPPEND, l, nil)
ir.NodAt(xpos, ir.ODELETE, l, nil) -> ir.NewCallExpr(xpos, ir.ODELETE, l, nil)
ir.NodAt(xpos, ir.OGETG, l, nil) -> ir.NewCallExpr(xpos, ir.OGETG, l, nil)
ir.NodAt(xpos, ir.OMAKE, l, nil) -> ir.NewCallExpr(xpos, ir.OMAKE, l, nil)
ir.NodAt(xpos, ir.OPRINT, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINT, l, nil)
ir.NodAt(xpos, ir.OPRINTN, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINTN, l, nil)
ir.NodAt(xpos, ir.ORECOVER, l, nil) -> ir.NewCallExpr(xpos, ir.ORECOVER, l, nil)
ir.NodAt(xpos, ir.OCASE, nil, nil) -> ir.NewCaseStmt(xpos, nil, nil)
ir.NodAt(xpos, ir.OCONV, l, nil) -> ir.NewConvExpr(xpos, ir.OCONV, nil, l)
ir.NodAt(xpos, ir.OCONVIFACE, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVIFACE, nil, l)
ir.NodAt(xpos, ir.OCONVNOP, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVNOP, nil, l)
ir.NodAt(xpos, ir.ORUNESTR, l, nil) -> ir.NewConvExpr(xpos, ir.ORUNESTR, nil, l)
ir.NodAt(xpos, ir.ODCL, l, nil) -> ir.NewDecl(xpos, ir.ODCL, l)
ir.NodAt(xpos, ir.ODCLCONST, l, nil) -> ir.NewDecl(xpos, ir.ODCLCONST, l)
ir.NodAt(xpos, ir.ODCLTYPE, l, nil) -> ir.NewDecl(xpos, ir.ODCLTYPE, l)
ir.NodAt(xpos, ir.ODCLFUNC, nil, nil) -> ir.NewFunc(xpos)
ir.NodAt(xpos, ir.ODEFER, l, nil) -> ir.NewGoDeferStmt(xpos, ir.ODEFER, l)
ir.NodAt(xpos, ir.OGO, l, nil) -> ir.NewGoDeferStmt(xpos, ir.OGO, l)
ir.NodAt(xpos, ir.ODEREF, l, nil) -> ir.NewStarExpr(xpos, l)
ir.NodAt(xpos, ir.ODOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, nil)
ir.NodAt(xpos, ir.ODOTPTR, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, nil)
ir.NodAt(xpos, ir.ODOTMETH, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTMETH, l, nil)
ir.NodAt(xpos, ir.ODOTINTER, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTINTER, l, nil)
ir.NodAt(xpos, ir.OXDOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, nil) -> ir.NewTypeAssertExpr(xpos, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, r) -> ir.NewTypeAssertExpr(xpos, l, r.(ir.Ntype))
ir.NodAt(xpos, ir.OFOR, l, r) -> ir.NewForStmt(xpos, nil, l, r, nil)
ir.NodAt(xpos, ir.OINDEX, l, r) -> ir.NewIndexExpr(xpos, l, r)
ir.NodAt(xpos, ir.OINLMARK, nil, nil) -> ir.NewInlineMarkStmt(xpos, types.BADWIDTH)
ir.NodAt(xpos, ir.OKEY, l, r) -> ir.NewKeyExpr(xpos, l, r)
ir.NodAt(xpos, ir.OLABEL, nil, nil) -> ir.NewLabelStmt(xpos, nil)
ir.NodAt(xpos, ir.OMAKECHAN, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKECHAN, l, r)
ir.NodAt(xpos, ir.OMAKEMAP, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKEMAP, l, r)
ir.NodAt(xpos, ir.OMAKESLICE, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICE, l, r)
ir.NodAt(xpos, ir.OMAKESLICECOPY, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICECOPY, l, r)
ir.NodAt(xpos, ir.ONIL, nil, nil) -> ir.NewNilExpr(xpos)
ir.NodAt(xpos, ir.OPACK, nil, nil) -> ir.NewPkgName(xpos, nil, nil)
ir.NodAt(xpos, ir.OPAREN, l, nil) -> ir.NewParenExpr(xpos, l)
ir.NodAt(xpos, ir.ORANGE, nil, r) -> ir.NewRangeStmt(xpos, nil, r, nil)
ir.NodAt(xpos, ir.ORESULT, nil, nil) -> ir.NewResultExpr(xpos, nil, types.BADWIDTH)
ir.NodAt(xpos, ir.ORETURN, nil, nil) -> ir.NewReturnStmt(xpos, nil)
ir.NodAt(xpos, ir.OSELECT, nil, nil) -> ir.NewSelectStmt(xpos, nil)
ir.NodAt(xpos, ir.OSEND, l, r) -> ir.NewSendStmt(xpos, l, r)
ir.NodAt(xpos, ir.OSLICE, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE, l)
ir.NodAt(xpos, ir.OSLICEARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICEARR, l)
ir.NodAt(xpos, ir.OSLICESTR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICESTR, l)
ir.NodAt(xpos, ir.OSLICE3, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3, l)
ir.NodAt(xpos, ir.OSLICE3ARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3ARR, l)
ir.NodAt(xpos, ir.OSLICEHEADER, l, nil) -> ir.NewSliceHeaderExpr(xpos, nil, l, nil, nil)
ir.NodAt(xpos, ir.OSWITCH, l, nil) -> ir.NewSwitchStmt(xpos, l, nil)
ir.NodAt(xpos, ir.OINLCALL, nil, nil) -> ir.NewInlinedCallExpr(xpos, nil, nil)
}
rm noder.nod noder.nodSym nodSym nodlSym ir.NodAt ir.Nod
'
Change-Id: Ibf1eb708de8463ae74ccc47d7966cc263a18295e
Reviewed-on: https://go-review.googlesource.com/c/go/+/277933
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:55:29 -05:00
|
|
|
o.append(ir.NewAssignStmt(base.Pos, v, n))
|
2018-03-04 17:17:55 -08:00
|
|
|
return v
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// cheapExpr returns a cheap version of n.
|
2015-02-13 14:40:36 -05:00
|
|
|
// The definition of cheap is that n is a variable or constant.
|
2018-03-04 17:17:55 -08:00
|
|
|
// If not, cheapExpr allocates a new tmp, emits tmp = n,
|
2015-02-13 14:40:36 -05:00
|
|
|
// and then returns tmp.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) cheapExpr(n ir.Node) ir.Node {
|
cmd/internal/gc: optimize slice + write barrier
The code generated for a slice x[i:j] or x[i:j:k] computes the entire
new slice (base, len, cap) and then uses it as the evaluation of the
slice expression.
If the slice is part of an update x = x[i:j] or x = x[i:j:k], there are
opportunities to avoid computing some of these fields.
For x = x[0:i], we know that only the len is changing;
base can be ignored completely, and cap can be left unmodified.
For x = x[0:i:j], we know that only len and cap are changing;
base can be ignored completely.
For x = x[i:i], we know that the resulting cap is zero, and we don't
adjust the base during a slice producing a zero-cap result,
so again base can be ignored completely.
No write to base, no write barrier.
The old slice code was trying to work at a Go syntax level, mainly
because that was how you wrote code just once instead of once
per architecture. Now the compiler is factored a bit better and we
can implement slice during code generation but still have one copy
of the code. So the new code is working at that lower level.
(It must, to update only parts of the result.)
This CL by itself:
name old mean new mean delta
BinaryTree17 5.81s × (0.98,1.03) 5.71s × (0.96,1.05) ~ (p=0.101)
Fannkuch11 4.35s × (1.00,1.00) 4.39s × (1.00,1.00) +0.79% (p=0.000)
FmtFprintfEmpty 86.0ns × (0.94,1.11) 82.6ns × (0.98,1.04) -3.86% (p=0.048)
FmtFprintfString 276ns × (0.98,1.04) 273ns × (0.98,1.02) ~ (p=0.235)
FmtFprintfInt 274ns × (0.98,1.06) 270ns × (0.99,1.01) ~ (p=0.119)
FmtFprintfIntInt 506ns × (0.99,1.01) 475ns × (0.99,1.01) -6.02% (p=0.000)
FmtFprintfPrefixedInt 391ns × (0.99,1.01) 393ns × (1.00,1.01) ~ (p=0.139)
FmtFprintfFloat 566ns × (0.99,1.01) 574ns × (1.00,1.01) +1.33% (p=0.001)
FmtManyArgs 1.91µs × (0.99,1.01) 1.87µs × (0.99,1.02) -1.83% (p=0.000)
GobDecode 15.3ms × (0.99,1.02) 15.0ms × (0.98,1.05) -1.84% (p=0.042)
GobEncode 11.5ms × (0.97,1.03) 11.4ms × (0.99,1.03) ~ (p=0.152)
Gzip 645ms × (0.99,1.01) 647ms × (0.99,1.01) ~ (p=0.265)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.90% (p=0.000)
HTTPClientServer 90.5µs × (0.97,1.04) 88.5µs × (0.99,1.03) -2.27% (p=0.014)
JSONEncode 32.0ms × (0.98,1.03) 29.6ms × (0.98,1.01) -7.51% (p=0.000)
JSONDecode 114ms × (0.99,1.01) 104ms × (1.00,1.01) -8.60% (p=0.000)
Mandelbrot200 6.04ms × (1.00,1.01) 6.02ms × (1.00,1.00) ~ (p=0.057)
GoParse 6.47ms × (0.97,1.05) 6.37ms × (0.97,1.04) ~ (p=0.105)
RegexpMatchEasy0_32 171ns × (0.93,1.07) 152ns × (0.99,1.01) -11.09% (p=0.000)
RegexpMatchEasy0_1K 550ns × (0.98,1.01) 530ns × (1.00,1.00) -3.78% (p=0.000)
RegexpMatchEasy1_32 135ns × (0.99,1.02) 134ns × (0.99,1.01) -1.33% (p=0.002)
RegexpMatchEasy1_1K 879ns × (1.00,1.01) 865ns × (1.00,1.00) -1.58% (p=0.000)
RegexpMatchMedium_32 243ns × (1.00,1.00) 233ns × (1.00,1.00) -4.30% (p=0.000)
RegexpMatchMedium_1K 70.3µs × (1.00,1.00) 69.5µs × (1.00,1.00) -1.13% (p=0.000)
RegexpMatchHard_32 3.82µs × (1.00,1.01) 3.74µs × (1.00,1.00) -1.95% (p=0.000)
RegexpMatchHard_1K 117µs × (1.00,1.00) 115µs × (1.00,1.00) -1.69% (p=0.000)
Revcomp 917ms × (0.97,1.04) 920ms × (0.97,1.04) ~ (p=0.786)
Template 114ms × (0.99,1.01) 117ms × (0.99,1.01) +2.58% (p=0.000)
TimeParse 622ns × (0.99,1.01) 615ns × (0.99,1.00) -1.06% (p=0.000)
TimeFormat 665ns × (0.99,1.01) 654ns × (0.99,1.00) -1.70% (p=0.000)
This CL and previous CL (append) combined:
name old mean new mean delta
BinaryTree17 5.68s × (0.97,1.04) 5.71s × (0.96,1.05) ~ (p=0.638)
Fannkuch11 4.41s × (0.98,1.03) 4.39s × (1.00,1.00) ~ (p=0.474)
FmtFprintfEmpty 92.7ns × (0.91,1.16) 82.6ns × (0.98,1.04) -10.89% (p=0.004)
FmtFprintfString 281ns × (0.96,1.08) 273ns × (0.98,1.02) ~ (p=0.078)
FmtFprintfInt 288ns × (0.97,1.06) 270ns × (0.99,1.01) -6.37% (p=0.000)
FmtFprintfIntInt 493ns × (0.97,1.04) 475ns × (0.99,1.01) -3.53% (p=0.002)
FmtFprintfPrefixedInt 423ns × (0.97,1.04) 393ns × (1.00,1.01) -7.07% (p=0.000)
FmtFprintfFloat 598ns × (0.99,1.01) 574ns × (1.00,1.01) -4.02% (p=0.000)
FmtManyArgs 1.89µs × (0.98,1.05) 1.87µs × (0.99,1.02) ~ (p=0.305)
GobDecode 14.8ms × (0.98,1.03) 15.0ms × (0.98,1.05) ~ (p=0.237)
GobEncode 12.3ms × (0.98,1.01) 11.4ms × (0.99,1.03) -6.95% (p=0.000)
Gzip 656ms × (0.99,1.05) 647ms × (0.99,1.01) ~ (p=0.101)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.58% (p=0.001)
HTTPClientServer 91.2µs × (0.97,1.04) 88.5µs × (0.99,1.03) -3.02% (p=0.003)
JSONEncode 32.6ms × (0.97,1.08) 29.6ms × (0.98,1.01) -9.10% (p=0.000)
JSONDecode 114ms × (0.97,1.05) 104ms × (1.00,1.01) -8.74% (p=0.000)
Mandelbrot200 6.11ms × (0.98,1.04) 6.02ms × (1.00,1.00) ~ (p=0.090)
GoParse 6.66ms × (0.97,1.04) 6.37ms × (0.97,1.04) -4.41% (p=0.000)
RegexpMatchEasy0_32 159ns × (0.99,1.00) 152ns × (0.99,1.01) -4.69% (p=0.000)
RegexpMatchEasy0_1K 538ns × (1.00,1.01) 530ns × (1.00,1.00) -1.57% (p=0.000)
RegexpMatchEasy1_32 138ns × (1.00,1.00) 134ns × (0.99,1.01) -2.91% (p=0.000)
RegexpMatchEasy1_1K 869ns × (0.99,1.01) 865ns × (1.00,1.00) -0.51% (p=0.012)
RegexpMatchMedium_32 252ns × (0.99,1.01) 233ns × (1.00,1.00) -7.85% (p=0.000)
RegexpMatchMedium_1K 72.7µs × (1.00,1.00) 69.5µs × (1.00,1.00) -4.43% (p=0.000)
RegexpMatchHard_32 3.85µs × (1.00,1.00) 3.74µs × (1.00,1.00) -2.74% (p=0.000)
RegexpMatchHard_1K 118µs × (1.00,1.00) 115µs × (1.00,1.00) -2.24% (p=0.000)
Revcomp 920ms × (0.97,1.07) 920ms × (0.97,1.04) ~ (p=0.998)
Template 129ms × (0.98,1.03) 117ms × (0.99,1.01) -9.79% (p=0.000)
TimeParse 619ns × (0.99,1.01) 615ns × (0.99,1.00) -0.57% (p=0.011)
TimeFormat 661ns × (0.98,1.04) 654ns × (0.99,1.00) ~ (p=0.223)
Change-Id: If054d81ab2c71d8d62cf54b5b1fac2af66b387fc
Reviewed-on: https://go-review.googlesource.com/9813
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-05-06 12:35:53 -04:00
|
|
|
if n == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2018-03-04 17:17:55 -08:00
|
|
|
|
2020-11-22 09:59:15 -05:00
|
|
|
switch n.Op() {
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ONAME, ir.OLITERAL, ir.ONIL:
|
2015-02-13 14:40:36 -05:00
|
|
|
return n
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OLEN, ir.OCAP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.UnaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
l := o.cheapExpr(n.X)
|
|
|
|
|
if l == n.X {
|
cmd/internal/gc: optimize slice + write barrier
The code generated for a slice x[i:j] or x[i:j:k] computes the entire
new slice (base, len, cap) and then uses it as the evaluation of the
slice expression.
If the slice is part of an update x = x[i:j] or x = x[i:j:k], there are
opportunities to avoid computing some of these fields.
For x = x[0:i], we know that only the len is changing;
base can be ignored completely, and cap can be left unmodified.
For x = x[0:i:j], we know that only len and cap are changing;
base can be ignored completely.
For x = x[i:i], we know that the resulting cap is zero, and we don't
adjust the base during a slice producing a zero-cap result,
so again base can be ignored completely.
No write to base, no write barrier.
The old slice code was trying to work at a Go syntax level, mainly
because that was how you wrote code just once instead of once
per architecture. Now the compiler is factored a bit better and we
can implement slice during code generation but still have one copy
of the code. So the new code is working at that lower level.
(It must, to update only parts of the result.)
This CL by itself:
name old mean new mean delta
BinaryTree17 5.81s × (0.98,1.03) 5.71s × (0.96,1.05) ~ (p=0.101)
Fannkuch11 4.35s × (1.00,1.00) 4.39s × (1.00,1.00) +0.79% (p=0.000)
FmtFprintfEmpty 86.0ns × (0.94,1.11) 82.6ns × (0.98,1.04) -3.86% (p=0.048)
FmtFprintfString 276ns × (0.98,1.04) 273ns × (0.98,1.02) ~ (p=0.235)
FmtFprintfInt 274ns × (0.98,1.06) 270ns × (0.99,1.01) ~ (p=0.119)
FmtFprintfIntInt 506ns × (0.99,1.01) 475ns × (0.99,1.01) -6.02% (p=0.000)
FmtFprintfPrefixedInt 391ns × (0.99,1.01) 393ns × (1.00,1.01) ~ (p=0.139)
FmtFprintfFloat 566ns × (0.99,1.01) 574ns × (1.00,1.01) +1.33% (p=0.001)
FmtManyArgs 1.91µs × (0.99,1.01) 1.87µs × (0.99,1.02) -1.83% (p=0.000)
GobDecode 15.3ms × (0.99,1.02) 15.0ms × (0.98,1.05) -1.84% (p=0.042)
GobEncode 11.5ms × (0.97,1.03) 11.4ms × (0.99,1.03) ~ (p=0.152)
Gzip 645ms × (0.99,1.01) 647ms × (0.99,1.01) ~ (p=0.265)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.90% (p=0.000)
HTTPClientServer 90.5µs × (0.97,1.04) 88.5µs × (0.99,1.03) -2.27% (p=0.014)
JSONEncode 32.0ms × (0.98,1.03) 29.6ms × (0.98,1.01) -7.51% (p=0.000)
JSONDecode 114ms × (0.99,1.01) 104ms × (1.00,1.01) -8.60% (p=0.000)
Mandelbrot200 6.04ms × (1.00,1.01) 6.02ms × (1.00,1.00) ~ (p=0.057)
GoParse 6.47ms × (0.97,1.05) 6.37ms × (0.97,1.04) ~ (p=0.105)
RegexpMatchEasy0_32 171ns × (0.93,1.07) 152ns × (0.99,1.01) -11.09% (p=0.000)
RegexpMatchEasy0_1K 550ns × (0.98,1.01) 530ns × (1.00,1.00) -3.78% (p=0.000)
RegexpMatchEasy1_32 135ns × (0.99,1.02) 134ns × (0.99,1.01) -1.33% (p=0.002)
RegexpMatchEasy1_1K 879ns × (1.00,1.01) 865ns × (1.00,1.00) -1.58% (p=0.000)
RegexpMatchMedium_32 243ns × (1.00,1.00) 233ns × (1.00,1.00) -4.30% (p=0.000)
RegexpMatchMedium_1K 70.3µs × (1.00,1.00) 69.5µs × (1.00,1.00) -1.13% (p=0.000)
RegexpMatchHard_32 3.82µs × (1.00,1.01) 3.74µs × (1.00,1.00) -1.95% (p=0.000)
RegexpMatchHard_1K 117µs × (1.00,1.00) 115µs × (1.00,1.00) -1.69% (p=0.000)
Revcomp 917ms × (0.97,1.04) 920ms × (0.97,1.04) ~ (p=0.786)
Template 114ms × (0.99,1.01) 117ms × (0.99,1.01) +2.58% (p=0.000)
TimeParse 622ns × (0.99,1.01) 615ns × (0.99,1.00) -1.06% (p=0.000)
TimeFormat 665ns × (0.99,1.01) 654ns × (0.99,1.00) -1.70% (p=0.000)
This CL and previous CL (append) combined:
name old mean new mean delta
BinaryTree17 5.68s × (0.97,1.04) 5.71s × (0.96,1.05) ~ (p=0.638)
Fannkuch11 4.41s × (0.98,1.03) 4.39s × (1.00,1.00) ~ (p=0.474)
FmtFprintfEmpty 92.7ns × (0.91,1.16) 82.6ns × (0.98,1.04) -10.89% (p=0.004)
FmtFprintfString 281ns × (0.96,1.08) 273ns × (0.98,1.02) ~ (p=0.078)
FmtFprintfInt 288ns × (0.97,1.06) 270ns × (0.99,1.01) -6.37% (p=0.000)
FmtFprintfIntInt 493ns × (0.97,1.04) 475ns × (0.99,1.01) -3.53% (p=0.002)
FmtFprintfPrefixedInt 423ns × (0.97,1.04) 393ns × (1.00,1.01) -7.07% (p=0.000)
FmtFprintfFloat 598ns × (0.99,1.01) 574ns × (1.00,1.01) -4.02% (p=0.000)
FmtManyArgs 1.89µs × (0.98,1.05) 1.87µs × (0.99,1.02) ~ (p=0.305)
GobDecode 14.8ms × (0.98,1.03) 15.0ms × (0.98,1.05) ~ (p=0.237)
GobEncode 12.3ms × (0.98,1.01) 11.4ms × (0.99,1.03) -6.95% (p=0.000)
Gzip 656ms × (0.99,1.05) 647ms × (0.99,1.01) ~ (p=0.101)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.58% (p=0.001)
HTTPClientServer 91.2µs × (0.97,1.04) 88.5µs × (0.99,1.03) -3.02% (p=0.003)
JSONEncode 32.6ms × (0.97,1.08) 29.6ms × (0.98,1.01) -9.10% (p=0.000)
JSONDecode 114ms × (0.97,1.05) 104ms × (1.00,1.01) -8.74% (p=0.000)
Mandelbrot200 6.11ms × (0.98,1.04) 6.02ms × (1.00,1.00) ~ (p=0.090)
GoParse 6.66ms × (0.97,1.04) 6.37ms × (0.97,1.04) -4.41% (p=0.000)
RegexpMatchEasy0_32 159ns × (0.99,1.00) 152ns × (0.99,1.01) -4.69% (p=0.000)
RegexpMatchEasy0_1K 538ns × (1.00,1.01) 530ns × (1.00,1.00) -1.57% (p=0.000)
RegexpMatchEasy1_32 138ns × (1.00,1.00) 134ns × (0.99,1.01) -2.91% (p=0.000)
RegexpMatchEasy1_1K 869ns × (0.99,1.01) 865ns × (1.00,1.00) -0.51% (p=0.012)
RegexpMatchMedium_32 252ns × (0.99,1.01) 233ns × (1.00,1.00) -7.85% (p=0.000)
RegexpMatchMedium_1K 72.7µs × (1.00,1.00) 69.5µs × (1.00,1.00) -4.43% (p=0.000)
RegexpMatchHard_32 3.85µs × (1.00,1.00) 3.74µs × (1.00,1.00) -2.74% (p=0.000)
RegexpMatchHard_1K 118µs × (1.00,1.00) 115µs × (1.00,1.00) -2.24% (p=0.000)
Revcomp 920ms × (0.97,1.07) 920ms × (0.97,1.04) ~ (p=0.998)
Template 129ms × (0.98,1.03) 117ms × (0.99,1.01) -9.79% (p=0.000)
TimeParse 619ns × (0.99,1.01) 615ns × (0.99,1.00) -0.57% (p=0.011)
TimeFormat 661ns × (0.98,1.04) 654ns × (0.99,1.00) ~ (p=0.223)
Change-Id: If054d81ab2c71d8d62cf54b5b1fac2af66b387fc
Reviewed-on: https://go-review.googlesource.com/9813
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-05-06 12:35:53 -04:00
|
|
|
return n
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
a := ir.SepCopy(n).(*ir.UnaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
a.X = l
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
return typecheck.Expr(a)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-11-29 11:16:20 -05:00
|
|
|
return o.copyExpr(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// safeExpr returns a safe version of n.
|
2015-02-13 14:40:36 -05:00
|
|
|
// The definition of safe is that n can appear multiple times
|
|
|
|
|
// without violating the semantics of the original program,
|
|
|
|
|
// and that assigning to the safe version has the same effect
|
|
|
|
|
// as assigning to the original n.
|
|
|
|
|
//
|
|
|
|
|
// The intended use is to apply to x when rewriting x += y into x = x + y.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) safeExpr(n ir.Node) ir.Node {
|
2020-11-22 09:59:15 -05:00
|
|
|
switch n.Op() {
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ONAME, ir.OLITERAL, ir.ONIL:
|
2015-02-13 14:40:36 -05:00
|
|
|
return n
|
|
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
case ir.OLEN, ir.OCAP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.UnaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
l := o.safeExpr(n.X)
|
|
|
|
|
if l == n.X {
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
a := ir.SepCopy(n).(*ir.UnaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
a.X = l
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
return typecheck.Expr(a)
|
2020-12-10 18:45:35 -05:00
|
|
|
|
|
|
|
|
case ir.ODOT:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.SelectorExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
l := o.safeExpr(n.X)
|
|
|
|
|
if l == n.X {
|
2015-02-13 14:40:36 -05:00
|
|
|
return n
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
a := ir.SepCopy(n).(*ir.SelectorExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
a.X = l
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
return typecheck.Expr(a)
|
2020-12-10 18:45:35 -05:00
|
|
|
|
|
|
|
|
case ir.ODOTPTR:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.SelectorExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
l := o.cheapExpr(n.X)
|
|
|
|
|
if l == n.X {
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
a := ir.SepCopy(n).(*ir.SelectorExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
a.X = l
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
return typecheck.Expr(a)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
case ir.ODEREF:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.StarExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
l := o.cheapExpr(n.X)
|
|
|
|
|
if l == n.X {
|
2015-02-13 14:40:36 -05:00
|
|
|
return n
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
a := ir.SepCopy(n).(*ir.StarExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
a.X = l
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
return typecheck.Expr(a)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OINDEX, ir.OINDEXMAP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.IndexExpr)
|
[dev.regabi] cmd/compile: replace *Node type with an interface Node [generated]
The plan is to introduce a Node interface that replaces the old *Node pointer-to-struct.
The previous CL defined an interface INode modeling a *Node.
This CL:
- Changes all references outside internal/ir to use INode,
along with many references inside internal/ir as well.
- Renames Node to node.
- Renames INode to Node
So now ir.Node is an interface implemented by *ir.node, which is otherwise inaccessible,
and the code outside package ir is now (clearly) using only the interface.
The usual rule is never to redefine an existing name with a new meaning,
so that old code that hasn't been updated gets a "unknown name" error
instead of more mysterious errors or silent misbehavior. That rule would
caution against replacing Node-the-struct with Node-the-interface,
as in this CL, because code that says *Node would now be using a pointer
to an interface. But this CL is being landed at the same time as another that
moves Node from gc to ir. So the net effect is to replace *gc.Node with ir.Node,
which does follow the rule: any lingering references to gc.Node will be told
it's gone, not silently start using pointers to interfaces. So the rule is followed
by the CL sequence, just not this specific CL.
Overall, the loss of inlining caused by using interfaces cuts the compiler speed
by about 6%, a not insignificant amount. However, as we convert the representation
to concrete structs that are not the giant Node over the next weeks, that speed
should come back as more of the compiler starts operating directly on concrete types
and the memory taken up by the graph of Nodes drops due to the more precise
structs. Honestly, I was expecting worse.
% benchstat bench.old bench.new
name old time/op new time/op delta
Template 168ms ± 4% 182ms ± 2% +8.34% (p=0.000 n=9+9)
Unicode 72.2ms ±10% 82.5ms ± 6% +14.38% (p=0.000 n=9+9)
GoTypes 563ms ± 8% 598ms ± 2% +6.14% (p=0.006 n=9+9)
Compiler 2.89s ± 4% 3.04s ± 2% +5.37% (p=0.000 n=10+9)
SSA 6.45s ± 4% 7.25s ± 5% +12.41% (p=0.000 n=9+10)
Flate 105ms ± 2% 115ms ± 1% +9.66% (p=0.000 n=10+8)
GoParser 144ms ±10% 152ms ± 2% +5.79% (p=0.011 n=9+8)
Reflect 345ms ± 9% 370ms ± 4% +7.28% (p=0.001 n=10+9)
Tar 149ms ± 9% 161ms ± 5% +8.05% (p=0.001 n=10+9)
XML 190ms ± 3% 209ms ± 2% +9.54% (p=0.000 n=9+8)
LinkCompiler 327ms ± 2% 325ms ± 2% ~ (p=0.382 n=8+8)
ExternalLinkCompiler 1.77s ± 4% 1.73s ± 6% ~ (p=0.113 n=9+10)
LinkWithoutDebugCompiler 214ms ± 4% 211ms ± 2% ~ (p=0.360 n=10+8)
StdCmd 14.8s ± 3% 15.9s ± 1% +6.98% (p=0.000 n=10+9)
[Geo mean] 480ms 510ms +6.31%
name old user-time/op new user-time/op delta
Template 223ms ± 3% 237ms ± 3% +6.16% (p=0.000 n=9+10)
Unicode 103ms ± 6% 113ms ± 3% +9.53% (p=0.000 n=9+9)
GoTypes 758ms ± 8% 800ms ± 2% +5.55% (p=0.003 n=10+9)
Compiler 3.95s ± 2% 4.12s ± 2% +4.34% (p=0.000 n=10+9)
SSA 9.43s ± 1% 9.74s ± 4% +3.25% (p=0.000 n=8+10)
Flate 132ms ± 2% 141ms ± 2% +6.89% (p=0.000 n=9+9)
GoParser 177ms ± 9% 183ms ± 4% ~ (p=0.050 n=9+9)
Reflect 467ms ±10% 495ms ± 7% +6.17% (p=0.029 n=10+10)
Tar 183ms ± 9% 197ms ± 5% +7.92% (p=0.001 n=10+10)
XML 249ms ± 5% 268ms ± 4% +7.82% (p=0.000 n=10+9)
LinkCompiler 544ms ± 5% 544ms ± 6% ~ (p=0.863 n=9+9)
ExternalLinkCompiler 1.79s ± 4% 1.75s ± 6% ~ (p=0.075 n=10+10)
LinkWithoutDebugCompiler 248ms ± 6% 246ms ± 2% ~ (p=0.965 n=10+8)
[Geo mean] 483ms 504ms +4.41%
[git-generate]
cd src/cmd/compile/internal/ir
: # We need to do the conversion in multiple steps, so we introduce
: # a temporary type alias that will start out meaning the pointer-to-struct
: # and then change to mean the interface.
rf '
mv Node OldNode
add node.go \
type Node = *OldNode
'
: # It should work to do this ex in ir, but it misses test files, due to a bug in rf.
: # Run the command in gc to handle gc's tests, and then again in ssa for ssa's tests.
cd ../gc
rf '
ex . ../arm ../riscv64 ../arm64 ../mips64 ../ppc64 ../mips ../wasm {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
cd ../ssa
rf '
ex {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
: # Back in ir, finish conversion clumsily with sed,
: # because type checking and circular aliases do not mix.
cd ../ir
sed -i '' '
/type Node = \*OldNode/d
s/\*OldNode/Node/g
s/^func (n Node)/func (n *OldNode)/
s/OldNode/node/g
s/type INode interface/type Node interface/
s/var _ INode = (Node)(nil)/var _ Node = (*node)(nil)/
' *.go
gofmt -w *.go
sed -i '' '
s/{Func{}, 136, 248}/{Func{}, 152, 280}/
s/{Name{}, 32, 56}/{Name{}, 44, 80}/
s/{Param{}, 24, 48}/{Param{}, 44, 88}/
s/{node{}, 76, 128}/{node{}, 88, 152}/
' sizeof_test.go
cd ../ssa
sed -i '' '
s/{LocalSlot{}, 28, 40}/{LocalSlot{}, 32, 48}/
' sizeof_test.go
cd ../gc
sed -i '' 's/\*ir.Node/ir.Node/' mkbuiltin.go
cd ../../../..
go install std cmd
cd cmd/compile
go test -u || go test -u
Change-Id: I196bbe3b648e4701662e4a2bada40bf155e2a553
Reviewed-on: https://go-review.googlesource.com/c/go/+/272935
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-25 01:11:56 -05:00
|
|
|
var l ir.Node
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.X.Type().IsArray() {
|
|
|
|
|
l = o.safeExpr(n.X)
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
2020-12-23 00:02:08 -05:00
|
|
|
l = o.cheapExpr(n.X)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-23 00:02:08 -05:00
|
|
|
r := o.cheapExpr(n.Index)
|
|
|
|
|
if l == n.X && r == n.Index {
|
2015-02-13 14:40:36 -05:00
|
|
|
return n
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
a := ir.SepCopy(n).(*ir.IndexExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
a.X = l
|
|
|
|
|
a.Index = r
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
return typecheck.Expr(a)
|
2018-03-04 17:17:55 -08:00
|
|
|
|
2016-03-23 16:01:15 +11:00
|
|
|
default:
|
2020-11-22 09:59:15 -05:00
|
|
|
base.Fatalf("order.safeExpr %v", n.Op())
|
2016-03-23 16:01:15 +11:00
|
|
|
return nil // not reached
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-05 00:00:38 +07:00
|
|
|
// isaddrokay reports whether it is okay to pass n's address to runtime routines.
|
2015-02-13 14:40:36 -05:00
|
|
|
// Taking the address of a variable makes the liveness and optimization analyses
|
|
|
|
|
// lose track of where the variable's lifetime ends. To avoid hurting the analyses
|
|
|
|
|
// of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
|
|
|
|
|
// because we emit explicit VARKILL instructions marking the end of those
|
|
|
|
|
// temporaries' lifetimes.
|
[dev.regabi] cmd/compile: replace *Node type with an interface Node [generated]
The plan is to introduce a Node interface that replaces the old *Node pointer-to-struct.
The previous CL defined an interface INode modeling a *Node.
This CL:
- Changes all references outside internal/ir to use INode,
along with many references inside internal/ir as well.
- Renames Node to node.
- Renames INode to Node
So now ir.Node is an interface implemented by *ir.node, which is otherwise inaccessible,
and the code outside package ir is now (clearly) using only the interface.
The usual rule is never to redefine an existing name with a new meaning,
so that old code that hasn't been updated gets a "unknown name" error
instead of more mysterious errors or silent misbehavior. That rule would
caution against replacing Node-the-struct with Node-the-interface,
as in this CL, because code that says *Node would now be using a pointer
to an interface. But this CL is being landed at the same time as another that
moves Node from gc to ir. So the net effect is to replace *gc.Node with ir.Node,
which does follow the rule: any lingering references to gc.Node will be told
it's gone, not silently start using pointers to interfaces. So the rule is followed
by the CL sequence, just not this specific CL.
Overall, the loss of inlining caused by using interfaces cuts the compiler speed
by about 6%, a not insignificant amount. However, as we convert the representation
to concrete structs that are not the giant Node over the next weeks, that speed
should come back as more of the compiler starts operating directly on concrete types
and the memory taken up by the graph of Nodes drops due to the more precise
structs. Honestly, I was expecting worse.
% benchstat bench.old bench.new
name old time/op new time/op delta
Template 168ms ± 4% 182ms ± 2% +8.34% (p=0.000 n=9+9)
Unicode 72.2ms ±10% 82.5ms ± 6% +14.38% (p=0.000 n=9+9)
GoTypes 563ms ± 8% 598ms ± 2% +6.14% (p=0.006 n=9+9)
Compiler 2.89s ± 4% 3.04s ± 2% +5.37% (p=0.000 n=10+9)
SSA 6.45s ± 4% 7.25s ± 5% +12.41% (p=0.000 n=9+10)
Flate 105ms ± 2% 115ms ± 1% +9.66% (p=0.000 n=10+8)
GoParser 144ms ±10% 152ms ± 2% +5.79% (p=0.011 n=9+8)
Reflect 345ms ± 9% 370ms ± 4% +7.28% (p=0.001 n=10+9)
Tar 149ms ± 9% 161ms ± 5% +8.05% (p=0.001 n=10+9)
XML 190ms ± 3% 209ms ± 2% +9.54% (p=0.000 n=9+8)
LinkCompiler 327ms ± 2% 325ms ± 2% ~ (p=0.382 n=8+8)
ExternalLinkCompiler 1.77s ± 4% 1.73s ± 6% ~ (p=0.113 n=9+10)
LinkWithoutDebugCompiler 214ms ± 4% 211ms ± 2% ~ (p=0.360 n=10+8)
StdCmd 14.8s ± 3% 15.9s ± 1% +6.98% (p=0.000 n=10+9)
[Geo mean] 480ms 510ms +6.31%
name old user-time/op new user-time/op delta
Template 223ms ± 3% 237ms ± 3% +6.16% (p=0.000 n=9+10)
Unicode 103ms ± 6% 113ms ± 3% +9.53% (p=0.000 n=9+9)
GoTypes 758ms ± 8% 800ms ± 2% +5.55% (p=0.003 n=10+9)
Compiler 3.95s ± 2% 4.12s ± 2% +4.34% (p=0.000 n=10+9)
SSA 9.43s ± 1% 9.74s ± 4% +3.25% (p=0.000 n=8+10)
Flate 132ms ± 2% 141ms ± 2% +6.89% (p=0.000 n=9+9)
GoParser 177ms ± 9% 183ms ± 4% ~ (p=0.050 n=9+9)
Reflect 467ms ±10% 495ms ± 7% +6.17% (p=0.029 n=10+10)
Tar 183ms ± 9% 197ms ± 5% +7.92% (p=0.001 n=10+10)
XML 249ms ± 5% 268ms ± 4% +7.82% (p=0.000 n=10+9)
LinkCompiler 544ms ± 5% 544ms ± 6% ~ (p=0.863 n=9+9)
ExternalLinkCompiler 1.79s ± 4% 1.75s ± 6% ~ (p=0.075 n=10+10)
LinkWithoutDebugCompiler 248ms ± 6% 246ms ± 2% ~ (p=0.965 n=10+8)
[Geo mean] 483ms 504ms +4.41%
[git-generate]
cd src/cmd/compile/internal/ir
: # We need to do the conversion in multiple steps, so we introduce
: # a temporary type alias that will start out meaning the pointer-to-struct
: # and then change to mean the interface.
rf '
mv Node OldNode
add node.go \
type Node = *OldNode
'
: # It should work to do this ex in ir, but it misses test files, due to a bug in rf.
: # Run the command in gc to handle gc's tests, and then again in ssa for ssa's tests.
cd ../gc
rf '
ex . ../arm ../riscv64 ../arm64 ../mips64 ../ppc64 ../mips ../wasm {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
cd ../ssa
rf '
ex {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
: # Back in ir, finish conversion clumsily with sed,
: # because type checking and circular aliases do not mix.
cd ../ir
sed -i '' '
/type Node = \*OldNode/d
s/\*OldNode/Node/g
s/^func (n Node)/func (n *OldNode)/
s/OldNode/node/g
s/type INode interface/type Node interface/
s/var _ INode = (Node)(nil)/var _ Node = (*node)(nil)/
' *.go
gofmt -w *.go
sed -i '' '
s/{Func{}, 136, 248}/{Func{}, 152, 280}/
s/{Name{}, 32, 56}/{Name{}, 44, 80}/
s/{Param{}, 24, 48}/{Param{}, 44, 88}/
s/{node{}, 76, 128}/{node{}, 88, 152}/
' sizeof_test.go
cd ../ssa
sed -i '' '
s/{LocalSlot{}, 28, 40}/{LocalSlot{}, 32, 48}/
' sizeof_test.go
cd ../gc
sed -i '' 's/\*ir.Node/ir.Node/' mkbuiltin.go
cd ../../../..
go install std cmd
cd cmd/compile
go test -u || go test -u
Change-Id: I196bbe3b648e4701662e4a2bada40bf155e2a553
Reviewed-on: https://go-review.googlesource.com/c/go/+/272935
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-25 01:11:56 -05:00
|
|
|
func isaddrokay(n ir.Node) bool {
|
2021-01-03 20:14:00 -08:00
|
|
|
return ir.IsAddressable(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class == ir.PEXTERN || ir.IsAutoTmp(n))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// addrTemp ensures that n is okay to pass by address to runtime routines.
|
|
|
|
|
// If the original argument n is not okay, addrTemp creates a tmp, emits
|
2016-10-11 08:36:38 -07:00
|
|
|
// tmp = n, and then returns tmp.
|
2018-03-04 17:17:55 -08:00
|
|
|
// The result of addrTemp MUST be assigned back to n, e.g.
|
|
|
|
|
// n.Left = o.addrTemp(n.Left)
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) addrTemp(n ir.Node) ir.Node {
|
2020-11-22 09:59:15 -05:00
|
|
|
if n.Op() == ir.OLITERAL || n.Op() == ir.ONIL {
|
cmd/compile: convert constants to interfaces without allocating
The order pass is responsible for ensuring that
values passed to runtime functions, including
convT2E/convT2I, are addressable.
Prior to this CL, this was always accomplished
by creating a temp, which frequently escaped to
the heap, causing allocations, perhaps most
notably in code like:
fmt.Println(1, 2, 3) // allocates three times
None of the runtime routines modify the contents
of the pointers they receive, so in the case of
constants, instead of creating a temp value,
we can create a static value.
(Marking the static value as read-only provides
protection against accidental attempts by the runtime
to modify the constant data.)
This improves code generation for code like:
panic("abc")
c <- 2 // c is a chan int
which can now simply refer to "abc" and 2,
rather than going by way of a temporary.
It also allows us to optimize convT2E/convT2I,
by recognizing static readonly values
and directly constructing the interface.
This CL adds ~0.5% to binary size, despite
decreasing the size of many functions,
because it also adds many static symbols.
This binary size regression could be recovered in
future (but currently unplanned) work.
There is a lot of content-duplication in these
symbols; this statement generates six new symbols,
three containing an int 1 and three containing
a pointer to the string "a":
fmt.Println(1, 1, 1, "a", "a", "a")
These symbols could be made content-addressable.
Furthermore, these symbols are small, so the
alignment and naming overhead is large.
As with the go.strings section, these symbols
could be hidden and have their alignment reduced.
The changes to test/live.go make it impossible
(at least with current optimization techniques)
to place the values being passed to the runtime
in static symbols, preserving autotmp creation.
Fixes #18704
Benchmarks from fmt and go-kit's logging package:
github.com/go-kit/kit/log
name old time/op new time/op delta
JSONLoggerSimple-8 1.91µs ± 2% 2.11µs ±22% ~ (p=1.000 n=9+10)
JSONLoggerContextual-8 2.60µs ± 6% 2.43µs ± 2% -6.29% (p=0.000 n=9+10)
Discard-8 101ns ± 2% 34ns ±14% -66.33% (p=0.000 n=10+9)
OneWith-8 161ns ± 1% 102ns ±16% -36.78% (p=0.000 n=10+10)
TwoWith-8 175ns ± 3% 106ns ± 7% -39.36% (p=0.000 n=10+9)
TenWith-8 293ns ± 3% 227ns ±15% -22.44% (p=0.000 n=9+10)
LogfmtLoggerSimple-8 704ns ± 2% 608ns ± 2% -13.65% (p=0.000 n=10+9)
LogfmtLoggerContextual-8 962ns ± 1% 860ns ±17% -10.57% (p=0.003 n=9+10)
NopLoggerSimple-8 188ns ± 1% 120ns ± 1% -36.39% (p=0.000 n=9+10)
NopLoggerContextual-8 379ns ± 1% 243ns ± 0% -35.77% (p=0.000 n=9+10)
ValueBindingTimestamp-8 577ns ± 1% 499ns ± 1% -13.51% (p=0.000 n=10+10)
ValueBindingCaller-8 898ns ± 2% 844ns ± 2% -6.00% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
JSONLoggerSimple-8 904B ± 0% 872B ± 0% -3.54% (p=0.000 n=10+10)
JSONLoggerContextual-8 1.20kB ± 0% 1.14kB ± 0% -5.33% (p=0.000 n=10+10)
Discard-8 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=10+10)
OneWith-8 96.0B ± 0% 64.0B ± 0% -33.33% (p=0.000 n=10+10)
TwoWith-8 160B ± 0% 128B ± 0% -20.00% (p=0.000 n=10+10)
TenWith-8 672B ± 0% 640B ± 0% -4.76% (p=0.000 n=10+10)
LogfmtLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10)
LogfmtLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10)
NopLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10)
NopLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10)
ValueBindingTimestamp-8 159B ± 0% 127B ± 0% -20.13% (p=0.000 n=10+10)
ValueBindingCaller-8 112B ± 0% 80B ± 0% -28.57% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
JSONLoggerSimple-8 19.0 ± 0% 17.0 ± 0% -10.53% (p=0.000 n=10+10)
JSONLoggerContextual-8 25.0 ± 0% 21.0 ± 0% -16.00% (p=0.000 n=10+10)
Discard-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
OneWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
TwoWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
TenWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
LogfmtLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
LogfmtLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10)
NopLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
NopLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10)
ValueBindingTimestamp-8 5.00 ± 0% 3.00 ± 0% -40.00% (p=0.000 n=10+10)
ValueBindingCaller-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
fmt
name old time/op new time/op delta
SprintfPadding-8 88.9ns ± 3% 79.1ns ± 1% -11.09% (p=0.000 n=10+7)
SprintfEmpty-8 12.6ns ± 3% 12.8ns ± 3% ~ (p=0.136 n=10+10)
SprintfString-8 38.7ns ± 5% 26.9ns ± 6% -30.65% (p=0.000 n=10+10)
SprintfTruncateString-8 56.7ns ± 2% 47.0ns ± 3% -17.05% (p=0.000 n=10+10)
SprintfQuoteString-8 164ns ± 2% 153ns ± 2% -7.01% (p=0.000 n=10+10)
SprintfInt-8 38.9ns ±15% 26.5ns ± 2% -31.93% (p=0.000 n=10+9)
SprintfIntInt-8 60.3ns ± 9% 38.2ns ± 1% -36.67% (p=0.000 n=10+8)
SprintfPrefixedInt-8 58.6ns ±13% 51.2ns ±11% -12.66% (p=0.001 n=10+10)
SprintfFloat-8 71.4ns ± 3% 64.2ns ± 3% -10.08% (p=0.000 n=8+10)
SprintfComplex-8 175ns ± 3% 159ns ± 2% -9.03% (p=0.000 n=10+10)
SprintfBoolean-8 33.5ns ± 4% 25.7ns ± 5% -23.28% (p=0.000 n=10+10)
SprintfHexString-8 65.3ns ± 3% 51.7ns ± 5% -20.86% (p=0.000 n=10+9)
SprintfHexBytes-8 67.2ns ± 5% 67.9ns ± 4% ~ (p=0.383 n=10+10)
SprintfBytes-8 129ns ± 7% 124ns ± 7% ~ (p=0.074 n=9+10)
SprintfStringer-8 127ns ± 4% 126ns ± 8% ~ (p=0.506 n=9+10)
SprintfStructure-8 357ns ± 3% 359ns ± 3% ~ (p=0.469 n=10+10)
ManyArgs-8 203ns ± 6% 126ns ± 3% -37.94% (p=0.000 n=10+10)
FprintInt-8 119ns ±10% 74ns ± 3% -37.54% (p=0.000 n=10+10)
FprintfBytes-8 122ns ± 4% 120ns ± 3% ~ (p=0.124 n=10+10)
FprintIntNoAlloc-8 78.2ns ± 5% 74.1ns ± 3% -5.28% (p=0.000 n=10+10)
ScanInts-8 349µs ± 1% 349µs ± 0% ~ (p=0.606 n=9+8)
ScanRecursiveInt-8 43.8ms ± 7% 40.1ms ± 2% -8.42% (p=0.000 n=10+10)
ScanRecursiveIntReaderWrapper-8 43.5ms ± 4% 40.4ms ± 2% -7.16% (p=0.000 n=10+9)
name old alloc/op new alloc/op delta
SprintfPadding-8 24.0B ± 0% 16.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfEmpty-8 0.00B 0.00B ~ (all equal)
SprintfString-8 21.0B ± 0% 5.0B ± 0% -76.19% (p=0.000 n=10+10)
SprintfTruncateString-8 32.0B ± 0% 16.0B ± 0% -50.00% (p=0.000 n=10+10)
SprintfQuoteString-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfInt-8 16.0B ± 0% 1.0B ± 0% -93.75% (p=0.000 n=10+10)
SprintfIntInt-8 24.0B ± 0% 3.0B ± 0% -87.50% (p=0.000 n=10+10)
SprintfPrefixedInt-8 72.0B ± 0% 64.0B ± 0% -11.11% (p=0.000 n=10+10)
SprintfFloat-8 16.0B ± 0% 8.0B ± 0% -50.00% (p=0.000 n=10+10)
SprintfComplex-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfBoolean-8 8.00B ± 0% 4.00B ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexString-8 96.0B ± 0% 80.0B ± 0% -16.67% (p=0.000 n=10+10)
SprintfHexBytes-8 112B ± 0% 112B ± 0% ~ (all equal)
SprintfBytes-8 96.0B ± 0% 96.0B ± 0% ~ (all equal)
SprintfStringer-8 32.0B ± 0% 32.0B ± 0% ~ (all equal)
SprintfStructure-8 256B ± 0% 256B ± 0% ~ (all equal)
ManyArgs-8 80.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10)
FprintInt-8 8.00B ± 0% 0.00B -100.00% (p=0.000 n=10+10)
FprintfBytes-8 32.0B ± 0% 32.0B ± 0% ~ (all equal)
FprintIntNoAlloc-8 0.00B 0.00B ~ (all equal)
ScanInts-8 15.2kB ± 0% 15.2kB ± 0% ~ (p=0.248 n=9+10)
ScanRecursiveInt-8 21.6kB ± 0% 21.6kB ± 0% ~ (all equal)
ScanRecursiveIntReaderWrapper-8 21.7kB ± 0% 21.7kB ± 0% ~ (all equal)
name old allocs/op new allocs/op delta
SprintfPadding-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfEmpty-8 0.00 0.00 ~ (all equal)
SprintfString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfTruncateString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfQuoteString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfIntInt-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
SprintfPrefixedInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfFloat-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfComplex-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfBoolean-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal)
SprintfBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal)
SprintfStringer-8 4.00 ± 0% 4.00 ± 0% ~ (all equal)
SprintfStructure-8 7.00 ± 0% 7.00 ± 0% ~ (all equal)
ManyArgs-8 8.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
FprintInt-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
FprintfBytes-8 1.00 ± 0% 1.00 ± 0% ~ (all equal)
FprintIntNoAlloc-8 0.00 0.00 ~ (all equal)
ScanInts-8 1.60k ± 0% 1.60k ± 0% ~ (all equal)
ScanRecursiveInt-8 1.71k ± 0% 1.71k ± 0% ~ (all equal)
ScanRecursiveIntReaderWrapper-8 1.71k ± 0% 1.71k ± 0% ~ (all equal)
Change-Id: I7ba72a25fea4140a0ba40a9f443103ed87cc69b5
Reviewed-on: https://go-review.googlesource.com/35554
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2017-01-21 13:41:06 -08:00
|
|
|
// TODO: expand this to all static composite literal nodes?
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
n = typecheck.DefaultLit(n, nil)
|
2020-12-23 00:39:45 -05:00
|
|
|
types.CalcSize(n.Type())
|
2020-11-22 09:59:15 -05:00
|
|
|
vstat := readonlystaticname(n.Type())
|
2020-12-23 01:05:16 -05:00
|
|
|
var s staticinit.Schedule
|
|
|
|
|
s.StaticAssign(vstat, 0, n, n.Type())
|
|
|
|
|
if s.Out != nil {
|
2020-11-19 20:49:23 -05:00
|
|
|
base.Fatalf("staticassign of const generated code: %+v", n)
|
cmd/compile: convert constants to interfaces without allocating
The order pass is responsible for ensuring that
values passed to runtime functions, including
convT2E/convT2I, are addressable.
Prior to this CL, this was always accomplished
by creating a temp, which frequently escaped to
the heap, causing allocations, perhaps most
notably in code like:
fmt.Println(1, 2, 3) // allocates three times
None of the runtime routines modify the contents
of the pointers they receive, so in the case of
constants, instead of creating a temp value,
we can create a static value.
(Marking the static value as read-only provides
protection against accidental attempts by the runtime
to modify the constant data.)
This improves code generation for code like:
panic("abc")
c <- 2 // c is a chan int
which can now simply refer to "abc" and 2,
rather than going by way of a temporary.
It also allows us to optimize convT2E/convT2I,
by recognizing static readonly values
and directly constructing the interface.
This CL adds ~0.5% to binary size, despite
decreasing the size of many functions,
because it also adds many static symbols.
This binary size regression could be recovered in
future (but currently unplanned) work.
There is a lot of content-duplication in these
symbols; this statement generates six new symbols,
three containing an int 1 and three containing
a pointer to the string "a":
fmt.Println(1, 1, 1, "a", "a", "a")
These symbols could be made content-addressable.
Furthermore, these symbols are small, so the
alignment and naming overhead is large.
As with the go.strings section, these symbols
could be hidden and have their alignment reduced.
The changes to test/live.go make it impossible
(at least with current optimization techniques)
to place the values being passed to the runtime
in static symbols, preserving autotmp creation.
Fixes #18704
Benchmarks from fmt and go-kit's logging package:
github.com/go-kit/kit/log
name old time/op new time/op delta
JSONLoggerSimple-8 1.91µs ± 2% 2.11µs ±22% ~ (p=1.000 n=9+10)
JSONLoggerContextual-8 2.60µs ± 6% 2.43µs ± 2% -6.29% (p=0.000 n=9+10)
Discard-8 101ns ± 2% 34ns ±14% -66.33% (p=0.000 n=10+9)
OneWith-8 161ns ± 1% 102ns ±16% -36.78% (p=0.000 n=10+10)
TwoWith-8 175ns ± 3% 106ns ± 7% -39.36% (p=0.000 n=10+9)
TenWith-8 293ns ± 3% 227ns ±15% -22.44% (p=0.000 n=9+10)
LogfmtLoggerSimple-8 704ns ± 2% 608ns ± 2% -13.65% (p=0.000 n=10+9)
LogfmtLoggerContextual-8 962ns ± 1% 860ns ±17% -10.57% (p=0.003 n=9+10)
NopLoggerSimple-8 188ns ± 1% 120ns ± 1% -36.39% (p=0.000 n=9+10)
NopLoggerContextual-8 379ns ± 1% 243ns ± 0% -35.77% (p=0.000 n=9+10)
ValueBindingTimestamp-8 577ns ± 1% 499ns ± 1% -13.51% (p=0.000 n=10+10)
ValueBindingCaller-8 898ns ± 2% 844ns ± 2% -6.00% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
JSONLoggerSimple-8 904B ± 0% 872B ± 0% -3.54% (p=0.000 n=10+10)
JSONLoggerContextual-8 1.20kB ± 0% 1.14kB ± 0% -5.33% (p=0.000 n=10+10)
Discard-8 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=10+10)
OneWith-8 96.0B ± 0% 64.0B ± 0% -33.33% (p=0.000 n=10+10)
TwoWith-8 160B ± 0% 128B ± 0% -20.00% (p=0.000 n=10+10)
TenWith-8 672B ± 0% 640B ± 0% -4.76% (p=0.000 n=10+10)
LogfmtLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10)
LogfmtLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10)
NopLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10)
NopLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10)
ValueBindingTimestamp-8 159B ± 0% 127B ± 0% -20.13% (p=0.000 n=10+10)
ValueBindingCaller-8 112B ± 0% 80B ± 0% -28.57% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
JSONLoggerSimple-8 19.0 ± 0% 17.0 ± 0% -10.53% (p=0.000 n=10+10)
JSONLoggerContextual-8 25.0 ± 0% 21.0 ± 0% -16.00% (p=0.000 n=10+10)
Discard-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
OneWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
TwoWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
TenWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
LogfmtLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
LogfmtLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10)
NopLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
NopLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10)
ValueBindingTimestamp-8 5.00 ± 0% 3.00 ± 0% -40.00% (p=0.000 n=10+10)
ValueBindingCaller-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
fmt
name old time/op new time/op delta
SprintfPadding-8 88.9ns ± 3% 79.1ns ± 1% -11.09% (p=0.000 n=10+7)
SprintfEmpty-8 12.6ns ± 3% 12.8ns ± 3% ~ (p=0.136 n=10+10)
SprintfString-8 38.7ns ± 5% 26.9ns ± 6% -30.65% (p=0.000 n=10+10)
SprintfTruncateString-8 56.7ns ± 2% 47.0ns ± 3% -17.05% (p=0.000 n=10+10)
SprintfQuoteString-8 164ns ± 2% 153ns ± 2% -7.01% (p=0.000 n=10+10)
SprintfInt-8 38.9ns ±15% 26.5ns ± 2% -31.93% (p=0.000 n=10+9)
SprintfIntInt-8 60.3ns ± 9% 38.2ns ± 1% -36.67% (p=0.000 n=10+8)
SprintfPrefixedInt-8 58.6ns ±13% 51.2ns ±11% -12.66% (p=0.001 n=10+10)
SprintfFloat-8 71.4ns ± 3% 64.2ns ± 3% -10.08% (p=0.000 n=8+10)
SprintfComplex-8 175ns ± 3% 159ns ± 2% -9.03% (p=0.000 n=10+10)
SprintfBoolean-8 33.5ns ± 4% 25.7ns ± 5% -23.28% (p=0.000 n=10+10)
SprintfHexString-8 65.3ns ± 3% 51.7ns ± 5% -20.86% (p=0.000 n=10+9)
SprintfHexBytes-8 67.2ns ± 5% 67.9ns ± 4% ~ (p=0.383 n=10+10)
SprintfBytes-8 129ns ± 7% 124ns ± 7% ~ (p=0.074 n=9+10)
SprintfStringer-8 127ns ± 4% 126ns ± 8% ~ (p=0.506 n=9+10)
SprintfStructure-8 357ns ± 3% 359ns ± 3% ~ (p=0.469 n=10+10)
ManyArgs-8 203ns ± 6% 126ns ± 3% -37.94% (p=0.000 n=10+10)
FprintInt-8 119ns ±10% 74ns ± 3% -37.54% (p=0.000 n=10+10)
FprintfBytes-8 122ns ± 4% 120ns ± 3% ~ (p=0.124 n=10+10)
FprintIntNoAlloc-8 78.2ns ± 5% 74.1ns ± 3% -5.28% (p=0.000 n=10+10)
ScanInts-8 349µs ± 1% 349µs ± 0% ~ (p=0.606 n=9+8)
ScanRecursiveInt-8 43.8ms ± 7% 40.1ms ± 2% -8.42% (p=0.000 n=10+10)
ScanRecursiveIntReaderWrapper-8 43.5ms ± 4% 40.4ms ± 2% -7.16% (p=0.000 n=10+9)
name old alloc/op new alloc/op delta
SprintfPadding-8 24.0B ± 0% 16.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfEmpty-8 0.00B 0.00B ~ (all equal)
SprintfString-8 21.0B ± 0% 5.0B ± 0% -76.19% (p=0.000 n=10+10)
SprintfTruncateString-8 32.0B ± 0% 16.0B ± 0% -50.00% (p=0.000 n=10+10)
SprintfQuoteString-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfInt-8 16.0B ± 0% 1.0B ± 0% -93.75% (p=0.000 n=10+10)
SprintfIntInt-8 24.0B ± 0% 3.0B ± 0% -87.50% (p=0.000 n=10+10)
SprintfPrefixedInt-8 72.0B ± 0% 64.0B ± 0% -11.11% (p=0.000 n=10+10)
SprintfFloat-8 16.0B ± 0% 8.0B ± 0% -50.00% (p=0.000 n=10+10)
SprintfComplex-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfBoolean-8 8.00B ± 0% 4.00B ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexString-8 96.0B ± 0% 80.0B ± 0% -16.67% (p=0.000 n=10+10)
SprintfHexBytes-8 112B ± 0% 112B ± 0% ~ (all equal)
SprintfBytes-8 96.0B ± 0% 96.0B ± 0% ~ (all equal)
SprintfStringer-8 32.0B ± 0% 32.0B ± 0% ~ (all equal)
SprintfStructure-8 256B ± 0% 256B ± 0% ~ (all equal)
ManyArgs-8 80.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10)
FprintInt-8 8.00B ± 0% 0.00B -100.00% (p=0.000 n=10+10)
FprintfBytes-8 32.0B ± 0% 32.0B ± 0% ~ (all equal)
FprintIntNoAlloc-8 0.00B 0.00B ~ (all equal)
ScanInts-8 15.2kB ± 0% 15.2kB ± 0% ~ (p=0.248 n=9+10)
ScanRecursiveInt-8 21.6kB ± 0% 21.6kB ± 0% ~ (all equal)
ScanRecursiveIntReaderWrapper-8 21.7kB ± 0% 21.7kB ± 0% ~ (all equal)
name old allocs/op new allocs/op delta
SprintfPadding-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfEmpty-8 0.00 0.00 ~ (all equal)
SprintfString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfTruncateString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfQuoteString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfIntInt-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
SprintfPrefixedInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfFloat-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfComplex-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfBoolean-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal)
SprintfBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal)
SprintfStringer-8 4.00 ± 0% 4.00 ± 0% ~ (all equal)
SprintfStructure-8 7.00 ± 0% 7.00 ± 0% ~ (all equal)
ManyArgs-8 8.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
FprintInt-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
FprintfBytes-8 1.00 ± 0% 1.00 ± 0% ~ (all equal)
FprintIntNoAlloc-8 0.00 0.00 ~ (all equal)
ScanInts-8 1.60k ± 0% 1.60k ± 0% ~ (all equal)
ScanRecursiveInt-8 1.71k ± 0% 1.71k ± 0% ~ (all equal)
ScanRecursiveIntReaderWrapper-8 1.71k ± 0% 1.71k ± 0% ~ (all equal)
Change-Id: I7ba72a25fea4140a0ba40a9f443103ed87cc69b5
Reviewed-on: https://go-review.googlesource.com/35554
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2017-01-21 13:41:06 -08:00
|
|
|
}
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
vstat = typecheck.Expr(vstat).(*ir.Name)
|
cmd/compile: convert constants to interfaces without allocating
The order pass is responsible for ensuring that
values passed to runtime functions, including
convT2E/convT2I, are addressable.
Prior to this CL, this was always accomplished
by creating a temp, which frequently escaped to
the heap, causing allocations, perhaps most
notably in code like:
fmt.Println(1, 2, 3) // allocates three times
None of the runtime routines modify the contents
of the pointers they receive, so in the case of
constants, instead of creating a temp value,
we can create a static value.
(Marking the static value as read-only provides
protection against accidental attempts by the runtime
to modify the constant data.)
This improves code generation for code like:
panic("abc")
c <- 2 // c is a chan int
which can now simply refer to "abc" and 2,
rather than going by way of a temporary.
It also allows us to optimize convT2E/convT2I,
by recognizing static readonly values
and directly constructing the interface.
This CL adds ~0.5% to binary size, despite
decreasing the size of many functions,
because it also adds many static symbols.
This binary size regression could be recovered in
future (but currently unplanned) work.
There is a lot of content-duplication in these
symbols; this statement generates six new symbols,
three containing an int 1 and three containing
a pointer to the string "a":
fmt.Println(1, 1, 1, "a", "a", "a")
These symbols could be made content-addressable.
Furthermore, these symbols are small, so the
alignment and naming overhead is large.
As with the go.strings section, these symbols
could be hidden and have their alignment reduced.
The changes to test/live.go make it impossible
(at least with current optimization techniques)
to place the values being passed to the runtime
in static symbols, preserving autotmp creation.
Fixes #18704
Benchmarks from fmt and go-kit's logging package:
github.com/go-kit/kit/log
name old time/op new time/op delta
JSONLoggerSimple-8 1.91µs ± 2% 2.11µs ±22% ~ (p=1.000 n=9+10)
JSONLoggerContextual-8 2.60µs ± 6% 2.43µs ± 2% -6.29% (p=0.000 n=9+10)
Discard-8 101ns ± 2% 34ns ±14% -66.33% (p=0.000 n=10+9)
OneWith-8 161ns ± 1% 102ns ±16% -36.78% (p=0.000 n=10+10)
TwoWith-8 175ns ± 3% 106ns ± 7% -39.36% (p=0.000 n=10+9)
TenWith-8 293ns ± 3% 227ns ±15% -22.44% (p=0.000 n=9+10)
LogfmtLoggerSimple-8 704ns ± 2% 608ns ± 2% -13.65% (p=0.000 n=10+9)
LogfmtLoggerContextual-8 962ns ± 1% 860ns ±17% -10.57% (p=0.003 n=9+10)
NopLoggerSimple-8 188ns ± 1% 120ns ± 1% -36.39% (p=0.000 n=9+10)
NopLoggerContextual-8 379ns ± 1% 243ns ± 0% -35.77% (p=0.000 n=9+10)
ValueBindingTimestamp-8 577ns ± 1% 499ns ± 1% -13.51% (p=0.000 n=10+10)
ValueBindingCaller-8 898ns ± 2% 844ns ± 2% -6.00% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
JSONLoggerSimple-8 904B ± 0% 872B ± 0% -3.54% (p=0.000 n=10+10)
JSONLoggerContextual-8 1.20kB ± 0% 1.14kB ± 0% -5.33% (p=0.000 n=10+10)
Discard-8 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=10+10)
OneWith-8 96.0B ± 0% 64.0B ± 0% -33.33% (p=0.000 n=10+10)
TwoWith-8 160B ± 0% 128B ± 0% -20.00% (p=0.000 n=10+10)
TenWith-8 672B ± 0% 640B ± 0% -4.76% (p=0.000 n=10+10)
LogfmtLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10)
LogfmtLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10)
NopLoggerSimple-8 128B ± 0% 96B ± 0% -25.00% (p=0.000 n=10+10)
NopLoggerContextual-8 304B ± 0% 240B ± 0% -21.05% (p=0.000 n=10+10)
ValueBindingTimestamp-8 159B ± 0% 127B ± 0% -20.13% (p=0.000 n=10+10)
ValueBindingCaller-8 112B ± 0% 80B ± 0% -28.57% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
JSONLoggerSimple-8 19.0 ± 0% 17.0 ± 0% -10.53% (p=0.000 n=10+10)
JSONLoggerContextual-8 25.0 ± 0% 21.0 ± 0% -16.00% (p=0.000 n=10+10)
Discard-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
OneWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
TwoWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
TenWith-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
LogfmtLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
LogfmtLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10)
NopLoggerSimple-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
NopLoggerContextual-8 7.00 ± 0% 3.00 ± 0% -57.14% (p=0.000 n=10+10)
ValueBindingTimestamp-8 5.00 ± 0% 3.00 ± 0% -40.00% (p=0.000 n=10+10)
ValueBindingCaller-8 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10)
fmt
name old time/op new time/op delta
SprintfPadding-8 88.9ns ± 3% 79.1ns ± 1% -11.09% (p=0.000 n=10+7)
SprintfEmpty-8 12.6ns ± 3% 12.8ns ± 3% ~ (p=0.136 n=10+10)
SprintfString-8 38.7ns ± 5% 26.9ns ± 6% -30.65% (p=0.000 n=10+10)
SprintfTruncateString-8 56.7ns ± 2% 47.0ns ± 3% -17.05% (p=0.000 n=10+10)
SprintfQuoteString-8 164ns ± 2% 153ns ± 2% -7.01% (p=0.000 n=10+10)
SprintfInt-8 38.9ns ±15% 26.5ns ± 2% -31.93% (p=0.000 n=10+9)
SprintfIntInt-8 60.3ns ± 9% 38.2ns ± 1% -36.67% (p=0.000 n=10+8)
SprintfPrefixedInt-8 58.6ns ±13% 51.2ns ±11% -12.66% (p=0.001 n=10+10)
SprintfFloat-8 71.4ns ± 3% 64.2ns ± 3% -10.08% (p=0.000 n=8+10)
SprintfComplex-8 175ns ± 3% 159ns ± 2% -9.03% (p=0.000 n=10+10)
SprintfBoolean-8 33.5ns ± 4% 25.7ns ± 5% -23.28% (p=0.000 n=10+10)
SprintfHexString-8 65.3ns ± 3% 51.7ns ± 5% -20.86% (p=0.000 n=10+9)
SprintfHexBytes-8 67.2ns ± 5% 67.9ns ± 4% ~ (p=0.383 n=10+10)
SprintfBytes-8 129ns ± 7% 124ns ± 7% ~ (p=0.074 n=9+10)
SprintfStringer-8 127ns ± 4% 126ns ± 8% ~ (p=0.506 n=9+10)
SprintfStructure-8 357ns ± 3% 359ns ± 3% ~ (p=0.469 n=10+10)
ManyArgs-8 203ns ± 6% 126ns ± 3% -37.94% (p=0.000 n=10+10)
FprintInt-8 119ns ±10% 74ns ± 3% -37.54% (p=0.000 n=10+10)
FprintfBytes-8 122ns ± 4% 120ns ± 3% ~ (p=0.124 n=10+10)
FprintIntNoAlloc-8 78.2ns ± 5% 74.1ns ± 3% -5.28% (p=0.000 n=10+10)
ScanInts-8 349µs ± 1% 349µs ± 0% ~ (p=0.606 n=9+8)
ScanRecursiveInt-8 43.8ms ± 7% 40.1ms ± 2% -8.42% (p=0.000 n=10+10)
ScanRecursiveIntReaderWrapper-8 43.5ms ± 4% 40.4ms ± 2% -7.16% (p=0.000 n=10+9)
name old alloc/op new alloc/op delta
SprintfPadding-8 24.0B ± 0% 16.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfEmpty-8 0.00B 0.00B ~ (all equal)
SprintfString-8 21.0B ± 0% 5.0B ± 0% -76.19% (p=0.000 n=10+10)
SprintfTruncateString-8 32.0B ± 0% 16.0B ± 0% -50.00% (p=0.000 n=10+10)
SprintfQuoteString-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfInt-8 16.0B ± 0% 1.0B ± 0% -93.75% (p=0.000 n=10+10)
SprintfIntInt-8 24.0B ± 0% 3.0B ± 0% -87.50% (p=0.000 n=10+10)
SprintfPrefixedInt-8 72.0B ± 0% 64.0B ± 0% -11.11% (p=0.000 n=10+10)
SprintfFloat-8 16.0B ± 0% 8.0B ± 0% -50.00% (p=0.000 n=10+10)
SprintfComplex-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=10+10)
SprintfBoolean-8 8.00B ± 0% 4.00B ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexString-8 96.0B ± 0% 80.0B ± 0% -16.67% (p=0.000 n=10+10)
SprintfHexBytes-8 112B ± 0% 112B ± 0% ~ (all equal)
SprintfBytes-8 96.0B ± 0% 96.0B ± 0% ~ (all equal)
SprintfStringer-8 32.0B ± 0% 32.0B ± 0% ~ (all equal)
SprintfStructure-8 256B ± 0% 256B ± 0% ~ (all equal)
ManyArgs-8 80.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10)
FprintInt-8 8.00B ± 0% 0.00B -100.00% (p=0.000 n=10+10)
FprintfBytes-8 32.0B ± 0% 32.0B ± 0% ~ (all equal)
FprintIntNoAlloc-8 0.00B 0.00B ~ (all equal)
ScanInts-8 15.2kB ± 0% 15.2kB ± 0% ~ (p=0.248 n=9+10)
ScanRecursiveInt-8 21.6kB ± 0% 21.6kB ± 0% ~ (all equal)
ScanRecursiveIntReaderWrapper-8 21.7kB ± 0% 21.7kB ± 0% ~ (all equal)
name old allocs/op new allocs/op delta
SprintfPadding-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfEmpty-8 0.00 0.00 ~ (all equal)
SprintfString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfTruncateString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfQuoteString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfIntInt-8 3.00 ± 0% 1.00 ± 0% -66.67% (p=0.000 n=10+10)
SprintfPrefixedInt-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfFloat-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfComplex-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfBoolean-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexString-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
SprintfHexBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal)
SprintfBytes-8 2.00 ± 0% 2.00 ± 0% ~ (all equal)
SprintfStringer-8 4.00 ± 0% 4.00 ± 0% ~ (all equal)
SprintfStructure-8 7.00 ± 0% 7.00 ± 0% ~ (all equal)
ManyArgs-8 8.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
FprintInt-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
FprintfBytes-8 1.00 ± 0% 1.00 ± 0% ~ (all equal)
FprintIntNoAlloc-8 0.00 0.00 ~ (all equal)
ScanInts-8 1.60k ± 0% 1.60k ± 0% ~ (all equal)
ScanRecursiveInt-8 1.71k ± 0% 1.71k ± 0% ~ (all equal)
ScanRecursiveIntReaderWrapper-8 1.71k ± 0% 1.71k ± 0% ~ (all equal)
Change-Id: I7ba72a25fea4140a0ba40a9f443103ed87cc69b5
Reviewed-on: https://go-review.googlesource.com/35554
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2017-01-21 13:41:06 -08:00
|
|
|
return vstat
|
|
|
|
|
}
|
2015-02-17 22:13:49 -05:00
|
|
|
if isaddrokay(n) {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-11-29 11:16:20 -05:00
|
|
|
return o.copyExpr(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// mapKeyTemp prepares n to be a key in a map runtime call and returns n.
|
2017-03-14 11:11:28 -07:00
|
|
|
// It should only be used for map runtime calls which have *_fast* versions.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) mapKeyTemp(t *types.Type, n ir.Node) ir.Node {
|
2017-02-09 14:00:23 -08:00
|
|
|
// Most map calls need to take the address of the key.
|
2017-03-14 11:11:28 -07:00
|
|
|
// Exception: map*_fast* calls. See golang.org/issue/19015.
|
2021-04-12 16:12:20 -04:00
|
|
|
alg := mapfast(t)
|
|
|
|
|
if alg == mapslow {
|
2018-03-04 17:17:55 -08:00
|
|
|
return o.addrTemp(n)
|
2017-02-09 14:00:23 -08:00
|
|
|
}
|
2021-04-12 16:12:20 -04:00
|
|
|
var kt *types.Type
|
|
|
|
|
switch alg {
|
|
|
|
|
case mapfast32, mapfast32ptr:
|
|
|
|
|
kt = types.Types[types.TUINT32]
|
|
|
|
|
case mapfast64, mapfast64ptr:
|
|
|
|
|
kt = types.Types[types.TUINT64]
|
|
|
|
|
case mapfaststr:
|
|
|
|
|
kt = types.Types[types.TSTRING]
|
|
|
|
|
}
|
|
|
|
|
nt := n.Type()
|
|
|
|
|
switch {
|
|
|
|
|
case nt == kt:
|
|
|
|
|
return n
|
|
|
|
|
case nt.Kind() == kt.Kind():
|
|
|
|
|
// can directly convert (e.g. named type to underlying type)
|
|
|
|
|
return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONVNOP, kt, n))
|
|
|
|
|
case nt.IsInteger() && kt.IsInteger():
|
|
|
|
|
// can directly convert (e.g. int32 to uint32)
|
|
|
|
|
if n.Op() == ir.OLITERAL && nt.IsSigned() {
|
|
|
|
|
// avoid constant overflow error
|
|
|
|
|
n = ir.NewConstExpr(constant.MakeUint64(uint64(ir.Int64Val(n))), n)
|
|
|
|
|
n.SetType(kt)
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONV, kt, n))
|
|
|
|
|
default:
|
|
|
|
|
// Unsafe cast through memory.
|
|
|
|
|
// We'll need to do a load with type kt. Create a temporary of type kt to
|
|
|
|
|
// ensure sufficient alignment. nt may be under-aligned.
|
|
|
|
|
if kt.Align < nt.Align {
|
|
|
|
|
base.Fatalf("mapKeyTemp: key type is not sufficiently aligned, kt=%v nt=%v", kt, nt)
|
|
|
|
|
}
|
|
|
|
|
clear := base.Flag.Cfg.Instrumenting // clear tmp if instrumenting, as it may be live at an inserted race call
|
|
|
|
|
tmp := o.newTemp(kt, clear)
|
|
|
|
|
// *(*nt)(&tmp) = n
|
|
|
|
|
var e ir.Node = typecheck.NodAddr(tmp)
|
|
|
|
|
e = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, nt.PtrTo(), e)
|
|
|
|
|
e = ir.NewStarExpr(n.Pos(), e)
|
|
|
|
|
o.append(ir.NewAssignStmt(base.Pos, e, n))
|
|
|
|
|
return tmp
|
|
|
|
|
}
|
2017-02-09 14:00:23 -08:00
|
|
|
}
|
|
|
|
|
|
2018-11-18 08:34:38 -08:00
|
|
|
// mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP
|
2018-06-04 08:24:11 +02:00
|
|
|
// in n to avoid string allocations for keys in map lookups.
|
|
|
|
|
// Returns a bool that signals if a modification was made.
|
|
|
|
|
//
|
|
|
|
|
// For:
|
|
|
|
|
// x = m[string(k)]
|
|
|
|
|
// x = m[T1{... Tn{..., string(k), ...}]
|
|
|
|
|
// where k is []byte, T1 to Tn is a nesting of struct and array literals,
|
|
|
|
|
// the allocation of backing bytes for the string can be avoided
|
|
|
|
|
// by reusing the []byte backing array. These are special cases
|
|
|
|
|
// for avoiding allocations when converting byte slices to strings.
|
|
|
|
|
// It would be nice to handle these generally, but because
|
|
|
|
|
// []byte keys are not allowed in maps, the use of string(k)
|
|
|
|
|
// comes up in important cases in practice. See issue 3512.
|
[dev.regabi] cmd/compile: replace *Node type with an interface Node [generated]
The plan is to introduce a Node interface that replaces the old *Node pointer-to-struct.
The previous CL defined an interface INode modeling a *Node.
This CL:
- Changes all references outside internal/ir to use INode,
along with many references inside internal/ir as well.
- Renames Node to node.
- Renames INode to Node
So now ir.Node is an interface implemented by *ir.node, which is otherwise inaccessible,
and the code outside package ir is now (clearly) using only the interface.
The usual rule is never to redefine an existing name with a new meaning,
so that old code that hasn't been updated gets a "unknown name" error
instead of more mysterious errors or silent misbehavior. That rule would
caution against replacing Node-the-struct with Node-the-interface,
as in this CL, because code that says *Node would now be using a pointer
to an interface. But this CL is being landed at the same time as another that
moves Node from gc to ir. So the net effect is to replace *gc.Node with ir.Node,
which does follow the rule: any lingering references to gc.Node will be told
it's gone, not silently start using pointers to interfaces. So the rule is followed
by the CL sequence, just not this specific CL.
Overall, the loss of inlining caused by using interfaces cuts the compiler speed
by about 6%, a not insignificant amount. However, as we convert the representation
to concrete structs that are not the giant Node over the next weeks, that speed
should come back as more of the compiler starts operating directly on concrete types
and the memory taken up by the graph of Nodes drops due to the more precise
structs. Honestly, I was expecting worse.
% benchstat bench.old bench.new
name old time/op new time/op delta
Template 168ms ± 4% 182ms ± 2% +8.34% (p=0.000 n=9+9)
Unicode 72.2ms ±10% 82.5ms ± 6% +14.38% (p=0.000 n=9+9)
GoTypes 563ms ± 8% 598ms ± 2% +6.14% (p=0.006 n=9+9)
Compiler 2.89s ± 4% 3.04s ± 2% +5.37% (p=0.000 n=10+9)
SSA 6.45s ± 4% 7.25s ± 5% +12.41% (p=0.000 n=9+10)
Flate 105ms ± 2% 115ms ± 1% +9.66% (p=0.000 n=10+8)
GoParser 144ms ±10% 152ms ± 2% +5.79% (p=0.011 n=9+8)
Reflect 345ms ± 9% 370ms ± 4% +7.28% (p=0.001 n=10+9)
Tar 149ms ± 9% 161ms ± 5% +8.05% (p=0.001 n=10+9)
XML 190ms ± 3% 209ms ± 2% +9.54% (p=0.000 n=9+8)
LinkCompiler 327ms ± 2% 325ms ± 2% ~ (p=0.382 n=8+8)
ExternalLinkCompiler 1.77s ± 4% 1.73s ± 6% ~ (p=0.113 n=9+10)
LinkWithoutDebugCompiler 214ms ± 4% 211ms ± 2% ~ (p=0.360 n=10+8)
StdCmd 14.8s ± 3% 15.9s ± 1% +6.98% (p=0.000 n=10+9)
[Geo mean] 480ms 510ms +6.31%
name old user-time/op new user-time/op delta
Template 223ms ± 3% 237ms ± 3% +6.16% (p=0.000 n=9+10)
Unicode 103ms ± 6% 113ms ± 3% +9.53% (p=0.000 n=9+9)
GoTypes 758ms ± 8% 800ms ± 2% +5.55% (p=0.003 n=10+9)
Compiler 3.95s ± 2% 4.12s ± 2% +4.34% (p=0.000 n=10+9)
SSA 9.43s ± 1% 9.74s ± 4% +3.25% (p=0.000 n=8+10)
Flate 132ms ± 2% 141ms ± 2% +6.89% (p=0.000 n=9+9)
GoParser 177ms ± 9% 183ms ± 4% ~ (p=0.050 n=9+9)
Reflect 467ms ±10% 495ms ± 7% +6.17% (p=0.029 n=10+10)
Tar 183ms ± 9% 197ms ± 5% +7.92% (p=0.001 n=10+10)
XML 249ms ± 5% 268ms ± 4% +7.82% (p=0.000 n=10+9)
LinkCompiler 544ms ± 5% 544ms ± 6% ~ (p=0.863 n=9+9)
ExternalLinkCompiler 1.79s ± 4% 1.75s ± 6% ~ (p=0.075 n=10+10)
LinkWithoutDebugCompiler 248ms ± 6% 246ms ± 2% ~ (p=0.965 n=10+8)
[Geo mean] 483ms 504ms +4.41%
[git-generate]
cd src/cmd/compile/internal/ir
: # We need to do the conversion in multiple steps, so we introduce
: # a temporary type alias that will start out meaning the pointer-to-struct
: # and then change to mean the interface.
rf '
mv Node OldNode
add node.go \
type Node = *OldNode
'
: # It should work to do this ex in ir, but it misses test files, due to a bug in rf.
: # Run the command in gc to handle gc's tests, and then again in ssa for ssa's tests.
cd ../gc
rf '
ex . ../arm ../riscv64 ../arm64 ../mips64 ../ppc64 ../mips ../wasm {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
cd ../ssa
rf '
ex {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
: # Back in ir, finish conversion clumsily with sed,
: # because type checking and circular aliases do not mix.
cd ../ir
sed -i '' '
/type Node = \*OldNode/d
s/\*OldNode/Node/g
s/^func (n Node)/func (n *OldNode)/
s/OldNode/node/g
s/type INode interface/type Node interface/
s/var _ INode = (Node)(nil)/var _ Node = (*node)(nil)/
' *.go
gofmt -w *.go
sed -i '' '
s/{Func{}, 136, 248}/{Func{}, 152, 280}/
s/{Name{}, 32, 56}/{Name{}, 44, 80}/
s/{Param{}, 24, 48}/{Param{}, 44, 88}/
s/{node{}, 76, 128}/{node{}, 88, 152}/
' sizeof_test.go
cd ../ssa
sed -i '' '
s/{LocalSlot{}, 28, 40}/{LocalSlot{}, 32, 48}/
' sizeof_test.go
cd ../gc
sed -i '' 's/\*ir.Node/ir.Node/' mkbuiltin.go
cd ../../../..
go install std cmd
cd cmd/compile
go test -u || go test -u
Change-Id: I196bbe3b648e4701662e4a2bada40bf155e2a553
Reviewed-on: https://go-review.googlesource.com/c/go/+/272935
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-25 01:11:56 -05:00
|
|
|
func mapKeyReplaceStrConv(n ir.Node) bool {
|
2018-06-04 08:24:11 +02:00
|
|
|
var replaced bool
|
2020-11-22 09:59:15 -05:00
|
|
|
switch n.Op() {
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OBYTES2STR:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.ConvExpr)
|
2020-11-22 09:59:15 -05:00
|
|
|
n.SetOp(ir.OBYTES2STRTMP)
|
2018-06-04 08:24:11 +02:00
|
|
|
replaced = true
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OSTRUCTLIT:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.CompLitExpr)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, elem := range n.List {
|
2020-12-10 18:45:35 -05:00
|
|
|
elem := elem.(*ir.StructKeyExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
if mapKeyReplaceStrConv(elem.Value) {
|
2018-06-04 08:24:11 +02:00
|
|
|
replaced = true
|
|
|
|
|
}
|
|
|
|
|
}
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OARRAYLIT:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.CompLitExpr)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, elem := range n.List {
|
2020-11-22 09:59:15 -05:00
|
|
|
if elem.Op() == ir.OKEY {
|
2020-12-23 00:02:08 -05:00
|
|
|
elem = elem.(*ir.KeyExpr).Value
|
2018-06-04 08:24:11 +02:00
|
|
|
}
|
|
|
|
|
if mapKeyReplaceStrConv(elem) {
|
|
|
|
|
replaced = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return replaced
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-20 18:49:22 -08:00
|
|
|
type ordermarker int
|
|
|
|
|
|
2019-10-05 00:00:38 +07:00
|
|
|
// markTemp returns the top of the temporary variable stack.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) markTemp() ordermarker {
|
2018-03-04 17:17:55 -08:00
|
|
|
return ordermarker(len(o.temp))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2019-10-05 00:00:38 +07:00
|
|
|
// popTemp pops temporaries off the stack until reaching the mark,
|
|
|
|
|
// which must have been returned by markTemp.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) popTemp(mark ordermarker) {
|
2018-10-05 08:54:50 -07:00
|
|
|
for _, n := range o.temp[mark:] {
|
2020-11-22 09:59:15 -05:00
|
|
|
key := n.Type().LongString()
|
2018-10-05 08:54:50 -07:00
|
|
|
o.free[key] = append(o.free[key], n)
|
|
|
|
|
}
|
2018-03-04 17:17:55 -08:00
|
|
|
o.temp = o.temp[:mark]
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-09-12 01:57:27 +07:00
|
|
|
// cleanTempNoPop emits VARKILL instructions to *out
|
|
|
|
|
// for each temporary above the mark on the temporary stack.
|
2018-01-21 10:25:07 +01:00
|
|
|
// It does not pop the temporaries from the stack.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) cleanTempNoPop(mark ordermarker) []ir.Node {
|
[dev.regabi] cmd/compile: replace *Node type with an interface Node [generated]
The plan is to introduce a Node interface that replaces the old *Node pointer-to-struct.
The previous CL defined an interface INode modeling a *Node.
This CL:
- Changes all references outside internal/ir to use INode,
along with many references inside internal/ir as well.
- Renames Node to node.
- Renames INode to Node
So now ir.Node is an interface implemented by *ir.node, which is otherwise inaccessible,
and the code outside package ir is now (clearly) using only the interface.
The usual rule is never to redefine an existing name with a new meaning,
so that old code that hasn't been updated gets a "unknown name" error
instead of more mysterious errors or silent misbehavior. That rule would
caution against replacing Node-the-struct with Node-the-interface,
as in this CL, because code that says *Node would now be using a pointer
to an interface. But this CL is being landed at the same time as another that
moves Node from gc to ir. So the net effect is to replace *gc.Node with ir.Node,
which does follow the rule: any lingering references to gc.Node will be told
it's gone, not silently start using pointers to interfaces. So the rule is followed
by the CL sequence, just not this specific CL.
Overall, the loss of inlining caused by using interfaces cuts the compiler speed
by about 6%, a not insignificant amount. However, as we convert the representation
to concrete structs that are not the giant Node over the next weeks, that speed
should come back as more of the compiler starts operating directly on concrete types
and the memory taken up by the graph of Nodes drops due to the more precise
structs. Honestly, I was expecting worse.
% benchstat bench.old bench.new
name old time/op new time/op delta
Template 168ms ± 4% 182ms ± 2% +8.34% (p=0.000 n=9+9)
Unicode 72.2ms ±10% 82.5ms ± 6% +14.38% (p=0.000 n=9+9)
GoTypes 563ms ± 8% 598ms ± 2% +6.14% (p=0.006 n=9+9)
Compiler 2.89s ± 4% 3.04s ± 2% +5.37% (p=0.000 n=10+9)
SSA 6.45s ± 4% 7.25s ± 5% +12.41% (p=0.000 n=9+10)
Flate 105ms ± 2% 115ms ± 1% +9.66% (p=0.000 n=10+8)
GoParser 144ms ±10% 152ms ± 2% +5.79% (p=0.011 n=9+8)
Reflect 345ms ± 9% 370ms ± 4% +7.28% (p=0.001 n=10+9)
Tar 149ms ± 9% 161ms ± 5% +8.05% (p=0.001 n=10+9)
XML 190ms ± 3% 209ms ± 2% +9.54% (p=0.000 n=9+8)
LinkCompiler 327ms ± 2% 325ms ± 2% ~ (p=0.382 n=8+8)
ExternalLinkCompiler 1.77s ± 4% 1.73s ± 6% ~ (p=0.113 n=9+10)
LinkWithoutDebugCompiler 214ms ± 4% 211ms ± 2% ~ (p=0.360 n=10+8)
StdCmd 14.8s ± 3% 15.9s ± 1% +6.98% (p=0.000 n=10+9)
[Geo mean] 480ms 510ms +6.31%
name old user-time/op new user-time/op delta
Template 223ms ± 3% 237ms ± 3% +6.16% (p=0.000 n=9+10)
Unicode 103ms ± 6% 113ms ± 3% +9.53% (p=0.000 n=9+9)
GoTypes 758ms ± 8% 800ms ± 2% +5.55% (p=0.003 n=10+9)
Compiler 3.95s ± 2% 4.12s ± 2% +4.34% (p=0.000 n=10+9)
SSA 9.43s ± 1% 9.74s ± 4% +3.25% (p=0.000 n=8+10)
Flate 132ms ± 2% 141ms ± 2% +6.89% (p=0.000 n=9+9)
GoParser 177ms ± 9% 183ms ± 4% ~ (p=0.050 n=9+9)
Reflect 467ms ±10% 495ms ± 7% +6.17% (p=0.029 n=10+10)
Tar 183ms ± 9% 197ms ± 5% +7.92% (p=0.001 n=10+10)
XML 249ms ± 5% 268ms ± 4% +7.82% (p=0.000 n=10+9)
LinkCompiler 544ms ± 5% 544ms ± 6% ~ (p=0.863 n=9+9)
ExternalLinkCompiler 1.79s ± 4% 1.75s ± 6% ~ (p=0.075 n=10+10)
LinkWithoutDebugCompiler 248ms ± 6% 246ms ± 2% ~ (p=0.965 n=10+8)
[Geo mean] 483ms 504ms +4.41%
[git-generate]
cd src/cmd/compile/internal/ir
: # We need to do the conversion in multiple steps, so we introduce
: # a temporary type alias that will start out meaning the pointer-to-struct
: # and then change to mean the interface.
rf '
mv Node OldNode
add node.go \
type Node = *OldNode
'
: # It should work to do this ex in ir, but it misses test files, due to a bug in rf.
: # Run the command in gc to handle gc's tests, and then again in ssa for ssa's tests.
cd ../gc
rf '
ex . ../arm ../riscv64 ../arm64 ../mips64 ../ppc64 ../mips ../wasm {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
cd ../ssa
rf '
ex {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
: # Back in ir, finish conversion clumsily with sed,
: # because type checking and circular aliases do not mix.
cd ../ir
sed -i '' '
/type Node = \*OldNode/d
s/\*OldNode/Node/g
s/^func (n Node)/func (n *OldNode)/
s/OldNode/node/g
s/type INode interface/type Node interface/
s/var _ INode = (Node)(nil)/var _ Node = (*node)(nil)/
' *.go
gofmt -w *.go
sed -i '' '
s/{Func{}, 136, 248}/{Func{}, 152, 280}/
s/{Name{}, 32, 56}/{Name{}, 44, 80}/
s/{Param{}, 24, 48}/{Param{}, 44, 88}/
s/{node{}, 76, 128}/{node{}, 88, 152}/
' sizeof_test.go
cd ../ssa
sed -i '' '
s/{LocalSlot{}, 28, 40}/{LocalSlot{}, 32, 48}/
' sizeof_test.go
cd ../gc
sed -i '' 's/\*ir.Node/ir.Node/' mkbuiltin.go
cd ../../../..
go install std cmd
cd cmd/compile
go test -u || go test -u
Change-Id: I196bbe3b648e4701662e4a2bada40bf155e2a553
Reviewed-on: https://go-review.googlesource.com/c/go/+/272935
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-25 01:11:56 -05:00
|
|
|
var out []ir.Node
|
2018-03-04 17:17:55 -08:00
|
|
|
for i := len(o.temp) - 1; i >= int(mark); i-- {
|
|
|
|
|
n := o.temp[i]
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
out = append(out, typecheck.Stmt(ir.NewUnaryExpr(base.Pos, ir.OVARKILL, n)))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-03-22 12:49:48 -07:00
|
|
|
return out
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// cleanTemp emits VARKILL instructions for each temporary above the
|
2015-02-13 14:40:36 -05:00
|
|
|
// mark on the temporary stack and removes them from the stack.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) cleanTemp(top ordermarker) {
|
2018-03-22 12:49:48 -07:00
|
|
|
o.out = append(o.out, o.cleanTempNoPop(top)...)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.popTemp(top)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// stmtList orders each of the statements in the list.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) stmtList(l ir.Nodes) {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
s := l
|
2018-10-23 13:50:07 +02:00
|
|
|
for i := range s {
|
|
|
|
|
orderMakeSliceCopy(s[i:])
|
|
|
|
|
o.stmt(s[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// orderMakeSliceCopy matches the pattern:
|
|
|
|
|
// m = OMAKESLICE([]T, x); OCOPY(m, s)
|
|
|
|
|
// and rewrites it to:
|
|
|
|
|
// m = OMAKESLICECOPY([]T, x, s); nil
|
[dev.regabi] cmd/compile: replace *Node type with an interface Node [generated]
The plan is to introduce a Node interface that replaces the old *Node pointer-to-struct.
The previous CL defined an interface INode modeling a *Node.
This CL:
- Changes all references outside internal/ir to use INode,
along with many references inside internal/ir as well.
- Renames Node to node.
- Renames INode to Node
So now ir.Node is an interface implemented by *ir.node, which is otherwise inaccessible,
and the code outside package ir is now (clearly) using only the interface.
The usual rule is never to redefine an existing name with a new meaning,
so that old code that hasn't been updated gets a "unknown name" error
instead of more mysterious errors or silent misbehavior. That rule would
caution against replacing Node-the-struct with Node-the-interface,
as in this CL, because code that says *Node would now be using a pointer
to an interface. But this CL is being landed at the same time as another that
moves Node from gc to ir. So the net effect is to replace *gc.Node with ir.Node,
which does follow the rule: any lingering references to gc.Node will be told
it's gone, not silently start using pointers to interfaces. So the rule is followed
by the CL sequence, just not this specific CL.
Overall, the loss of inlining caused by using interfaces cuts the compiler speed
by about 6%, a not insignificant amount. However, as we convert the representation
to concrete structs that are not the giant Node over the next weeks, that speed
should come back as more of the compiler starts operating directly on concrete types
and the memory taken up by the graph of Nodes drops due to the more precise
structs. Honestly, I was expecting worse.
% benchstat bench.old bench.new
name old time/op new time/op delta
Template 168ms ± 4% 182ms ± 2% +8.34% (p=0.000 n=9+9)
Unicode 72.2ms ±10% 82.5ms ± 6% +14.38% (p=0.000 n=9+9)
GoTypes 563ms ± 8% 598ms ± 2% +6.14% (p=0.006 n=9+9)
Compiler 2.89s ± 4% 3.04s ± 2% +5.37% (p=0.000 n=10+9)
SSA 6.45s ± 4% 7.25s ± 5% +12.41% (p=0.000 n=9+10)
Flate 105ms ± 2% 115ms ± 1% +9.66% (p=0.000 n=10+8)
GoParser 144ms ±10% 152ms ± 2% +5.79% (p=0.011 n=9+8)
Reflect 345ms ± 9% 370ms ± 4% +7.28% (p=0.001 n=10+9)
Tar 149ms ± 9% 161ms ± 5% +8.05% (p=0.001 n=10+9)
XML 190ms ± 3% 209ms ± 2% +9.54% (p=0.000 n=9+8)
LinkCompiler 327ms ± 2% 325ms ± 2% ~ (p=0.382 n=8+8)
ExternalLinkCompiler 1.77s ± 4% 1.73s ± 6% ~ (p=0.113 n=9+10)
LinkWithoutDebugCompiler 214ms ± 4% 211ms ± 2% ~ (p=0.360 n=10+8)
StdCmd 14.8s ± 3% 15.9s ± 1% +6.98% (p=0.000 n=10+9)
[Geo mean] 480ms 510ms +6.31%
name old user-time/op new user-time/op delta
Template 223ms ± 3% 237ms ± 3% +6.16% (p=0.000 n=9+10)
Unicode 103ms ± 6% 113ms ± 3% +9.53% (p=0.000 n=9+9)
GoTypes 758ms ± 8% 800ms ± 2% +5.55% (p=0.003 n=10+9)
Compiler 3.95s ± 2% 4.12s ± 2% +4.34% (p=0.000 n=10+9)
SSA 9.43s ± 1% 9.74s ± 4% +3.25% (p=0.000 n=8+10)
Flate 132ms ± 2% 141ms ± 2% +6.89% (p=0.000 n=9+9)
GoParser 177ms ± 9% 183ms ± 4% ~ (p=0.050 n=9+9)
Reflect 467ms ±10% 495ms ± 7% +6.17% (p=0.029 n=10+10)
Tar 183ms ± 9% 197ms ± 5% +7.92% (p=0.001 n=10+10)
XML 249ms ± 5% 268ms ± 4% +7.82% (p=0.000 n=10+9)
LinkCompiler 544ms ± 5% 544ms ± 6% ~ (p=0.863 n=9+9)
ExternalLinkCompiler 1.79s ± 4% 1.75s ± 6% ~ (p=0.075 n=10+10)
LinkWithoutDebugCompiler 248ms ± 6% 246ms ± 2% ~ (p=0.965 n=10+8)
[Geo mean] 483ms 504ms +4.41%
[git-generate]
cd src/cmd/compile/internal/ir
: # We need to do the conversion in multiple steps, so we introduce
: # a temporary type alias that will start out meaning the pointer-to-struct
: # and then change to mean the interface.
rf '
mv Node OldNode
add node.go \
type Node = *OldNode
'
: # It should work to do this ex in ir, but it misses test files, due to a bug in rf.
: # Run the command in gc to handle gc's tests, and then again in ssa for ssa's tests.
cd ../gc
rf '
ex . ../arm ../riscv64 ../arm64 ../mips64 ../ppc64 ../mips ../wasm {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
cd ../ssa
rf '
ex {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
: # Back in ir, finish conversion clumsily with sed,
: # because type checking and circular aliases do not mix.
cd ../ir
sed -i '' '
/type Node = \*OldNode/d
s/\*OldNode/Node/g
s/^func (n Node)/func (n *OldNode)/
s/OldNode/node/g
s/type INode interface/type Node interface/
s/var _ INode = (Node)(nil)/var _ Node = (*node)(nil)/
' *.go
gofmt -w *.go
sed -i '' '
s/{Func{}, 136, 248}/{Func{}, 152, 280}/
s/{Name{}, 32, 56}/{Name{}, 44, 80}/
s/{Param{}, 24, 48}/{Param{}, 44, 88}/
s/{node{}, 76, 128}/{node{}, 88, 152}/
' sizeof_test.go
cd ../ssa
sed -i '' '
s/{LocalSlot{}, 28, 40}/{LocalSlot{}, 32, 48}/
' sizeof_test.go
cd ../gc
sed -i '' 's/\*ir.Node/ir.Node/' mkbuiltin.go
cd ../../../..
go install std cmd
cd cmd/compile
go test -u || go test -u
Change-Id: I196bbe3b648e4701662e4a2bada40bf155e2a553
Reviewed-on: https://go-review.googlesource.com/c/go/+/272935
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-25 01:11:56 -05:00
|
|
|
func orderMakeSliceCopy(s []ir.Node) {
|
2020-12-23 00:05:23 -05:00
|
|
|
if base.Flag.N != 0 || base.Flag.Cfg.Instrumenting {
|
2018-10-23 13:50:07 +02:00
|
|
|
return
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
if len(s) < 2 || s[0] == nil || s[0].Op() != ir.OAS || s[1] == nil || s[1].Op() != ir.OCOPY {
|
2018-10-23 13:50:07 +02:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
as := s[0].(*ir.AssignStmt)
|
|
|
|
|
cp := s[1].(*ir.BinaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
if as.Y == nil || as.Y.Op() != ir.OMAKESLICE || ir.IsBlank(as.X) ||
|
|
|
|
|
as.X.Op() != ir.ONAME || cp.X.Op() != ir.ONAME || cp.Y.Op() != ir.ONAME ||
|
|
|
|
|
as.X.Name() != cp.X.Name() || cp.X.Name() == cp.Y.Name() {
|
2020-12-10 18:45:35 -05:00
|
|
|
// The line above this one is correct with the differing equality operators:
|
|
|
|
|
// we want as.X and cp.X to be the same name,
|
|
|
|
|
// but we want the initial data to be coming from a different name.
|
2018-10-23 13:50:07 +02:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
mk := as.Y.(*ir.MakeExpr)
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
if mk.Esc() == ir.EscNone || mk.Len == nil || mk.Cap != nil {
|
2018-10-23 13:50:07 +02:00
|
|
|
return
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
mk.SetOp(ir.OMAKESLICECOPY)
|
2020-12-23 00:02:08 -05:00
|
|
|
mk.Cap = cp.Y
|
2018-10-23 13:50:07 +02:00
|
|
|
// Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
mk.SetBounded(mk.Len.Op() == ir.OLEN && ir.SameSafeExpr(mk.Len.(*ir.UnaryExpr).X, cp.Y))
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
as.Y = typecheck.Expr(mk)
|
2018-10-23 13:50:07 +02:00
|
|
|
s[1] = nil // remove separate copy call
|
2016-02-27 14:31:33 -08:00
|
|
|
}
|
|
|
|
|
|
2019-10-18 17:39:39 -07:00
|
|
|
// edge inserts coverage instrumentation for libfuzzer.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) edge() {
|
2020-11-19 20:49:23 -05:00
|
|
|
if base.Debug.Libfuzzer == 0 {
|
2019-10-18 17:39:39 -07:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a new uint8 counter to be allocated in section
|
|
|
|
|
// __libfuzzer_extra_counters.
|
2020-12-23 01:05:16 -05:00
|
|
|
counter := staticinit.StaticName(types.Types[types.TUINT8])
|
2020-12-31 18:25:35 -08:00
|
|
|
counter.SetLibfuzzerExtraCounter(true)
|
2019-10-18 17:39:39 -07:00
|
|
|
|
|
|
|
|
// counter += 1
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))
|
2020-12-07 14:56:49 -05:00
|
|
|
o.append(incr)
|
2019-10-18 17:39:39 -07:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// orderBlock orders the block of statements in n into a new slice,
|
2016-02-27 14:31:33 -08:00
|
|
|
// and then replaces the old slice in n with the new slice.
|
2018-10-05 08:54:50 -07:00
|
|
|
// free is a map that can be used to obtain temporary variables by type.
|
2020-12-04 11:38:47 +07:00
|
|
|
func orderBlock(n *ir.Nodes, free map[string][]*ir.Name) {
|
2020-12-23 01:05:16 -05:00
|
|
|
var order orderState
|
2018-10-05 08:54:50 -07:00
|
|
|
order.free = free
|
2018-03-04 17:17:55 -08:00
|
|
|
mark := order.markTemp()
|
2019-10-18 17:39:39 -07:00
|
|
|
order.edge()
|
2018-03-04 17:17:55 -08:00
|
|
|
order.stmtList(*n)
|
|
|
|
|
order.cleanTemp(mark)
|
2021-01-02 01:27:29 -08:00
|
|
|
*n = order.out
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// exprInPlace orders the side effects in *np and
|
2015-02-13 14:40:36 -05:00
|
|
|
// leaves them as the init list of the final *np.
|
2018-03-04 17:17:55 -08:00
|
|
|
// The result of exprInPlace MUST be assigned back to n, e.g.
|
|
|
|
|
// n.Left = o.exprInPlace(n.Left)
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) exprInPlace(n ir.Node) ir.Node {
|
|
|
|
|
var order orderState
|
2018-10-05 08:54:50 -07:00
|
|
|
order.free = o.free
|
2018-03-04 17:17:55 -08:00
|
|
|
n = order.expr(n, nil)
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
n = ir.InitExpr(order.out, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// insert new temporaries from order
|
|
|
|
|
// at head of outer list.
|
2018-03-04 17:17:55 -08:00
|
|
|
o.temp = append(o.temp, order.temp...)
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// orderStmtInPlace orders the side effects of the single statement *np
|
2015-02-13 14:40:36 -05:00
|
|
|
// and replaces it with the resulting statement list.
|
2018-03-04 17:17:55 -08:00
|
|
|
// The result of orderStmtInPlace MUST be assigned back to n, e.g.
|
|
|
|
|
// n.Left = orderStmtInPlace(n.Left)
|
2018-10-05 08:54:50 -07:00
|
|
|
// free is a map that can be used to obtain temporary variables by type.
|
2020-12-04 11:38:47 +07:00
|
|
|
func orderStmtInPlace(n ir.Node, free map[string][]*ir.Name) ir.Node {
|
2020-12-23 01:05:16 -05:00
|
|
|
var order orderState
|
2018-10-05 08:54:50 -07:00
|
|
|
order.free = free
|
2018-03-04 17:17:55 -08:00
|
|
|
mark := order.markTemp()
|
|
|
|
|
order.stmt(n)
|
|
|
|
|
order.cleanTemp(mark)
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
return ir.NewBlockStmt(src.NoXPos, order.out)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// init moves n's init list to o.out.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) init(n ir.Node) {
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
if ir.MayBeShared(n) {
|
2017-03-28 07:12:57 -07:00
|
|
|
// For concurrency safety, don't mutate potentially shared nodes.
|
|
|
|
|
// First, ensure that no work is required here.
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
if len(n.Init()) > 0 {
|
2020-11-19 20:49:23 -05:00
|
|
|
base.Fatalf("order.init shared node with ninit")
|
2017-03-28 07:12:57 -07:00
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2021-01-02 01:04:19 -08:00
|
|
|
o.stmtList(ir.TakeInit(n))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// call orders the call expression n.
|
|
|
|
|
// n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) call(nn ir.Node) {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
if len(nn.Init()) > 0 {
|
2020-12-10 18:45:35 -05:00
|
|
|
// Caller should have already called o.init(nn).
|
|
|
|
|
base.Fatalf("%v with unexpected ninit", nn.Op())
|
2019-03-25 16:34:19 -07:00
|
|
|
}
|
cmd/compile: move fixVariadicCall from walk to order
This CL moves fixVariadicCall from mid-Walk of function calls to
early-Order, in preparation for moving it even earlier in the future.
Notably, rewriting variadic calls this early introduces two
compilation output changes:
1. Previously, Order visited the ODDDARG before the rest of the
arguments list, whereas the natural time to visit it is at the end of
the list (as we visit arguments left-to-right, and the ... argument is
the rightmost one). Changing this ordering permutes the autotmp
allocation order, which in turn permutes autotmp naming and stack
offsets.
2. Previously, Walk separately walked all of the variadic arguments
before walking the entire slice literal, whereas the more natural
thing to do is just walk the entire slice literal. This triggers
slightly different code paths for composite literal construction in
some cases.
Neither of these have semantic impact. They simply mean we're now
compiling f(a,b,c) the same way as we were already compiling
f([]T{a,b,c}...).
Change-Id: I40ccc5725697a116370111ebe746b2639562fe87
Reviewed-on: https://go-review.googlesource.com/c/go/+/229601
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2020-04-21 15:59:11 -07:00
|
|
|
|
|
|
|
|
// Builtin functions.
|
2020-12-10 18:45:35 -05:00
|
|
|
if nn.Op() != ir.OCALLFUNC && nn.Op() != ir.OCALLMETH && nn.Op() != ir.OCALLINTER {
|
|
|
|
|
switch n := nn.(type) {
|
|
|
|
|
default:
|
|
|
|
|
base.Fatalf("unexpected call: %+v", n)
|
|
|
|
|
case *ir.UnaryExpr:
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
case *ir.ConvExpr:
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
case *ir.BinaryExpr:
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
n.Y = o.expr(n.Y, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
case *ir.MakeExpr:
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Len = o.expr(n.Len, nil)
|
|
|
|
|
n.Cap = o.expr(n.Cap, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
case *ir.CallExpr:
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.Args)
|
2020-12-10 18:45:35 -05:00
|
|
|
}
|
cmd/compile: move fixVariadicCall from walk to order
This CL moves fixVariadicCall from mid-Walk of function calls to
early-Order, in preparation for moving it even earlier in the future.
Notably, rewriting variadic calls this early introduces two
compilation output changes:
1. Previously, Order visited the ODDDARG before the rest of the
arguments list, whereas the natural time to visit it is at the end of
the list (as we visit arguments left-to-right, and the ... argument is
the rightmost one). Changing this ordering permutes the autotmp
allocation order, which in turn permutes autotmp naming and stack
offsets.
2. Previously, Walk separately walked all of the variadic arguments
before walking the entire slice literal, whereas the more natural
thing to do is just walk the entire slice literal. This triggers
slightly different code paths for composite literal construction in
some cases.
Neither of these have semantic impact. They simply mean we're now
compiling f(a,b,c) the same way as we were already compiling
f([]T{a,b,c}...).
Change-Id: I40ccc5725697a116370111ebe746b2639562fe87
Reviewed-on: https://go-review.googlesource.com/c/go/+/229601
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2020-04-21 15:59:11 -07:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
n := nn.(*ir.CallExpr)
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
typecheck.FixVariadicCall(n)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
o.exprList(n.Args)
|
cmd/compile: recognize Syscall-like functions for liveness analysis
Consider this code:
func f(*int)
func g() {
p := new(int)
f(p)
}
where f is an assembly function.
In general liveness analysis assumes that during the call to f, p is dead
in this frame. If f has retained p, p will be found alive in f's frame and keep
the new(int) from being garbage collected. This is all correct and works.
We use the Go func declaration for f to give the assembly function
liveness information (the arguments are assumed live for the entire call).
Now consider this code:
func h1() {
p := new(int)
syscall.Syscall(1, 2, 3, uintptr(unsafe.Pointer(p)))
}
Here syscall.Syscall is taking the place of f, but because its arguments
are uintptr, the liveness analysis and the garbage collector ignore them.
Since p is no longer live in h once the call starts, if the garbage collector
scans the stack while the system call is blocked, it will find no reference
to the new(int) and reclaim it. If the kernel is going to write to *p once
the call finishes, reclaiming the memory is a mistake.
We can't change the arguments or the liveness information for
syscall.Syscall itself, both for compatibility and because sometimes the
arguments really are integers, and the garbage collector will get quite upset
if it finds an integer where it expects a pointer. The problem is that
these arguments are fundamentally untyped.
The solution we have taken in the syscall package's wrappers in past
releases is to insert a call to a dummy function named "use", to make
it look like the argument is live during the call to syscall.Syscall:
func h2() {
p := new(int)
syscall.Syscall(1, 2, 3, uintptr(unsafe.Pointer(p)))
use(unsafe.Pointer(p))
}
Keeping p alive during the call means that if the garbage collector
scans the stack during the system call now, it will find the reference to p.
Unfortunately, this approach is not available to users outside syscall,
because 'use' is unexported, and people also have to realize they need
to use it and do so. There is much existing code using syscall.Syscall
without a 'use'-like function. That code will fail very occasionally in
mysterious ways (see #13372).
This CL fixes all that existing code by making the compiler do the right
thing automatically, without any code modifications. That is, it takes h1
above, which is incorrect code today, and makes it correct code.
Specifically, if the compiler sees a foreign func definition (one
without a body) that has uintptr arguments, it marks those arguments
as "unsafe uintptrs". If it later sees the function being called
with uintptr(unsafe.Pointer(x)) as an argument, it arranges to mark x
as having escaped, and it makes sure to hold x in a live temporary
variable until the call returns, so that the garbage collector cannot
reclaim whatever heap memory x points to.
For now I am leaving the explicit calls to use in package syscall,
but they can be removed early in a future cycle (likely Go 1.7).
The rule has no effect on escape analysis, only on liveness analysis.
Fixes #13372.
Change-Id: I2addb83f70d08db08c64d394f9d06ff0a063c500
Reviewed-on: https://go-review.googlesource.com/18584
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-01-13 00:46:28 -05:00
|
|
|
|
2020-11-22 09:59:15 -05:00
|
|
|
if n.Op() == ir.OCALLINTER {
|
2018-04-03 13:17:28 +01:00
|
|
|
return
|
|
|
|
|
}
|
[dev.regabi] cmd/compile: replace *Node type with an interface Node [generated]
The plan is to introduce a Node interface that replaces the old *Node pointer-to-struct.
The previous CL defined an interface INode modeling a *Node.
This CL:
- Changes all references outside internal/ir to use INode,
along with many references inside internal/ir as well.
- Renames Node to node.
- Renames INode to Node
So now ir.Node is an interface implemented by *ir.node, which is otherwise inaccessible,
and the code outside package ir is now (clearly) using only the interface.
The usual rule is never to redefine an existing name with a new meaning,
so that old code that hasn't been updated gets a "unknown name" error
instead of more mysterious errors or silent misbehavior. That rule would
caution against replacing Node-the-struct with Node-the-interface,
as in this CL, because code that says *Node would now be using a pointer
to an interface. But this CL is being landed at the same time as another that
moves Node from gc to ir. So the net effect is to replace *gc.Node with ir.Node,
which does follow the rule: any lingering references to gc.Node will be told
it's gone, not silently start using pointers to interfaces. So the rule is followed
by the CL sequence, just not this specific CL.
Overall, the loss of inlining caused by using interfaces cuts the compiler speed
by about 6%, a not insignificant amount. However, as we convert the representation
to concrete structs that are not the giant Node over the next weeks, that speed
should come back as more of the compiler starts operating directly on concrete types
and the memory taken up by the graph of Nodes drops due to the more precise
structs. Honestly, I was expecting worse.
% benchstat bench.old bench.new
name old time/op new time/op delta
Template 168ms ± 4% 182ms ± 2% +8.34% (p=0.000 n=9+9)
Unicode 72.2ms ±10% 82.5ms ± 6% +14.38% (p=0.000 n=9+9)
GoTypes 563ms ± 8% 598ms ± 2% +6.14% (p=0.006 n=9+9)
Compiler 2.89s ± 4% 3.04s ± 2% +5.37% (p=0.000 n=10+9)
SSA 6.45s ± 4% 7.25s ± 5% +12.41% (p=0.000 n=9+10)
Flate 105ms ± 2% 115ms ± 1% +9.66% (p=0.000 n=10+8)
GoParser 144ms ±10% 152ms ± 2% +5.79% (p=0.011 n=9+8)
Reflect 345ms ± 9% 370ms ± 4% +7.28% (p=0.001 n=10+9)
Tar 149ms ± 9% 161ms ± 5% +8.05% (p=0.001 n=10+9)
XML 190ms ± 3% 209ms ± 2% +9.54% (p=0.000 n=9+8)
LinkCompiler 327ms ± 2% 325ms ± 2% ~ (p=0.382 n=8+8)
ExternalLinkCompiler 1.77s ± 4% 1.73s ± 6% ~ (p=0.113 n=9+10)
LinkWithoutDebugCompiler 214ms ± 4% 211ms ± 2% ~ (p=0.360 n=10+8)
StdCmd 14.8s ± 3% 15.9s ± 1% +6.98% (p=0.000 n=10+9)
[Geo mean] 480ms 510ms +6.31%
name old user-time/op new user-time/op delta
Template 223ms ± 3% 237ms ± 3% +6.16% (p=0.000 n=9+10)
Unicode 103ms ± 6% 113ms ± 3% +9.53% (p=0.000 n=9+9)
GoTypes 758ms ± 8% 800ms ± 2% +5.55% (p=0.003 n=10+9)
Compiler 3.95s ± 2% 4.12s ± 2% +4.34% (p=0.000 n=10+9)
SSA 9.43s ± 1% 9.74s ± 4% +3.25% (p=0.000 n=8+10)
Flate 132ms ± 2% 141ms ± 2% +6.89% (p=0.000 n=9+9)
GoParser 177ms ± 9% 183ms ± 4% ~ (p=0.050 n=9+9)
Reflect 467ms ±10% 495ms ± 7% +6.17% (p=0.029 n=10+10)
Tar 183ms ± 9% 197ms ± 5% +7.92% (p=0.001 n=10+10)
XML 249ms ± 5% 268ms ± 4% +7.82% (p=0.000 n=10+9)
LinkCompiler 544ms ± 5% 544ms ± 6% ~ (p=0.863 n=9+9)
ExternalLinkCompiler 1.79s ± 4% 1.75s ± 6% ~ (p=0.075 n=10+10)
LinkWithoutDebugCompiler 248ms ± 6% 246ms ± 2% ~ (p=0.965 n=10+8)
[Geo mean] 483ms 504ms +4.41%
[git-generate]
cd src/cmd/compile/internal/ir
: # We need to do the conversion in multiple steps, so we introduce
: # a temporary type alias that will start out meaning the pointer-to-struct
: # and then change to mean the interface.
rf '
mv Node OldNode
add node.go \
type Node = *OldNode
'
: # It should work to do this ex in ir, but it misses test files, due to a bug in rf.
: # Run the command in gc to handle gc's tests, and then again in ssa for ssa's tests.
cd ../gc
rf '
ex . ../arm ../riscv64 ../arm64 ../mips64 ../ppc64 ../mips ../wasm {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
cd ../ssa
rf '
ex {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
: # Back in ir, finish conversion clumsily with sed,
: # because type checking and circular aliases do not mix.
cd ../ir
sed -i '' '
/type Node = \*OldNode/d
s/\*OldNode/Node/g
s/^func (n Node)/func (n *OldNode)/
s/OldNode/node/g
s/type INode interface/type Node interface/
s/var _ INode = (Node)(nil)/var _ Node = (*node)(nil)/
' *.go
gofmt -w *.go
sed -i '' '
s/{Func{}, 136, 248}/{Func{}, 152, 280}/
s/{Name{}, 32, 56}/{Name{}, 44, 80}/
s/{Param{}, 24, 48}/{Param{}, 44, 88}/
s/{node{}, 76, 128}/{node{}, 88, 152}/
' sizeof_test.go
cd ../ssa
sed -i '' '
s/{LocalSlot{}, 28, 40}/{LocalSlot{}, 32, 48}/
' sizeof_test.go
cd ../gc
sed -i '' 's/\*ir.Node/ir.Node/' mkbuiltin.go
cd ../../../..
go install std cmd
cd cmd/compile
go test -u || go test -u
Change-Id: I196bbe3b648e4701662e4a2bada40bf155e2a553
Reviewed-on: https://go-review.googlesource.com/c/go/+/272935
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-25 01:11:56 -05:00
|
|
|
keepAlive := func(arg ir.Node) {
|
2018-04-03 13:17:28 +01:00
|
|
|
// If the argument is really a pointer being converted to uintptr,
|
|
|
|
|
// arrange for the pointer to be kept alive until the call returns,
|
|
|
|
|
// by copying it into a temp and marking that temp
|
|
|
|
|
// still alive when we pop the temp stack.
|
2020-12-10 18:45:35 -05:00
|
|
|
if arg.Op() == ir.OCONVNOP {
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
arg := arg.(*ir.ConvExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
if arg.X.Type().IsUnsafePtr() {
|
|
|
|
|
x := o.copyExpr(arg.X)
|
|
|
|
|
arg.X = x
|
2020-12-31 18:25:35 -08:00
|
|
|
x.SetAddrtaken(true) // ensure SSA keeps the x variable
|
2020-12-31 16:51:12 +07:00
|
|
|
n.KeepAlive = append(n.KeepAlive, x)
|
2020-12-10 18:45:35 -05:00
|
|
|
}
|
2017-04-05 19:38:21 -07:00
|
|
|
}
|
2018-04-03 13:17:28 +01:00
|
|
|
}
|
2017-04-05 19:38:21 -07:00
|
|
|
|
2020-04-22 14:37:02 -07:00
|
|
|
// Check for "unsafe-uintptr" tag provided by escape analysis.
|
2020-12-23 00:02:08 -05:00
|
|
|
for i, param := range n.X.Type().Params().FieldSlice() {
|
2020-12-23 00:51:28 -05:00
|
|
|
if param.Note == escape.UnsafeUintptrNote || param.Note == escape.UintptrEscapesNote {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
if arg := n.Args[i]; arg.Op() == ir.OSLICELIT {
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
arg := arg.(*ir.CompLitExpr)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, elt := range arg.List {
|
cmd/compile: move fixVariadicCall from walk to order
This CL moves fixVariadicCall from mid-Walk of function calls to
early-Order, in preparation for moving it even earlier in the future.
Notably, rewriting variadic calls this early introduces two
compilation output changes:
1. Previously, Order visited the ODDDARG before the rest of the
arguments list, whereas the natural time to visit it is at the end of
the list (as we visit arguments left-to-right, and the ... argument is
the rightmost one). Changing this ordering permutes the autotmp
allocation order, which in turn permutes autotmp naming and stack
offsets.
2. Previously, Walk separately walked all of the variadic arguments
before walking the entire slice literal, whereas the more natural
thing to do is just walk the entire slice literal. This triggers
slightly different code paths for composite literal construction in
some cases.
Neither of these have semantic impact. They simply mean we're now
compiling f(a,b,c) the same way as we were already compiling
f([]T{a,b,c}...).
Change-Id: I40ccc5725697a116370111ebe746b2639562fe87
Reviewed-on: https://go-review.googlesource.com/c/go/+/229601
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2020-04-21 15:59:11 -07:00
|
|
|
keepAlive(elt)
|
cmd/compile: recognize Syscall-like functions for liveness analysis
Consider this code:
func f(*int)
func g() {
p := new(int)
f(p)
}
where f is an assembly function.
In general liveness analysis assumes that during the call to f, p is dead
in this frame. If f has retained p, p will be found alive in f's frame and keep
the new(int) from being garbage collected. This is all correct and works.
We use the Go func declaration for f to give the assembly function
liveness information (the arguments are assumed live for the entire call).
Now consider this code:
func h1() {
p := new(int)
syscall.Syscall(1, 2, 3, uintptr(unsafe.Pointer(p)))
}
Here syscall.Syscall is taking the place of f, but because its arguments
are uintptr, the liveness analysis and the garbage collector ignore them.
Since p is no longer live in h once the call starts, if the garbage collector
scans the stack while the system call is blocked, it will find no reference
to the new(int) and reclaim it. If the kernel is going to write to *p once
the call finishes, reclaiming the memory is a mistake.
We can't change the arguments or the liveness information for
syscall.Syscall itself, both for compatibility and because sometimes the
arguments really are integers, and the garbage collector will get quite upset
if it finds an integer where it expects a pointer. The problem is that
these arguments are fundamentally untyped.
The solution we have taken in the syscall package's wrappers in past
releases is to insert a call to a dummy function named "use", to make
it look like the argument is live during the call to syscall.Syscall:
func h2() {
p := new(int)
syscall.Syscall(1, 2, 3, uintptr(unsafe.Pointer(p)))
use(unsafe.Pointer(p))
}
Keeping p alive during the call means that if the garbage collector
scans the stack during the system call now, it will find the reference to p.
Unfortunately, this approach is not available to users outside syscall,
because 'use' is unexported, and people also have to realize they need
to use it and do so. There is much existing code using syscall.Syscall
without a 'use'-like function. That code will fail very occasionally in
mysterious ways (see #13372).
This CL fixes all that existing code by making the compiler do the right
thing automatically, without any code modifications. That is, it takes h1
above, which is incorrect code today, and makes it correct code.
Specifically, if the compiler sees a foreign func definition (one
without a body) that has uintptr arguments, it marks those arguments
as "unsafe uintptrs". If it later sees the function being called
with uintptr(unsafe.Pointer(x)) as an argument, it arranges to mark x
as having escaped, and it makes sure to hold x in a live temporary
variable until the call returns, so that the garbage collector cannot
reclaim whatever heap memory x points to.
For now I am leaving the explicit calls to use in package syscall,
but they can be removed early in a future cycle (likely Go 1.7).
The rule has no effect on escape analysis, only on liveness analysis.
Fixes #13372.
Change-Id: I2addb83f70d08db08c64d394f9d06ff0a063c500
Reviewed-on: https://go-review.googlesource.com/18584
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-01-13 00:46:28 -05:00
|
|
|
}
|
2020-04-22 14:37:02 -07:00
|
|
|
} else {
|
cmd/compile: move fixVariadicCall from walk to order
This CL moves fixVariadicCall from mid-Walk of function calls to
early-Order, in preparation for moving it even earlier in the future.
Notably, rewriting variadic calls this early introduces two
compilation output changes:
1. Previously, Order visited the ODDDARG before the rest of the
arguments list, whereas the natural time to visit it is at the end of
the list (as we visit arguments left-to-right, and the ... argument is
the rightmost one). Changing this ordering permutes the autotmp
allocation order, which in turn permutes autotmp naming and stack
offsets.
2. Previously, Walk separately walked all of the variadic arguments
before walking the entire slice literal, whereas the more natural
thing to do is just walk the entire slice literal. This triggers
slightly different code paths for composite literal construction in
some cases.
Neither of these have semantic impact. They simply mean we're now
compiling f(a,b,c) the same way as we were already compiling
f([]T{a,b,c}...).
Change-Id: I40ccc5725697a116370111ebe746b2639562fe87
Reviewed-on: https://go-review.googlesource.com/c/go/+/229601
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2020-04-21 15:59:11 -07:00
|
|
|
keepAlive(arg)
|
2018-04-03 13:17:28 +01:00
|
|
|
}
|
cmd/compile: recognize Syscall-like functions for liveness analysis
Consider this code:
func f(*int)
func g() {
p := new(int)
f(p)
}
where f is an assembly function.
In general liveness analysis assumes that during the call to f, p is dead
in this frame. If f has retained p, p will be found alive in f's frame and keep
the new(int) from being garbage collected. This is all correct and works.
We use the Go func declaration for f to give the assembly function
liveness information (the arguments are assumed live for the entire call).
Now consider this code:
func h1() {
p := new(int)
syscall.Syscall(1, 2, 3, uintptr(unsafe.Pointer(p)))
}
Here syscall.Syscall is taking the place of f, but because its arguments
are uintptr, the liveness analysis and the garbage collector ignore them.
Since p is no longer live in h once the call starts, if the garbage collector
scans the stack while the system call is blocked, it will find no reference
to the new(int) and reclaim it. If the kernel is going to write to *p once
the call finishes, reclaiming the memory is a mistake.
We can't change the arguments or the liveness information for
syscall.Syscall itself, both for compatibility and because sometimes the
arguments really are integers, and the garbage collector will get quite upset
if it finds an integer where it expects a pointer. The problem is that
these arguments are fundamentally untyped.
The solution we have taken in the syscall package's wrappers in past
releases is to insert a call to a dummy function named "use", to make
it look like the argument is live during the call to syscall.Syscall:
func h2() {
p := new(int)
syscall.Syscall(1, 2, 3, uintptr(unsafe.Pointer(p)))
use(unsafe.Pointer(p))
}
Keeping p alive during the call means that if the garbage collector
scans the stack during the system call now, it will find the reference to p.
Unfortunately, this approach is not available to users outside syscall,
because 'use' is unexported, and people also have to realize they need
to use it and do so. There is much existing code using syscall.Syscall
without a 'use'-like function. That code will fail very occasionally in
mysterious ways (see #13372).
This CL fixes all that existing code by making the compiler do the right
thing automatically, without any code modifications. That is, it takes h1
above, which is incorrect code today, and makes it correct code.
Specifically, if the compiler sees a foreign func definition (one
without a body) that has uintptr arguments, it marks those arguments
as "unsafe uintptrs". If it later sees the function being called
with uintptr(unsafe.Pointer(x)) as an argument, it arranges to mark x
as having escaped, and it makes sure to hold x in a live temporary
variable until the call returns, so that the garbage collector cannot
reclaim whatever heap memory x points to.
For now I am leaving the explicit calls to use in package syscall,
but they can be removed early in a future cycle (likely Go 1.7).
The rule has no effect on escape analysis, only on liveness analysis.
Fixes #13372.
Change-Id: I2addb83f70d08db08c64d394f9d06ff0a063c500
Reviewed-on: https://go-review.googlesource.com/18584
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-01-13 00:46:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2021-01-03 00:16:46 -08:00
|
|
|
// mapAssign appends n to o.out.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) mapAssign(n ir.Node) {
|
2020-11-22 09:59:15 -05:00
|
|
|
switch n.Op() {
|
2015-02-13 14:40:36 -05:00
|
|
|
default:
|
2020-11-22 09:59:15 -05:00
|
|
|
base.Fatalf("order.mapAssign %v", n.Op())
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
case ir.OAS:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.AssignStmt)
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.X.Op() == ir.OINDEXMAP {
|
|
|
|
|
n.Y = o.safeMapRHS(n.Y)
|
2020-12-10 18:45:35 -05:00
|
|
|
}
|
|
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
case ir.OASOP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.AssignOpStmt)
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.X.Op() == ir.OINDEXMAP {
|
|
|
|
|
n.Y = o.safeMapRHS(n.Y)
|
2017-12-04 14:47:32 -08:00
|
|
|
}
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) safeMapRHS(r ir.Node) ir.Node {
|
2020-12-10 18:45:35 -05:00
|
|
|
// Make sure we evaluate the RHS before starting the map insert.
|
|
|
|
|
// We need to make sure the RHS won't panic. See issue 22881.
|
|
|
|
|
if r.Op() == ir.OAPPEND {
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
r := r.(*ir.CallExpr)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
s := r.Args[1:]
|
2020-12-10 18:45:35 -05:00
|
|
|
for i, n := range s {
|
|
|
|
|
s[i] = o.cheapExpr(n)
|
|
|
|
|
}
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
return o.cheapExpr(r)
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// stmt orders the statement n, appending to o.out.
|
2015-02-13 14:40:36 -05:00
|
|
|
// Temporaries created during the statement are cleaned
|
|
|
|
|
// up using VARKILL instructions as possible.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) stmt(n ir.Node) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
lno := ir.SetPos(n)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.init(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-11-22 09:59:15 -05:00
|
|
|
switch n.Op() {
|
2015-02-13 14:40:36 -05:00
|
|
|
default:
|
2020-11-22 09:59:15 -05:00
|
|
|
base.Fatalf("order.stmt %v", n.Op())
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK:
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OAS:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.AssignStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
n.Y = o.expr(n.Y, n.X)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.mapAssign(n)
|
|
|
|
|
o.cleanTemp(t)
|
cmd/internal/gc: avoid turning 'x = f()' into 'tmp = f(); x = tmp' for simple x
This slows down more things than I expected, but it also speeds things up,
and it reduces stack frame sizes and the load on the optimizer, so it's still
likely a net win.
name old mean new mean delta
BenchmarkBinaryTree17 13.2s × (0.98,1.03) 13.2s × (0.98,1.02) ~ (p=0.795)
BenchmarkFannkuch11 4.41s × (1.00,1.00) 4.45s × (0.99,1.01) +0.88% (p=0.000)
BenchmarkFmtFprintfEmpty 86.4ns × (0.99,1.01) 90.1ns × (0.95,1.05) +4.31% (p=0.000)
BenchmarkFmtFprintfString 318ns × (0.96,1.07) 337ns × (0.98,1.03) +6.05% (p=0.000)
BenchmarkFmtFprintfInt 332ns × (0.97,1.04) 320ns × (0.97,1.02) -3.42% (p=0.000)
BenchmarkFmtFprintfIntInt 562ns × (0.96,1.04) 574ns × (0.96,1.06) +2.00% (p=0.013)
BenchmarkFmtFprintfPrefixedInt 442ns × (0.96,1.06) 450ns × (0.97,1.05) +1.73% (p=0.039)
BenchmarkFmtFprintfFloat 640ns × (0.99,1.02) 659ns × (0.99,1.03) +3.01% (p=0.000)
BenchmarkFmtManyArgs 2.19µs × (0.97,1.06) 2.21µs × (0.98,1.02) ~ (p=0.104)
BenchmarkGobDecode 20.0ms × (0.98,1.03) 19.7ms × (0.97,1.04) -1.35% (p=0.035)
BenchmarkGobEncode 17.8ms × (0.96,1.04) 18.0ms × (0.96,1.06) ~ (p=0.131)
BenchmarkGzip 653ms × (0.99,1.02) 652ms × (0.99,1.01) ~ (p=0.572)
BenchmarkGunzip 143ms × (0.99,1.02) 142ms × (1.00,1.01) -0.52% (p=0.005)
BenchmarkHTTPClientServer 110µs × (0.98,1.03) 108µs × (0.99,1.02) -1.90% (p=0.000)
BenchmarkJSONEncode 40.0ms × (0.98,1.05) 41.5ms × (0.97,1.06) +3.89% (p=0.000)
BenchmarkJSONDecode 118ms × (0.99,1.01) 118ms × (0.98,1.01) +0.69% (p=0.010)
BenchmarkMandelbrot200 6.03ms × (1.00,1.01) 6.03ms × (1.00,1.01) ~ (p=0.924)
BenchmarkGoParse 8.43ms × (0.92,1.11) 8.56ms × (0.93,1.05) ~ (p=0.242)
BenchmarkRegexpMatchEasy0_32 180ns × (0.91,1.07) 163ns × (1.00,1.00) -9.33% (p=0.000)
BenchmarkRegexpMatchEasy0_1K 550ns × (0.98,1.02) 558ns × (0.99,1.01) +1.44% (p=0.000)
BenchmarkRegexpMatchEasy1_32 152ns × (0.94,1.05) 139ns × (0.98,1.02) -8.51% (p=0.000)
BenchmarkRegexpMatchEasy1_1K 909ns × (0.98,1.06) 868ns × (0.99,1.02) -4.52% (p=0.000)
BenchmarkRegexpMatchMedium_32 262ns × (0.97,1.03) 253ns × (0.99,1.02) -3.31% (p=0.000)
BenchmarkRegexpMatchMedium_1K 73.8µs × (0.98,1.04) 72.7µs × (1.00,1.01) -1.61% (p=0.001)
BenchmarkRegexpMatchHard_32 3.87µs × (0.99,1.02) 3.87µs × (1.00,1.01) ~ (p=0.791)
BenchmarkRegexpMatchHard_1K 118µs × (0.98,1.04) 117µs × (0.99,1.02) ~ (p=0.110)
BenchmarkRevcomp 1.00s × (0.94,1.10) 0.99s × (0.94,1.09) ~ (p=0.433)
BenchmarkTemplate 140ms × (0.97,1.04) 140ms × (0.99,1.01) ~ (p=0.303)
BenchmarkTimeParse 622ns × (0.99,1.02) 625ns × (0.99,1.01) +0.51% (p=0.001)
BenchmarkTimeFormat 731ns × (0.98,1.04) 719ns × (0.99,1.01) -1.66% (p=0.000)
Change-Id: Ibc3edb59a178adafda50156f46a341f69a17d83f
Reviewed-on: https://go-review.googlesource.com/9721
Reviewed-by: David Chase <drchase@google.com>
2015-04-30 20:35:47 -04:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OASOP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.AssignOpStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
n.Y = o.expr(n.Y, nil)
|
2017-08-29 15:40:32 -07:00
|
|
|
|
2020-12-23 00:05:23 -05:00
|
|
|
if base.Flag.Cfg.Instrumenting || n.X.Op() == ir.OINDEXMAP && (n.AsOp == ir.ODIV || n.AsOp == ir.OMOD) {
|
cmd/compile: avoid extra mapaccess in "m[k] op= r"
Currently, order desugars map assignment operations like
m[k] op= r
into
m[k] = m[k] op r
which in turn is transformed during walk into:
tmp := *mapaccess(m, k)
tmp = tmp op r
*mapassign(m, k) = tmp
However, this is suboptimal, as we could instead produce just:
*mapassign(m, k) op= r
One complication though is if "r == 0", then "m[k] /= r" and "m[k] %=
r" will panic, and they need to do so *before* calling mapassign,
otherwise we may insert a new zero-value element into the map.
It would be spec compliant to just emit the "r != 0" check before
calling mapassign (see #23735), but currently these checks aren't
generated until SSA construction. For now, it's simpler to continue
desugaring /= and %= into two map indexing operations.
Fixes #23661.
Change-Id: I46e3739d9adef10e92b46fdd78b88d5aabe68952
Reviewed-on: https://go-review.googlesource.com/91557
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
2018-02-01 21:33:56 -08:00
|
|
|
// Rewrite m[k] op= r into m[k] = m[k] op r so
|
|
|
|
|
// that we can ensure that if op panics
|
|
|
|
|
// because r is zero, the panic happens before
|
|
|
|
|
// the map assignment.
|
[dev.regabi] cmd/compile: clean up in preparation for statement Nodes
Using statement nodes restricts the set of valid SetOp operations,
because you can't SetOp across representation. Rewrite various
code to avoid crossing those as-yet-unintroduced boundaries.
In particular, code like
x, y := v.(T)
x, y := f()
x, y := m[k]
x, y := <-c
starts out with Op = OAS2, and then it turns into a specific Op
OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV, and then
later in walk is lowered to an OAS2 again.
In the middle, the specific forms move the right-hand side from
n.Rlist().First() to n.Right(), and then the conversion to OAS2 moves
it back. This is unnecessary and makes it hard for these all to
share an underlying Node implementation.
This CL changes these specific forms to leave the right-hand side
in n.Rlist().First().
Similarly, OSELRECV2 is really just a temporary form of OAS2.
This CL changes it to use same fields too.
Finally, this CL fixes the printing of OAS2 nodes in ir/fmt.go,
which formerly printed n.Right() instead of n.Rlist().
This results in a (correct!) update to cmd/compile/internal/logopt's
expected output: ~R0 = <N> becomes ~R0 = &y.b.
Passes buildall w/ toolstash -cmp.
Change-Id: I164aa2e17dc55bfb292024de53d7d250192ad64a
Reviewed-on: https://go-review.googlesource.com/c/go/+/274105
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-28 15:28:18 -05:00
|
|
|
// DeepCopy is a big hammer here, but safeExpr
|
|
|
|
|
// makes sure there is nothing too deep being copied.
|
2020-12-23 00:02:08 -05:00
|
|
|
l1 := o.safeExpr(n.X)
|
[dev.regabi] cmd/compile: clean up in preparation for statement Nodes
Using statement nodes restricts the set of valid SetOp operations,
because you can't SetOp across representation. Rewrite various
code to avoid crossing those as-yet-unintroduced boundaries.
In particular, code like
x, y := v.(T)
x, y := f()
x, y := m[k]
x, y := <-c
starts out with Op = OAS2, and then it turns into a specific Op
OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV, and then
later in walk is lowered to an OAS2 again.
In the middle, the specific forms move the right-hand side from
n.Rlist().First() to n.Right(), and then the conversion to OAS2 moves
it back. This is unnecessary and makes it hard for these all to
share an underlying Node implementation.
This CL changes these specific forms to leave the right-hand side
in n.Rlist().First().
Similarly, OSELRECV2 is really just a temporary form of OAS2.
This CL changes it to use same fields too.
Finally, this CL fixes the printing of OAS2 nodes in ir/fmt.go,
which formerly printed n.Right() instead of n.Rlist().
This results in a (correct!) update to cmd/compile/internal/logopt's
expected output: ~R0 = <N> becomes ~R0 = &y.b.
Passes buildall w/ toolstash -cmp.
Change-Id: I164aa2e17dc55bfb292024de53d7d250192ad64a
Reviewed-on: https://go-review.googlesource.com/c/go/+/274105
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-28 15:28:18 -05:00
|
|
|
l2 := ir.DeepCopy(src.NoXPos, l1)
|
2020-12-10 18:45:35 -05:00
|
|
|
if l2.Op() == ir.OINDEXMAP {
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
l2 := l2.(*ir.IndexExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
l2.Assigned = false
|
cmd/compile: avoid extra mapaccess in "m[k] op= r"
Currently, order desugars map assignment operations like
m[k] op= r
into
m[k] = m[k] op r
which in turn is transformed during walk into:
tmp := *mapaccess(m, k)
tmp = tmp op r
*mapassign(m, k) = tmp
However, this is suboptimal, as we could instead produce just:
*mapassign(m, k) op= r
One complication though is if "r == 0", then "m[k] /= r" and "m[k] %=
r" will panic, and they need to do so *before* calling mapassign,
otherwise we may insert a new zero-value element into the map.
It would be spec compliant to just emit the "r != 0" check before
calling mapassign (see #23735), but currently these checks aren't
generated until SSA construction. For now, it's simpler to continue
desugaring /= and %= into two map indexing operations.
Fixes #23661.
Change-Id: I46e3739d9adef10e92b46fdd78b88d5aabe68952
Reviewed-on: https://go-review.googlesource.com/91557
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
2018-02-01 21:33:56 -08:00
|
|
|
}
|
2020-11-29 11:16:20 -05:00
|
|
|
l2 = o.copyExpr(l2)
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
r := o.expr(typecheck.Expr(ir.NewBinaryExpr(n.Pos(), n.AsOp, l2, n.Y)), nil)
|
|
|
|
|
as := typecheck.Stmt(ir.NewAssignStmt(n.Pos(), l1, r))
|
2020-12-10 18:45:35 -05:00
|
|
|
o.mapAssign(as)
|
|
|
|
|
o.cleanTemp(t)
|
|
|
|
|
return
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: avoid extra mapaccess in "m[k] op= r"
Currently, order desugars map assignment operations like
m[k] op= r
into
m[k] = m[k] op r
which in turn is transformed during walk into:
tmp := *mapaccess(m, k)
tmp = tmp op r
*mapassign(m, k) = tmp
However, this is suboptimal, as we could instead produce just:
*mapassign(m, k) op= r
One complication though is if "r == 0", then "m[k] /= r" and "m[k] %=
r" will panic, and they need to do so *before* calling mapassign,
otherwise we may insert a new zero-value element into the map.
It would be spec compliant to just emit the "r != 0" check before
calling mapassign (see #23735), but currently these checks aren't
generated until SSA construction. For now, it's simpler to continue
desugaring /= and %= into two map indexing operations.
Fixes #23661.
Change-Id: I46e3739d9adef10e92b46fdd78b88d5aabe68952
Reviewed-on: https://go-review.googlesource.com/91557
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
2018-02-01 21:33:56 -08:00
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
o.mapAssign(n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OAS2:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.AssignListStmt)
|
2019-10-12 08:47:51 +07:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.Lhs)
|
|
|
|
|
o.exprList(n.Rhs)
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
o.out = append(o.out, n)
|
2019-10-12 08:47:51 +07:00
|
|
|
o.cleanTemp(t)
|
|
|
|
|
|
2019-10-12 02:43:29 +07:00
|
|
|
// Special: avoid copy of func call n.Right
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OAS2FUNC:
|
2020-12-10 18:45:35 -05:00
|
|
|
n := n.(*ir.AssignListStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.Lhs)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
o.init(n.Rhs[0])
|
|
|
|
|
o.call(n.Rhs[0])
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
o.as2func(n)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Special: use temporary variables to hold result,
|
2019-10-12 02:43:29 +07:00
|
|
|
// so that runtime can take address of temporary.
|
2015-02-13 14:40:36 -05:00
|
|
|
// No temporary for blank assignment.
|
2019-10-12 02:43:29 +07:00
|
|
|
//
|
|
|
|
|
// OAS2MAPR: make sure key is addressable if needed,
|
|
|
|
|
// and make sure OINDEXMAP is not copied out.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OAS2MAPR:
|
2020-12-10 18:45:35 -05:00
|
|
|
n := n.(*ir.AssignListStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.Lhs)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
switch r := n.Rhs[0]; r.Op() {
|
2020-12-10 18:45:35 -05:00
|
|
|
case ir.ODOTTYPE2:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
r := r.(*ir.TypeAssertExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
r.X = o.expr(r.X, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
case ir.ORECV:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
r := r.(*ir.UnaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
r.X = o.expr(r.X, nil)
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OINDEXMAP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
r := r.(*ir.IndexExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
r.X = o.expr(r.X, nil)
|
|
|
|
|
r.Index = o.expr(r.Index, nil)
|
2019-10-12 02:43:29 +07:00
|
|
|
// See similar conversion for OINDEXMAP below.
|
2020-12-23 00:02:08 -05:00
|
|
|
_ = mapKeyReplaceStrConv(r.Index)
|
|
|
|
|
r.Index = o.mapKeyTemp(r.X.Type(), r.Index)
|
2019-10-12 02:43:29 +07:00
|
|
|
default:
|
2020-11-22 09:59:15 -05:00
|
|
|
base.Fatalf("order.stmt: %v", r.Op())
|
2019-10-12 02:43:29 +07:00
|
|
|
}
|
|
|
|
|
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
o.as2ok(n)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Special: does not save n onto out.
|
2020-11-30 21:56:24 -05:00
|
|
|
case ir.OBLOCK:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.BlockStmt)
|
2020-12-23 00:02:08 -05:00
|
|
|
o.stmtList(n.List)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Special: n->left is not an expression; save as is.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OBREAK,
|
|
|
|
|
ir.OCONTINUE,
|
|
|
|
|
ir.ODCL,
|
|
|
|
|
ir.ODCLCONST,
|
|
|
|
|
ir.ODCLTYPE,
|
|
|
|
|
ir.OFALL,
|
|
|
|
|
ir.OGOTO,
|
|
|
|
|
ir.OLABEL,
|
2021-01-17 00:30:32 -08:00
|
|
|
ir.OTAILCALL:
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Special: handle call arguments.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.CallExpr)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
|
|
|
|
o.call(n)
|
|
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
case ir.OCLOSE, ir.ORECV:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.UnaryExpr)
|
2020-12-10 18:45:35 -05:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
|
|
|
|
|
|
|
|
|
case ir.OCOPY:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.BinaryExpr)
|
2019-10-12 08:47:51 +07:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
n.Y = o.expr(n.Y, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
|
|
|
|
|
|
|
|
|
case ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.CallExpr)
|
2020-12-10 18:45:35 -05:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.Args)
|
2019-10-12 08:47:51 +07:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
|
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Special: order arguments to inner call but not call itself.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ODEFER, ir.OGO:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.GoDeferStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
o.init(n.Call)
|
|
|
|
|
o.call(n.Call)
|
2021-03-25 13:24:16 -04:00
|
|
|
if n.Call.Op() == ir.ORECOVER {
|
|
|
|
|
// Special handling of "defer recover()". We need to evaluate the FP
|
|
|
|
|
// argument before wrapping.
|
|
|
|
|
var init ir.Nodes
|
|
|
|
|
n.Call = walkRecover(n.Call.(*ir.CallExpr), &init)
|
|
|
|
|
o.stmtList(init)
|
|
|
|
|
}
|
2021-02-24 12:55:52 -05:00
|
|
|
if objabi.Experiment.RegabiDefer {
|
|
|
|
|
o.wrapGoDefer(n)
|
|
|
|
|
}
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ODELETE:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.CallExpr)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
n.Args[0] = o.expr(n.Args[0], nil)
|
|
|
|
|
n.Args[1] = o.expr(n.Args[1], nil)
|
|
|
|
|
n.Args[1] = o.mapKeyTemp(n.Args[0].Type(), n.Args[1])
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Clean temporaries from condition evaluation at
|
2015-02-13 14:40:36 -05:00
|
|
|
// beginning of loop body and after for statement.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OFOR:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.ForStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Cond = o.exprInPlace(n.Cond)
|
|
|
|
|
n.Body.Prepend(o.cleanTempNoPop(t)...)
|
|
|
|
|
orderBlock(&n.Body, o.free)
|
|
|
|
|
n.Post = orderStmtInPlace(n.Post, o.free)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Clean temporaries from condition at
|
2015-02-13 14:40:36 -05:00
|
|
|
// beginning of both branches.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OIF:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.IfStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Cond = o.exprInPlace(n.Cond)
|
|
|
|
|
n.Body.Prepend(o.cleanTempNoPop(t)...)
|
|
|
|
|
n.Else.Prepend(o.cleanTempNoPop(t)...)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.popTemp(t)
|
2020-12-23 00:02:08 -05:00
|
|
|
orderBlock(&n.Body, o.free)
|
|
|
|
|
orderBlock(&n.Else, o.free)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OPANIC:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.UnaryExpr)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
[dev.regabi] cmd/compile: convert OPANIC argument to interface{} during typecheck
Currently, typecheck leaves arguments to OPANIC as their original
type. This CL changes it to insert implicit OCONVIFACE operations to
convert arguments to `interface{}` like how any other function call
would be handled.
No immediate benefits, other than getting to remove a tiny bit of
special-case logic in order.go's handling of OPANICs. Instead, the
generic code path for handling OCONVIFACE is used, if necessary.
Longer term, this should be marginally helpful for #43753, as it
reduces the number of cases where we need values to be addressable for
runtime calls.
However, this does require adding some hacks to appease existing
tests:
1. We need yet another kludge in inline budgeting, to ensure that
reflect.flag.mustBe stays inlinable for cmd/compile/internal/test's
TestIntendedInlining.
2. Since the OCONVIFACE expressions are now being introduced during
typecheck, they're now visible to escape analysis. So expressions like
"panic(1)" are now seen as "panic(interface{}(1))", and escape
analysis warns that the "interface{}(1)" escapes to the heap. These
have always escaped to heap, just now we're accurately reporting about
it.
(Also, unfortunately fmt.go hides implicit conversions by default in
diagnostics messages, so instead of reporting "interface{}(1) escapes
to heap", it actually reports "1 escapes to heap", which is
confusing. However, this confusing messaging also isn't new.)
Change-Id: Icedf60e1d2e464e219441b8d1233a313770272af
Reviewed-on: https://go-review.googlesource.com/c/go/+/284412
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Trust: Matthew Dempsky <mdempsky@google.com>
2021-01-17 16:14:48 -08:00
|
|
|
if !n.X.Type().IsEmptyInterface() {
|
|
|
|
|
base.FatalfAt(n.Pos(), "bad argument to panic: %L", n.X)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ORANGE:
|
2016-03-25 21:11:33 -07:00
|
|
|
// n.Right is the expression being ranged over.
|
|
|
|
|
// order it, and then make a copy if we need one.
|
|
|
|
|
// We almost always do, to ensure that we don't
|
|
|
|
|
// see any value changes made during the loop.
|
|
|
|
|
// Usually the copy is cheap (e.g., array pointer,
|
|
|
|
|
// chan, slice, string are all tiny).
|
|
|
|
|
// The exception is ranging over an array value
|
|
|
|
|
// (not a slice, not a pointer to array),
|
|
|
|
|
// which must make a copy to avoid seeing updates made during
|
|
|
|
|
// the range body. Ranging over an array value is uncommon though.
|
|
|
|
|
|
|
|
|
|
// Mark []byte(str) range expression to reuse string backing storage.
|
|
|
|
|
// It is safe because the storage cannot be mutated.
|
2020-12-10 18:45:35 -05:00
|
|
|
n := n.(*ir.RangeStmt)
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.X.Op() == ir.OSTR2BYTES {
|
|
|
|
|
n.X.(*ir.ConvExpr).SetOp(ir.OSTR2BYTESTMP)
|
2016-03-25 21:11:33 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2018-04-27 21:58:59 +02:00
|
|
|
|
|
|
|
|
orderBody := true
|
2020-12-24 18:49:35 +07:00
|
|
|
xt := typecheck.RangeExprType(n.X.Type())
|
|
|
|
|
switch xt.Kind() {
|
2015-02-13 14:40:36 -05:00
|
|
|
default:
|
2020-11-22 09:59:15 -05:00
|
|
|
base.Fatalf("order.stmt range %v", n.Type())
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case types.TARRAY, types.TSLICE:
|
2020-12-24 13:09:20 +07:00
|
|
|
if n.Value == nil || ir.IsBlank(n.Value) {
|
2015-02-13 14:40:36 -05:00
|
|
|
// for i := range x will only use x once, to compute len(x).
|
|
|
|
|
// No need to copy it.
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
fallthrough
|
|
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case types.TCHAN, types.TSTRING:
|
2016-03-25 21:11:33 -07:00
|
|
|
// chan, string, slice, array ranges use value multiple times.
|
|
|
|
|
// make copy.
|
2020-12-23 00:02:08 -05:00
|
|
|
r := n.X
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-11-22 09:59:15 -05:00
|
|
|
if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] {
|
[dev.regabi] cmd/compile: remove ir.Nod [generated]
Rewrite all uses of ir.Nod and friends to call the IR constructors directly.
This gives the results a more specific type and will play nicely with
introduction of more specific types throughout the code in a followup CL.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/compile/internal/syntax"
import "cmd/internal/src"
var p *noder
var orig syntax.Node
var op ir.Op
var l, r ir.Node
var sym *types.Sym
p.nod(orig, op, l, r) -> ir.NodAt(p.pos(orig), op, l, r)
p.nodSym(orig, op, l, sym) -> nodlSym(p.pos(orig), op, l, sym)
var xpos src.XPos
var ns ir.Nodes
npos(xpos, nodSym(op, l, sym)) -> nodlSym(xpos, op, l, sym)
npos(xpos, liststmt(ns)) -> ir.NewBlockStmt(xpos, ns)
}
ex . ../ir {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
var op ir.Op
var l, r ir.Node
ir.Nod(op, l, r) -> ir.NodAt(base.Pos, op, l, r)
var sym *types.Sym
nodSym(op, l, sym) -> nodlSym(base.Pos, op, l, sym)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/internal/src"
# rf overlapping match handling is not quite good enough
# for certain nested rewrites, so handle these two - which often contain other ir.NodAt calls - early.
var l, r ir.Node
var xpos src.XPos
ir.NodAt(xpos, ir.OAS, l, r) -> ir.NewAssignStmt(xpos, l, r)
ir.NodAt(xpos, ir.OIF, l, nil) -> ir.NewIfStmt(xpos, l, nil, nil)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var l, r ir.Node
var sym *types.Sym
var xpos src.XPos
nodlSym(xpos, ir.ODOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, sym)
nodlSym(xpos, ir.OXDOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, sym)
nodlSym(xpos, ir.ODOTPTR, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, sym)
nodlSym(xpos, ir.OGOTO, nil, sym) -> ir.NewBranchStmt(xpos, ir.OGOTO, sym)
nodlSym(xpos, ir.ORETJMP, nil, sym) -> ir.NewBranchStmt(xpos, ir.ORETJMP, sym)
nodlSym(xpos, ir.OLABEL, nil, sym) -> ir.NewLabelStmt(xpos, sym)
nodlSym(xpos, ir.OSTRUCTKEY, l, sym) -> ir.NewStructKeyExpr(xpos, sym, l)
ir.NodAt(xpos, ir.OADD, l, r) -> ir.NewBinaryExpr(xpos, ir.OADD, l, r)
ir.NodAt(xpos, ir.OAND, l, r) -> ir.NewBinaryExpr(xpos, ir.OAND, l, r)
ir.NodAt(xpos, ir.OANDNOT, l, r) -> ir.NewBinaryExpr(xpos, ir.OANDNOT, l, r)
ir.NodAt(xpos, ir.ODIV, l, r) -> ir.NewBinaryExpr(xpos, ir.ODIV, l, r)
ir.NodAt(xpos, ir.OEQ, l, r) -> ir.NewBinaryExpr(xpos, ir.OEQ, l, r)
ir.NodAt(xpos, ir.OGE, l, r) -> ir.NewBinaryExpr(xpos, ir.OGE, l, r)
ir.NodAt(xpos, ir.OGT, l, r) -> ir.NewBinaryExpr(xpos, ir.OGT, l, r)
ir.NodAt(xpos, ir.OLE, l, r) -> ir.NewBinaryExpr(xpos, ir.OLE, l, r)
ir.NodAt(xpos, ir.OLSH, l, r) -> ir.NewBinaryExpr(xpos, ir.OLSH, l, r)
ir.NodAt(xpos, ir.OLT, l, r) -> ir.NewBinaryExpr(xpos, ir.OLT, l, r)
ir.NodAt(xpos, ir.OMOD, l, r) -> ir.NewBinaryExpr(xpos, ir.OMOD, l, r)
ir.NodAt(xpos, ir.OMUL, l, r) -> ir.NewBinaryExpr(xpos, ir.OMUL, l, r)
ir.NodAt(xpos, ir.ONE, l, r) -> ir.NewBinaryExpr(xpos, ir.ONE, l, r)
ir.NodAt(xpos, ir.OOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OOR, l, r)
ir.NodAt(xpos, ir.ORSH, l, r) -> ir.NewBinaryExpr(xpos, ir.ORSH, l, r)
ir.NodAt(xpos, ir.OSUB, l, r) -> ir.NewBinaryExpr(xpos, ir.OSUB, l, r)
ir.NodAt(xpos, ir.OXOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OXOR, l, r)
ir.NodAt(xpos, ir.OCOPY, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOPY, l, r)
ir.NodAt(xpos, ir.OCOMPLEX, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOMPLEX, l, r)
ir.NodAt(xpos, ir.OEFACE, l, r) -> ir.NewBinaryExpr(xpos, ir.OEFACE, l, r)
ir.NodAt(xpos, ir.OADDR, l, nil) -> ir.NewAddrExpr(xpos, l)
ir.NodAt(xpos, ir.OADDSTR, nil, nil) -> ir.NewAddStringExpr(xpos, nil)
ir.NodAt(xpos, ir.OANDAND, l, r) -> ir.NewLogicalExpr(xpos, ir.OANDAND, l, r)
ir.NodAt(xpos, ir.OOROR, l, r) -> ir.NewLogicalExpr(xpos, ir.OOROR, l, r)
ir.NodAt(xpos, ir.OARRAYLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, nil, nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, nil, nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, nil, nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, nil, nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, nil, nil)
ir.NodAt(xpos, ir.OARRAYLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OAS2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2, nil, nil)
ir.NodAt(xpos, ir.OAS2DOTTYPE, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2DOTTYPE, nil, nil)
ir.NodAt(xpos, ir.OAS2FUNC, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2FUNC, nil, nil)
ir.NodAt(xpos, ir.OAS2MAPR, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2MAPR, nil, nil)
ir.NodAt(xpos, ir.OAS2RECV, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2RECV, nil, nil)
ir.NodAt(xpos, ir.OSELRECV2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OSELRECV2, nil, nil)
ir.NodAt(xpos, ir.OASOP, l, r) -> ir.NewAssignOpStmt(xpos, ir.OXXX, l, r)
ir.NodAt(xpos, ir.OBITNOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.OBITNOT, l)
ir.NodAt(xpos, ir.ONEG, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEG, l)
ir.NodAt(xpos, ir.ONOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONOT, l)
ir.NodAt(xpos, ir.OPLUS, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPLUS, l)
ir.NodAt(xpos, ir.ORECV, l, nil) -> ir.NewUnaryExpr(xpos, ir.ORECV, l)
ir.NodAt(xpos, ir.OALIGNOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OALIGNOF, l)
ir.NodAt(xpos, ir.OCAP, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCAP, l)
ir.NodAt(xpos, ir.OCLOSE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCLOSE, l)
ir.NodAt(xpos, ir.OIMAG, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIMAG, l)
ir.NodAt(xpos, ir.OLEN, l, nil) -> ir.NewUnaryExpr(xpos, ir.OLEN, l)
ir.NodAt(xpos, ir.ONEW, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEW, l)
ir.NodAt(xpos, ir.ONEWOBJ, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEWOBJ, l)
ir.NodAt(xpos, ir.OOFFSETOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OOFFSETOF, l)
ir.NodAt(xpos, ir.OPANIC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPANIC, l)
ir.NodAt(xpos, ir.OREAL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OREAL, l)
ir.NodAt(xpos, ir.OSIZEOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSIZEOF, l)
ir.NodAt(xpos, ir.OCHECKNIL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCHECKNIL, l)
ir.NodAt(xpos, ir.OCFUNC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCFUNC, l)
ir.NodAt(xpos, ir.OIDATA, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIDATA, l)
ir.NodAt(xpos, ir.OITAB, l, nil) -> ir.NewUnaryExpr(xpos, ir.OITAB, l)
ir.NodAt(xpos, ir.OSPTR, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSPTR, l)
ir.NodAt(xpos, ir.OVARDEF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARDEF, l)
ir.NodAt(xpos, ir.OVARKILL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARKILL, l)
ir.NodAt(xpos, ir.OVARLIVE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARLIVE, l)
ir.NodAt(xpos, ir.OBLOCK, nil, nil) -> ir.NewBlockStmt(xpos, nil)
ir.NodAt(xpos, ir.OBREAK, nil, nil) -> ir.NewBranchStmt(xpos, ir.OBREAK, nil)
ir.NodAt(xpos, ir.OCONTINUE, nil, nil) -> ir.NewBranchStmt(xpos, ir.OCONTINUE, nil)
ir.NodAt(xpos, ir.OFALL, nil, nil) -> ir.NewBranchStmt(xpos, ir.OFALL, nil)
ir.NodAt(xpos, ir.OGOTO, nil, nil) -> ir.NewBranchStmt(xpos, ir.OGOTO, nil)
ir.NodAt(xpos, ir.ORETJMP, nil, nil) -> ir.NewBranchStmt(xpos, ir.ORETJMP, nil)
ir.NodAt(xpos, ir.OCALL, l, nil) -> ir.NewCallExpr(xpos, ir.OCALL, l, nil)
ir.NodAt(xpos, ir.OCALLFUNC, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLFUNC, l, nil)
ir.NodAt(xpos, ir.OCALLINTER, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLINTER, l, nil)
ir.NodAt(xpos, ir.OCALLMETH, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLMETH, l, nil)
ir.NodAt(xpos, ir.OAPPEND, l, nil) -> ir.NewCallExpr(xpos, ir.OAPPEND, l, nil)
ir.NodAt(xpos, ir.ODELETE, l, nil) -> ir.NewCallExpr(xpos, ir.ODELETE, l, nil)
ir.NodAt(xpos, ir.OGETG, l, nil) -> ir.NewCallExpr(xpos, ir.OGETG, l, nil)
ir.NodAt(xpos, ir.OMAKE, l, nil) -> ir.NewCallExpr(xpos, ir.OMAKE, l, nil)
ir.NodAt(xpos, ir.OPRINT, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINT, l, nil)
ir.NodAt(xpos, ir.OPRINTN, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINTN, l, nil)
ir.NodAt(xpos, ir.ORECOVER, l, nil) -> ir.NewCallExpr(xpos, ir.ORECOVER, l, nil)
ir.NodAt(xpos, ir.OCASE, nil, nil) -> ir.NewCaseStmt(xpos, nil, nil)
ir.NodAt(xpos, ir.OCONV, l, nil) -> ir.NewConvExpr(xpos, ir.OCONV, nil, l)
ir.NodAt(xpos, ir.OCONVIFACE, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVIFACE, nil, l)
ir.NodAt(xpos, ir.OCONVNOP, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVNOP, nil, l)
ir.NodAt(xpos, ir.ORUNESTR, l, nil) -> ir.NewConvExpr(xpos, ir.ORUNESTR, nil, l)
ir.NodAt(xpos, ir.ODCL, l, nil) -> ir.NewDecl(xpos, ir.ODCL, l)
ir.NodAt(xpos, ir.ODCLCONST, l, nil) -> ir.NewDecl(xpos, ir.ODCLCONST, l)
ir.NodAt(xpos, ir.ODCLTYPE, l, nil) -> ir.NewDecl(xpos, ir.ODCLTYPE, l)
ir.NodAt(xpos, ir.ODCLFUNC, nil, nil) -> ir.NewFunc(xpos)
ir.NodAt(xpos, ir.ODEFER, l, nil) -> ir.NewGoDeferStmt(xpos, ir.ODEFER, l)
ir.NodAt(xpos, ir.OGO, l, nil) -> ir.NewGoDeferStmt(xpos, ir.OGO, l)
ir.NodAt(xpos, ir.ODEREF, l, nil) -> ir.NewStarExpr(xpos, l)
ir.NodAt(xpos, ir.ODOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, nil)
ir.NodAt(xpos, ir.ODOTPTR, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, nil)
ir.NodAt(xpos, ir.ODOTMETH, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTMETH, l, nil)
ir.NodAt(xpos, ir.ODOTINTER, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTINTER, l, nil)
ir.NodAt(xpos, ir.OXDOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, nil) -> ir.NewTypeAssertExpr(xpos, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, r) -> ir.NewTypeAssertExpr(xpos, l, r.(ir.Ntype))
ir.NodAt(xpos, ir.OFOR, l, r) -> ir.NewForStmt(xpos, nil, l, r, nil)
ir.NodAt(xpos, ir.OINDEX, l, r) -> ir.NewIndexExpr(xpos, l, r)
ir.NodAt(xpos, ir.OINLMARK, nil, nil) -> ir.NewInlineMarkStmt(xpos, types.BADWIDTH)
ir.NodAt(xpos, ir.OKEY, l, r) -> ir.NewKeyExpr(xpos, l, r)
ir.NodAt(xpos, ir.OLABEL, nil, nil) -> ir.NewLabelStmt(xpos, nil)
ir.NodAt(xpos, ir.OMAKECHAN, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKECHAN, l, r)
ir.NodAt(xpos, ir.OMAKEMAP, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKEMAP, l, r)
ir.NodAt(xpos, ir.OMAKESLICE, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICE, l, r)
ir.NodAt(xpos, ir.OMAKESLICECOPY, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICECOPY, l, r)
ir.NodAt(xpos, ir.ONIL, nil, nil) -> ir.NewNilExpr(xpos)
ir.NodAt(xpos, ir.OPACK, nil, nil) -> ir.NewPkgName(xpos, nil, nil)
ir.NodAt(xpos, ir.OPAREN, l, nil) -> ir.NewParenExpr(xpos, l)
ir.NodAt(xpos, ir.ORANGE, nil, r) -> ir.NewRangeStmt(xpos, nil, r, nil)
ir.NodAt(xpos, ir.ORESULT, nil, nil) -> ir.NewResultExpr(xpos, nil, types.BADWIDTH)
ir.NodAt(xpos, ir.ORETURN, nil, nil) -> ir.NewReturnStmt(xpos, nil)
ir.NodAt(xpos, ir.OSELECT, nil, nil) -> ir.NewSelectStmt(xpos, nil)
ir.NodAt(xpos, ir.OSEND, l, r) -> ir.NewSendStmt(xpos, l, r)
ir.NodAt(xpos, ir.OSLICE, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE, l)
ir.NodAt(xpos, ir.OSLICEARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICEARR, l)
ir.NodAt(xpos, ir.OSLICESTR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICESTR, l)
ir.NodAt(xpos, ir.OSLICE3, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3, l)
ir.NodAt(xpos, ir.OSLICE3ARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3ARR, l)
ir.NodAt(xpos, ir.OSLICEHEADER, l, nil) -> ir.NewSliceHeaderExpr(xpos, nil, l, nil, nil)
ir.NodAt(xpos, ir.OSWITCH, l, nil) -> ir.NewSwitchStmt(xpos, l, nil)
ir.NodAt(xpos, ir.OINLCALL, nil, nil) -> ir.NewInlinedCallExpr(xpos, nil, nil)
}
rm noder.nod noder.nodSym nodSym nodlSym ir.NodAt ir.Nod
'
Change-Id: Ibf1eb708de8463ae74ccc47d7966cc263a18295e
Reviewed-on: https://go-review.googlesource.com/c/go/+/277933
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:55:29 -05:00
|
|
|
r = ir.NewConvExpr(base.Pos, ir.OCONV, nil, r)
|
2020-11-22 09:59:15 -05:00
|
|
|
r.SetType(types.Types[types.TSTRING])
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
r = typecheck.Expr(r)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.copyExpr(r)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case types.TMAP:
|
2018-04-27 21:58:59 +02:00
|
|
|
if isMapClear(n) {
|
|
|
|
|
// Preserve the body of the map clear pattern so it can
|
|
|
|
|
// be detected during walk. The loop body will not be used
|
|
|
|
|
// when optimizing away the range loop to a runtime call.
|
|
|
|
|
orderBody = false
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-25 21:11:33 -07:00
|
|
|
// copy the map value in case it is a map literal.
|
|
|
|
|
// TODO(rsc): Make tmp = literal expressions reuse tmp.
|
|
|
|
|
// For maps tmp is just one word so it hardly matters.
|
2020-12-23 00:02:08 -05:00
|
|
|
r := n.X
|
|
|
|
|
n.X = o.copyExpr(r)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-12-17 08:49:22 -05:00
|
|
|
// n.Prealloc is the temp for the iterator.
|
2021-01-15 14:12:35 -08:00
|
|
|
// MapIterType contains pointers and needs to be zeroed.
|
2020-12-24 18:49:35 +07:00
|
|
|
n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-24 13:09:20 +07:00
|
|
|
n.Key = o.exprInPlace(n.Key)
|
|
|
|
|
n.Value = o.exprInPlace(n.Value)
|
2018-04-27 21:58:59 +02:00
|
|
|
if orderBody {
|
2020-12-23 00:02:08 -05:00
|
|
|
orderBlock(&n.Body, o.free)
|
2018-04-27 21:58:59 +02:00
|
|
|
}
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ORETURN:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.ReturnStmt)
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.Results)
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// Special: clean case temporaries in each block entry.
|
2015-02-13 14:40:36 -05:00
|
|
|
// Select must enter one of its blocks, so there is no
|
|
|
|
|
// need for a cleaning at the end.
|
|
|
|
|
// Doubly special: evaluation order for select is stricter
|
|
|
|
|
// than ordinary expressions. Even something like p.c
|
|
|
|
|
// has to be hoisted into a temporary, so that it cannot be
|
|
|
|
|
// reordered after the channel evaluation for a different
|
|
|
|
|
// case (if p were nil, then the timing of the fault would
|
|
|
|
|
// give this away).
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OSELECT:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.SelectStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, ncas := range n.Cases {
|
2020-12-23 00:02:08 -05:00
|
|
|
r := ncas.Comm
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
ir.SetPos(ncas)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// Append any new body prologue to ninit.
|
|
|
|
|
// The next loop will insert ninit into nbody.
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
if len(ncas.Init()) != 0 {
|
2020-11-19 20:49:23 -05:00
|
|
|
base.Fatalf("order select ninit")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2018-04-03 13:17:28 +01:00
|
|
|
if r == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2020-11-22 09:59:15 -05:00
|
|
|
switch r.Op() {
|
2018-04-03 13:17:28 +01:00
|
|
|
default:
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
ir.Dump("select case", r)
|
2020-11-22 09:59:15 -05:00
|
|
|
base.Fatalf("unknown op in select %v", r.Op())
|
2018-04-03 13:17:28 +01:00
|
|
|
|
2020-12-07 03:24:04 +07:00
|
|
|
case ir.OSELRECV2:
|
|
|
|
|
// case x, ok = <-c
|
2020-12-18 11:29:49 -05:00
|
|
|
r := r.(*ir.AssignListStmt)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
recv := r.Rhs[0].(*ir.UnaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
recv.X = o.expr(recv.X, nil)
|
|
|
|
|
if !ir.IsAutoTmp(recv.X) {
|
|
|
|
|
recv.X = o.copyExpr(recv.X)
|
2018-04-03 13:17:28 +01:00
|
|
|
}
|
2021-01-02 01:04:19 -08:00
|
|
|
init := ir.TakeInit(r)
|
2020-12-07 03:24:04 +07:00
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
colas := r.Def
|
2020-12-07 03:24:04 +07:00
|
|
|
do := func(i int, t *types.Type) {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
n := r.Lhs[i]
|
2020-12-07 03:24:04 +07:00
|
|
|
if ir.IsBlank(n) {
|
|
|
|
|
return
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-07 03:24:04 +07:00
|
|
|
// If this is case x := <-ch or case x, y := <-ch, the case has
|
|
|
|
|
// the ODCL nodes to declare x and y. We want to delay that
|
|
|
|
|
// declaration (and possible allocation) until inside the case body.
|
|
|
|
|
// Delete the ODCL nodes here and recreate them inside the body below.
|
|
|
|
|
if colas {
|
2020-12-23 00:02:08 -05:00
|
|
|
if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
|
2020-12-07 03:24:04 +07:00
|
|
|
init = init[1:]
|
|
|
|
|
}
|
2020-12-30 02:46:25 +07:00
|
|
|
dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
|
2020-12-07 03:24:04 +07:00
|
|
|
ncas.PtrInit().Append(dcl)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-07 03:24:04 +07:00
|
|
|
tmp := o.newTemp(t, t.HasPointers())
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, n, typecheck.Conv(tmp, n.Type())))
|
2020-12-07 03:24:04 +07:00
|
|
|
ncas.PtrInit().Append(as)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
r.Lhs[i] = tmp
|
[dev.regabi] cmd/compile: clean up in preparation for statement Nodes
Using statement nodes restricts the set of valid SetOp operations,
because you can't SetOp across representation. Rewrite various
code to avoid crossing those as-yet-unintroduced boundaries.
In particular, code like
x, y := v.(T)
x, y := f()
x, y := m[k]
x, y := <-c
starts out with Op = OAS2, and then it turns into a specific Op
OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV, and then
later in walk is lowered to an OAS2 again.
In the middle, the specific forms move the right-hand side from
n.Rlist().First() to n.Right(), and then the conversion to OAS2 moves
it back. This is unnecessary and makes it hard for these all to
share an underlying Node implementation.
This CL changes these specific forms to leave the right-hand side
in n.Rlist().First().
Similarly, OSELRECV2 is really just a temporary form of OAS2.
This CL changes it to use same fields too.
Finally, this CL fixes the printing of OAS2 nodes in ir/fmt.go,
which formerly printed n.Right() instead of n.Rlist().
This results in a (correct!) update to cmd/compile/internal/logopt's
expected output: ~R0 = <N> becomes ~R0 = &y.b.
Passes buildall w/ toolstash -cmp.
Change-Id: I164aa2e17dc55bfb292024de53d7d250192ad64a
Reviewed-on: https://go-review.googlesource.com/c/go/+/274105
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-28 15:28:18 -05:00
|
|
|
}
|
2020-12-23 00:02:08 -05:00
|
|
|
do(0, recv.X.Type().Elem())
|
2020-12-07 03:24:04 +07:00
|
|
|
do(1, types.Types[types.TBOOL])
|
|
|
|
|
if len(init) != 0 {
|
|
|
|
|
ir.DumpList("ninit", r.Init())
|
|
|
|
|
base.Fatalf("ninit on select recv")
|
2018-04-03 13:17:28 +01:00
|
|
|
}
|
2020-12-07 03:24:04 +07:00
|
|
|
orderBlock(ncas.PtrInit(), o.free)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OSEND:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
r := r.(*ir.SendStmt)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
if len(r.Init()) != 0 {
|
2020-11-22 09:59:15 -05:00
|
|
|
ir.DumpList("ninit", r.Init())
|
2020-11-19 20:49:23 -05:00
|
|
|
base.Fatalf("ninit on select send")
|
2018-04-03 13:17:28 +01:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-04-03 13:17:28 +01:00
|
|
|
// case c <- x
|
|
|
|
|
// r->left is c, r->right is x, both are always evaluated.
|
2020-12-23 00:02:08 -05:00
|
|
|
r.Chan = o.expr(r.Chan, nil)
|
2018-04-03 13:17:28 +01:00
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
if !ir.IsAutoTmp(r.Chan) {
|
|
|
|
|
r.Chan = o.copyExpr(r.Chan)
|
2018-04-03 13:17:28 +01:00
|
|
|
}
|
2020-12-23 00:02:08 -05:00
|
|
|
r.Value = o.expr(r.Value, nil)
|
|
|
|
|
if !ir.IsAutoTmp(r.Value) {
|
|
|
|
|
r.Value = o.copyExpr(r.Value)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Now that we have accumulated all the temporaries, clean them.
|
|
|
|
|
// Also insert any ninit queued during the previous loop.
|
|
|
|
|
// (The temporary cleaning must follow that ninit work.)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, cas := range n.Cases {
|
2020-12-23 00:02:08 -05:00
|
|
|
orderBlock(&cas.Body, o.free)
|
|
|
|
|
cas.Body.Prepend(o.cleanTempNoPop(t)...)
|
2018-03-22 12:49:48 -07:00
|
|
|
|
|
|
|
|
// TODO(mdempsky): Is this actually necessary?
|
2021-01-15 14:12:35 -08:00
|
|
|
// walkSelect appears to walk Ninit.
|
2021-01-02 01:04:19 -08:00
|
|
|
cas.Body.Prepend(ir.TakeInit(cas)...)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.popTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Special: value being sent is passed as a pointer; make it addressable.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OSEND:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.SendStmt)
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Chan = o.expr(n.Chan, nil)
|
|
|
|
|
n.Value = o.expr(n.Value, nil)
|
2020-12-23 00:05:23 -05:00
|
|
|
if base.Flag.Cfg.Instrumenting {
|
2017-03-18 15:55:41 +00:00
|
|
|
// Force copying to the stack so that (chan T)(nil) <- x
|
|
|
|
|
// is still instrumented as a read of x.
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Value = o.copyExpr(n.Value)
|
2017-03-18 15:55:41 +00:00
|
|
|
} else {
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Value = o.addrTemp(n.Value)
|
2017-03-18 15:55:41 +00:00
|
|
|
}
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// TODO(rsc): Clean temporaries more aggressively.
|
2021-01-15 14:12:35 -08:00
|
|
|
// Note that because walkSwitch will rewrite some of the
|
2015-02-13 14:40:36 -05:00
|
|
|
// switch into a binary search, this is not as easy as it looks.
|
2019-10-05 00:00:38 +07:00
|
|
|
// (If we ran that code here we could invoke order.stmt on
|
2015-02-13 14:40:36 -05:00
|
|
|
// the if-else chain instead.)
|
|
|
|
|
// For now just clean all the temporaries at the end.
|
|
|
|
|
// In practice that's fine.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OSWITCH:
|
2020-12-10 18:45:35 -05:00
|
|
|
n := n.(*ir.SwitchStmt)
|
2020-11-19 20:49:23 -05:00
|
|
|
if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
|
2019-10-18 17:39:39 -07:00
|
|
|
// Add empty "default:" case for instrumentation.
|
2020-12-26 22:23:45 -08:00
|
|
|
n.Cases = append(n.Cases, ir.NewCaseStmt(base.Pos, nil, nil))
|
2019-10-18 17:39:39 -07:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
t := o.markTemp()
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Tag = o.expr(n.Tag, nil)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, ncas := range n.Cases {
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprListInPlace(ncas.List)
|
|
|
|
|
orderBlock(&ncas.Body, o.free)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
|
|
|
|
o.cleanTemp(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-11-19 20:49:23 -05:00
|
|
|
base.Pos = lno
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
func hasDefaultCase(n *ir.SwitchStmt) bool {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, ncas := range n.Cases {
|
|
|
|
|
if len(ncas.List) == 0 {
|
2019-10-18 17:39:39 -07:00
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// exprList orders the expression list l into o.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) exprList(l ir.Nodes) {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
s := l
|
2016-03-09 12:39:36 -08:00
|
|
|
for i := range s {
|
2018-03-04 17:17:55 -08:00
|
|
|
s[i] = o.expr(s[i], nil)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// exprListInPlace orders the expression list l but saves
|
2015-02-13 14:40:36 -05:00
|
|
|
// the side effects on the individual expression ninit lists.
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) exprListInPlace(l ir.Nodes) {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
s := l
|
2016-03-09 12:39:36 -08:00
|
|
|
for i := range s {
|
2018-03-04 17:17:55 -08:00
|
|
|
s[i] = o.exprInPlace(s[i])
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) exprNoLHS(n ir.Node) ir.Node {
|
2020-12-02 20:18:47 -05:00
|
|
|
return o.expr(n, nil)
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
// expr orders a single expression, appending side
|
|
|
|
|
// effects to o.out as needed.
|
cmd/internal/gc: avoid turning 'x = f()' into 'tmp = f(); x = tmp' for simple x
This slows down more things than I expected, but it also speeds things up,
and it reduces stack frame sizes and the load on the optimizer, so it's still
likely a net win.
name old mean new mean delta
BenchmarkBinaryTree17 13.2s × (0.98,1.03) 13.2s × (0.98,1.02) ~ (p=0.795)
BenchmarkFannkuch11 4.41s × (1.00,1.00) 4.45s × (0.99,1.01) +0.88% (p=0.000)
BenchmarkFmtFprintfEmpty 86.4ns × (0.99,1.01) 90.1ns × (0.95,1.05) +4.31% (p=0.000)
BenchmarkFmtFprintfString 318ns × (0.96,1.07) 337ns × (0.98,1.03) +6.05% (p=0.000)
BenchmarkFmtFprintfInt 332ns × (0.97,1.04) 320ns × (0.97,1.02) -3.42% (p=0.000)
BenchmarkFmtFprintfIntInt 562ns × (0.96,1.04) 574ns × (0.96,1.06) +2.00% (p=0.013)
BenchmarkFmtFprintfPrefixedInt 442ns × (0.96,1.06) 450ns × (0.97,1.05) +1.73% (p=0.039)
BenchmarkFmtFprintfFloat 640ns × (0.99,1.02) 659ns × (0.99,1.03) +3.01% (p=0.000)
BenchmarkFmtManyArgs 2.19µs × (0.97,1.06) 2.21µs × (0.98,1.02) ~ (p=0.104)
BenchmarkGobDecode 20.0ms × (0.98,1.03) 19.7ms × (0.97,1.04) -1.35% (p=0.035)
BenchmarkGobEncode 17.8ms × (0.96,1.04) 18.0ms × (0.96,1.06) ~ (p=0.131)
BenchmarkGzip 653ms × (0.99,1.02) 652ms × (0.99,1.01) ~ (p=0.572)
BenchmarkGunzip 143ms × (0.99,1.02) 142ms × (1.00,1.01) -0.52% (p=0.005)
BenchmarkHTTPClientServer 110µs × (0.98,1.03) 108µs × (0.99,1.02) -1.90% (p=0.000)
BenchmarkJSONEncode 40.0ms × (0.98,1.05) 41.5ms × (0.97,1.06) +3.89% (p=0.000)
BenchmarkJSONDecode 118ms × (0.99,1.01) 118ms × (0.98,1.01) +0.69% (p=0.010)
BenchmarkMandelbrot200 6.03ms × (1.00,1.01) 6.03ms × (1.00,1.01) ~ (p=0.924)
BenchmarkGoParse 8.43ms × (0.92,1.11) 8.56ms × (0.93,1.05) ~ (p=0.242)
BenchmarkRegexpMatchEasy0_32 180ns × (0.91,1.07) 163ns × (1.00,1.00) -9.33% (p=0.000)
BenchmarkRegexpMatchEasy0_1K 550ns × (0.98,1.02) 558ns × (0.99,1.01) +1.44% (p=0.000)
BenchmarkRegexpMatchEasy1_32 152ns × (0.94,1.05) 139ns × (0.98,1.02) -8.51% (p=0.000)
BenchmarkRegexpMatchEasy1_1K 909ns × (0.98,1.06) 868ns × (0.99,1.02) -4.52% (p=0.000)
BenchmarkRegexpMatchMedium_32 262ns × (0.97,1.03) 253ns × (0.99,1.02) -3.31% (p=0.000)
BenchmarkRegexpMatchMedium_1K 73.8µs × (0.98,1.04) 72.7µs × (1.00,1.01) -1.61% (p=0.001)
BenchmarkRegexpMatchHard_32 3.87µs × (0.99,1.02) 3.87µs × (1.00,1.01) ~ (p=0.791)
BenchmarkRegexpMatchHard_1K 118µs × (0.98,1.04) 117µs × (0.99,1.02) ~ (p=0.110)
BenchmarkRevcomp 1.00s × (0.94,1.10) 0.99s × (0.94,1.09) ~ (p=0.433)
BenchmarkTemplate 140ms × (0.97,1.04) 140ms × (0.99,1.01) ~ (p=0.303)
BenchmarkTimeParse 622ns × (0.99,1.02) 625ns × (0.99,1.01) +0.51% (p=0.001)
BenchmarkTimeFormat 731ns × (0.98,1.04) 719ns × (0.99,1.01) -1.66% (p=0.000)
Change-Id: Ibc3edb59a178adafda50156f46a341f69a17d83f
Reviewed-on: https://go-review.googlesource.com/9721
Reviewed-by: David Chase <drchase@google.com>
2015-04-30 20:35:47 -04:00
|
|
|
// If this is part of an assignment lhs = *np, lhs is given.
|
|
|
|
|
// Otherwise lhs == nil. (When lhs != nil it may be possible
|
|
|
|
|
// to avoid copying the result of the expression to a temporary.)
|
2018-03-04 17:17:55 -08:00
|
|
|
// The result of expr MUST be assigned back to n, e.g.
|
|
|
|
|
// n.Left = o.expr(n.Left, lhs)
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) expr(n, lhs ir.Node) ir.Node {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n == nil {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
lno := ir.SetPos(n)
|
2020-12-10 18:45:35 -05:00
|
|
|
n = o.expr1(n, lhs)
|
|
|
|
|
base.Pos = lno
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 01:05:16 -05:00
|
|
|
func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
|
2018-03-04 17:17:55 -08:00
|
|
|
o.init(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-11-22 09:59:15 -05:00
|
|
|
switch n.Op() {
|
2015-02-13 14:40:36 -05:00
|
|
|
default:
|
2020-12-07 16:07:38 -05:00
|
|
|
if o.edit == nil {
|
|
|
|
|
o.edit = o.exprNoLHS // create closure once
|
|
|
|
|
}
|
|
|
|
|
ir.EditChildren(n, o.edit)
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-24 21:38:58 +02:00
|
|
|
// Addition of strings turns into a function call.
|
2015-02-13 14:40:36 -05:00
|
|
|
// Allocate a temporary to hold the strings.
|
|
|
|
|
// Fewer than 5 strings use direct runtime helpers.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OADDSTR:
|
2020-12-17 08:49:22 -05:00
|
|
|
n := n.(*ir.AddStringExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.List)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
if len(n.List) > 5 {
|
|
|
|
|
t := types.NewArray(types.Types[types.TSTRING], int64(len(n.List)))
|
2020-12-17 08:49:22 -05:00
|
|
|
n.Prealloc = o.newTemp(t, false)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mark string(byteSlice) arguments to reuse byteSlice backing
|
|
|
|
|
// buffer during conversion. String concatenation does not
|
|
|
|
|
// memorize the strings for later use, so it is safe.
|
|
|
|
|
// However, we can do it only if there is at least one non-empty string literal.
|
|
|
|
|
// Otherwise if all other arguments are empty strings,
|
|
|
|
|
// concatstrings will return the reference to the temp string
|
|
|
|
|
// to the caller.
|
2015-02-23 16:07:24 -05:00
|
|
|
hasbyte := false
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
haslit := false
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, n1 := range n.List {
|
2020-11-22 09:59:15 -05:00
|
|
|
hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR
|
2020-12-02 23:55:42 -08:00
|
|
|
haslit = haslit || n1.Op() == ir.OLITERAL && len(ir.StringVal(n1)) != 0
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
if haslit && hasbyte {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
for _, n2 := range n.List {
|
2020-11-22 09:59:15 -05:00
|
|
|
if n2.Op() == ir.OBYTES2STR {
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n2 := n2.(*ir.ConvExpr)
|
2020-11-22 09:59:15 -05:00
|
|
|
n2.SetOp(ir.OBYTES2STRTMP)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OINDEXMAP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.IndexExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
n.Index = o.expr(n.Index, nil)
|
2016-10-11 08:36:38 -07:00
|
|
|
needCopy := false
|
|
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
if !n.Assigned {
|
2018-06-04 08:24:11 +02:00
|
|
|
// Enforce that any []byte slices we are not copying
|
|
|
|
|
// can not be changed before the map index by forcing
|
|
|
|
|
// the map index to happen immediately following the
|
|
|
|
|
// conversions. See copyExpr a few lines below.
|
2020-12-23 00:02:08 -05:00
|
|
|
needCopy = mapKeyReplaceStrConv(n.Index)
|
2018-06-04 08:24:11 +02:00
|
|
|
|
2020-12-23 00:05:23 -05:00
|
|
|
if base.Flag.Cfg.Instrumenting {
|
2020-11-29 09:38:52 -05:00
|
|
|
// Race detector needs the copy.
|
2018-06-04 08:24:11 +02:00
|
|
|
needCopy = true
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2019-05-27 15:58:24 +07:00
|
|
|
// key must be addressable
|
2020-12-23 00:02:08 -05:00
|
|
|
n.Index = o.mapKeyTemp(n.X.Type(), n.Index)
|
2016-10-11 08:36:38 -07:00
|
|
|
if needCopy {
|
2020-12-10 18:45:35 -05:00
|
|
|
return o.copyExpr(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
runtime,cmd/compile: pass strings and slices to convT2{E,I} by value
When we pass these types by reference, we usually have to allocate
temporaries on the stack, initialize them, then pass their address
to the conversion functions. It's simpler to pass these types
directly by value.
This particularly applies to conversions needed for fmt.Printf
(to interface{} for constructing a [...]interface{}).
func f(a, b, c string) {
fmt.Printf("%s %s\n", a, b)
fmt.Printf("%s %s\n", b, c)
}
This function's stack frame shrinks from 200 to 136 bytes, and
its code shrinks from 535 to 453 bytes.
The go binary shrinks 0.3%.
Update #24286
Aside: for this function f, we don't really need to allocate
temporaries for the convT2E function. We could use the address
of a, b, and c directly. That might get similar (or maybe better?)
improvements. I investigated a bit, but it seemed complicated
to do it safely. This change was much easier.
Change-Id: I78cbe51b501fb41e1e324ce4203f0de56a1db82d
Reviewed-on: https://go-review.googlesource.com/c/135377
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2018-09-14 10:09:08 -07:00
|
|
|
// concrete type (not interface) argument might need an addressable
|
|
|
|
|
// temporary to pass to the runtime conversion routine.
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OCONVIFACE:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.ConvExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
if n.X.Type().IsInterface() {
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
runtime,cmd/compile: pass strings and slices to convT2{E,I} by value
When we pass these types by reference, we usually have to allocate
temporaries on the stack, initialize them, then pass their address
to the conversion functions. It's simpler to pass these types
directly by value.
This particularly applies to conversions needed for fmt.Printf
(to interface{} for constructing a [...]interface{}).
func f(a, b, c string) {
fmt.Printf("%s %s\n", a, b)
fmt.Printf("%s %s\n", b, c)
}
This function's stack frame shrinks from 200 to 136 bytes, and
its code shrinks from 535 to 453 bytes.
The go binary shrinks 0.3%.
Update #24286
Aside: for this function f, we don't really need to allocate
temporaries for the convT2E function. We could use the address
of a, b, and c directly. That might get similar (or maybe better?)
improvements. I investigated a bit, but it seemed complicated
to do it safely. This change was much easier.
Change-Id: I78cbe51b501fb41e1e324ce4203f0de56a1db82d
Reviewed-on: https://go-review.googlesource.com/c/135377
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2018-09-14 10:09:08 -07:00
|
|
|
}
|
cmd/compile: make interface conversion function selection ABI insensitive
Before register ABI, we always pass argument in memory, and the
compiler chooses interface conversion functions solely based on
the memory layout. As long as the two types have identical memory
layout, it is fine to mix and match, e.g. convT64 takes a uint64
argument, but it can be used for things like float64 or
struct { x [4]struct{}; y int64 }.
With register ABI, those types may be passed differently, e.g.
uint64 is passed in an integer register, float64 is passed in a
floating point register, the struct above is passed in memory.
I made a few attempts in the previous CLs to try to choose the
right function based on the argument type, but none of them is
really correct.
Instead, this CL changes it to always pass the argument in the
same type the runtime expects, and do conversion before the call
in the compiler. The conversion can be no-op (e.g. a named type
to its underlying type), direct (e.g. int64 to uint64), or
through memory (e.g. *(*uint64)(unsafe.Pointer(&arg))). This way,
the front end does not need to know the ABI. (It only needs to
know how to convert types, and it already does.)
TODO: do something similar for map functions.
Change-Id: I33fc780a47c3f332b765e09b5e527f52ea1d6b5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/309029
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-04-09 14:40:28 -04:00
|
|
|
if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
|
runtime,cmd/compile: pass strings and slices to convT2{E,I} by value
When we pass these types by reference, we usually have to allocate
temporaries on the stack, initialize them, then pass their address
to the conversion functions. It's simpler to pass these types
directly by value.
This particularly applies to conversions needed for fmt.Printf
(to interface{} for constructing a [...]interface{}).
func f(a, b, c string) {
fmt.Printf("%s %s\n", a, b)
fmt.Printf("%s %s\n", b, c)
}
This function's stack frame shrinks from 200 to 136 bytes, and
its code shrinks from 535 to 453 bytes.
The go binary shrinks 0.3%.
Update #24286
Aside: for this function f, we don't really need to allocate
temporaries for the convT2E function. We could use the address
of a, b, and c directly. That might get similar (or maybe better?)
improvements. I investigated a bit, but it seemed complicated
to do it safely. This change was much easier.
Change-Id: I78cbe51b501fb41e1e324ce4203f0de56a1db82d
Reviewed-on: https://go-review.googlesource.com/c/135377
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2018-09-14 10:09:08 -07:00
|
|
|
// Need a temp if we need to pass the address to the conversion function.
|
2019-03-23 01:43:06 +07:00
|
|
|
// We also process static composite literal node here, making a named static global
|
|
|
|
|
// whose address we can put directly in an interface (see OCONVIFACE case in walk).
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.addrTemp(n.X)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OCONVNOP:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.ConvExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.Type().IsKind(types.TUNSAFEPTR) && n.X.Type().IsKind(types.TUINTPTR) && (n.X.Op() == ir.OCALLFUNC || n.X.Op() == ir.OCALLINTER || n.X.Op() == ir.OCALLMETH) {
|
|
|
|
|
call := n.X.(*ir.CallExpr)
|
2016-04-19 15:02:06 -07:00
|
|
|
// When reordering unsafe.Pointer(f()) into a separate
|
|
|
|
|
// statement, the conversion and function call must stay
|
|
|
|
|
// together. See golang.org/issue/15329.
|
2020-12-10 18:45:35 -05:00
|
|
|
o.init(call)
|
|
|
|
|
o.call(call)
|
2020-12-23 00:05:23 -05:00
|
|
|
if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
|
2020-12-10 18:45:35 -05:00
|
|
|
return o.copyExpr(n)
|
2016-04-19 15:02:06 -07:00
|
|
|
}
|
|
|
|
|
} else {
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2016-04-19 15:02:06 -07:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2016-04-19 15:02:06 -07:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OANDAND, ir.OOROR:
|
2019-03-05 17:42:48 -08:00
|
|
|
// ... = LHS && RHS
|
|
|
|
|
//
|
|
|
|
|
// var r bool
|
|
|
|
|
// r = LHS
|
|
|
|
|
// if r { // or !r, for OROR
|
|
|
|
|
// r = RHS
|
|
|
|
|
// }
|
|
|
|
|
// ... = r
|
|
|
|
|
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.LogicalExpr)
|
2020-11-22 09:59:15 -05:00
|
|
|
r := o.newTemp(n.Type(), false)
|
2019-03-05 17:42:48 -08:00
|
|
|
|
|
|
|
|
// Evaluate left-hand side.
|
2020-12-23 00:02:08 -05:00
|
|
|
lhs := o.expr(n.X, nil)
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, lhs)))
|
2019-03-05 17:42:48 -08:00
|
|
|
|
|
|
|
|
// Evaluate right-hand side, save generated code.
|
|
|
|
|
saveout := o.out
|
|
|
|
|
o.out = nil
|
|
|
|
|
t := o.markTemp()
|
2019-10-18 17:39:39 -07:00
|
|
|
o.edge()
|
2020-12-23 00:02:08 -05:00
|
|
|
rhs := o.expr(n.Y, nil)
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
|
2019-03-05 17:42:48 -08:00
|
|
|
o.cleanTemp(t)
|
|
|
|
|
gen := o.out
|
|
|
|
|
o.out = saveout
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2019-03-05 17:42:48 -08:00
|
|
|
// If left-hand side doesn't cause a short-circuit, issue right-hand side.
|
[dev.regabi] cmd/compile: remove ir.Nod [generated]
Rewrite all uses of ir.Nod and friends to call the IR constructors directly.
This gives the results a more specific type and will play nicely with
introduction of more specific types throughout the code in a followup CL.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/compile/internal/syntax"
import "cmd/internal/src"
var p *noder
var orig syntax.Node
var op ir.Op
var l, r ir.Node
var sym *types.Sym
p.nod(orig, op, l, r) -> ir.NodAt(p.pos(orig), op, l, r)
p.nodSym(orig, op, l, sym) -> nodlSym(p.pos(orig), op, l, sym)
var xpos src.XPos
var ns ir.Nodes
npos(xpos, nodSym(op, l, sym)) -> nodlSym(xpos, op, l, sym)
npos(xpos, liststmt(ns)) -> ir.NewBlockStmt(xpos, ns)
}
ex . ../ir {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
var op ir.Op
var l, r ir.Node
ir.Nod(op, l, r) -> ir.NodAt(base.Pos, op, l, r)
var sym *types.Sym
nodSym(op, l, sym) -> nodlSym(base.Pos, op, l, sym)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/internal/src"
# rf overlapping match handling is not quite good enough
# for certain nested rewrites, so handle these two - which often contain other ir.NodAt calls - early.
var l, r ir.Node
var xpos src.XPos
ir.NodAt(xpos, ir.OAS, l, r) -> ir.NewAssignStmt(xpos, l, r)
ir.NodAt(xpos, ir.OIF, l, nil) -> ir.NewIfStmt(xpos, l, nil, nil)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var l, r ir.Node
var sym *types.Sym
var xpos src.XPos
nodlSym(xpos, ir.ODOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, sym)
nodlSym(xpos, ir.OXDOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, sym)
nodlSym(xpos, ir.ODOTPTR, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, sym)
nodlSym(xpos, ir.OGOTO, nil, sym) -> ir.NewBranchStmt(xpos, ir.OGOTO, sym)
nodlSym(xpos, ir.ORETJMP, nil, sym) -> ir.NewBranchStmt(xpos, ir.ORETJMP, sym)
nodlSym(xpos, ir.OLABEL, nil, sym) -> ir.NewLabelStmt(xpos, sym)
nodlSym(xpos, ir.OSTRUCTKEY, l, sym) -> ir.NewStructKeyExpr(xpos, sym, l)
ir.NodAt(xpos, ir.OADD, l, r) -> ir.NewBinaryExpr(xpos, ir.OADD, l, r)
ir.NodAt(xpos, ir.OAND, l, r) -> ir.NewBinaryExpr(xpos, ir.OAND, l, r)
ir.NodAt(xpos, ir.OANDNOT, l, r) -> ir.NewBinaryExpr(xpos, ir.OANDNOT, l, r)
ir.NodAt(xpos, ir.ODIV, l, r) -> ir.NewBinaryExpr(xpos, ir.ODIV, l, r)
ir.NodAt(xpos, ir.OEQ, l, r) -> ir.NewBinaryExpr(xpos, ir.OEQ, l, r)
ir.NodAt(xpos, ir.OGE, l, r) -> ir.NewBinaryExpr(xpos, ir.OGE, l, r)
ir.NodAt(xpos, ir.OGT, l, r) -> ir.NewBinaryExpr(xpos, ir.OGT, l, r)
ir.NodAt(xpos, ir.OLE, l, r) -> ir.NewBinaryExpr(xpos, ir.OLE, l, r)
ir.NodAt(xpos, ir.OLSH, l, r) -> ir.NewBinaryExpr(xpos, ir.OLSH, l, r)
ir.NodAt(xpos, ir.OLT, l, r) -> ir.NewBinaryExpr(xpos, ir.OLT, l, r)
ir.NodAt(xpos, ir.OMOD, l, r) -> ir.NewBinaryExpr(xpos, ir.OMOD, l, r)
ir.NodAt(xpos, ir.OMUL, l, r) -> ir.NewBinaryExpr(xpos, ir.OMUL, l, r)
ir.NodAt(xpos, ir.ONE, l, r) -> ir.NewBinaryExpr(xpos, ir.ONE, l, r)
ir.NodAt(xpos, ir.OOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OOR, l, r)
ir.NodAt(xpos, ir.ORSH, l, r) -> ir.NewBinaryExpr(xpos, ir.ORSH, l, r)
ir.NodAt(xpos, ir.OSUB, l, r) -> ir.NewBinaryExpr(xpos, ir.OSUB, l, r)
ir.NodAt(xpos, ir.OXOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OXOR, l, r)
ir.NodAt(xpos, ir.OCOPY, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOPY, l, r)
ir.NodAt(xpos, ir.OCOMPLEX, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOMPLEX, l, r)
ir.NodAt(xpos, ir.OEFACE, l, r) -> ir.NewBinaryExpr(xpos, ir.OEFACE, l, r)
ir.NodAt(xpos, ir.OADDR, l, nil) -> ir.NewAddrExpr(xpos, l)
ir.NodAt(xpos, ir.OADDSTR, nil, nil) -> ir.NewAddStringExpr(xpos, nil)
ir.NodAt(xpos, ir.OANDAND, l, r) -> ir.NewLogicalExpr(xpos, ir.OANDAND, l, r)
ir.NodAt(xpos, ir.OOROR, l, r) -> ir.NewLogicalExpr(xpos, ir.OOROR, l, r)
ir.NodAt(xpos, ir.OARRAYLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, nil, nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, nil, nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, nil, nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, nil, nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, nil, nil)
ir.NodAt(xpos, ir.OARRAYLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OAS2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2, nil, nil)
ir.NodAt(xpos, ir.OAS2DOTTYPE, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2DOTTYPE, nil, nil)
ir.NodAt(xpos, ir.OAS2FUNC, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2FUNC, nil, nil)
ir.NodAt(xpos, ir.OAS2MAPR, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2MAPR, nil, nil)
ir.NodAt(xpos, ir.OAS2RECV, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2RECV, nil, nil)
ir.NodAt(xpos, ir.OSELRECV2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OSELRECV2, nil, nil)
ir.NodAt(xpos, ir.OASOP, l, r) -> ir.NewAssignOpStmt(xpos, ir.OXXX, l, r)
ir.NodAt(xpos, ir.OBITNOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.OBITNOT, l)
ir.NodAt(xpos, ir.ONEG, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEG, l)
ir.NodAt(xpos, ir.ONOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONOT, l)
ir.NodAt(xpos, ir.OPLUS, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPLUS, l)
ir.NodAt(xpos, ir.ORECV, l, nil) -> ir.NewUnaryExpr(xpos, ir.ORECV, l)
ir.NodAt(xpos, ir.OALIGNOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OALIGNOF, l)
ir.NodAt(xpos, ir.OCAP, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCAP, l)
ir.NodAt(xpos, ir.OCLOSE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCLOSE, l)
ir.NodAt(xpos, ir.OIMAG, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIMAG, l)
ir.NodAt(xpos, ir.OLEN, l, nil) -> ir.NewUnaryExpr(xpos, ir.OLEN, l)
ir.NodAt(xpos, ir.ONEW, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEW, l)
ir.NodAt(xpos, ir.ONEWOBJ, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEWOBJ, l)
ir.NodAt(xpos, ir.OOFFSETOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OOFFSETOF, l)
ir.NodAt(xpos, ir.OPANIC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPANIC, l)
ir.NodAt(xpos, ir.OREAL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OREAL, l)
ir.NodAt(xpos, ir.OSIZEOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSIZEOF, l)
ir.NodAt(xpos, ir.OCHECKNIL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCHECKNIL, l)
ir.NodAt(xpos, ir.OCFUNC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCFUNC, l)
ir.NodAt(xpos, ir.OIDATA, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIDATA, l)
ir.NodAt(xpos, ir.OITAB, l, nil) -> ir.NewUnaryExpr(xpos, ir.OITAB, l)
ir.NodAt(xpos, ir.OSPTR, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSPTR, l)
ir.NodAt(xpos, ir.OVARDEF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARDEF, l)
ir.NodAt(xpos, ir.OVARKILL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARKILL, l)
ir.NodAt(xpos, ir.OVARLIVE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARLIVE, l)
ir.NodAt(xpos, ir.OBLOCK, nil, nil) -> ir.NewBlockStmt(xpos, nil)
ir.NodAt(xpos, ir.OBREAK, nil, nil) -> ir.NewBranchStmt(xpos, ir.OBREAK, nil)
ir.NodAt(xpos, ir.OCONTINUE, nil, nil) -> ir.NewBranchStmt(xpos, ir.OCONTINUE, nil)
ir.NodAt(xpos, ir.OFALL, nil, nil) -> ir.NewBranchStmt(xpos, ir.OFALL, nil)
ir.NodAt(xpos, ir.OGOTO, nil, nil) -> ir.NewBranchStmt(xpos, ir.OGOTO, nil)
ir.NodAt(xpos, ir.ORETJMP, nil, nil) -> ir.NewBranchStmt(xpos, ir.ORETJMP, nil)
ir.NodAt(xpos, ir.OCALL, l, nil) -> ir.NewCallExpr(xpos, ir.OCALL, l, nil)
ir.NodAt(xpos, ir.OCALLFUNC, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLFUNC, l, nil)
ir.NodAt(xpos, ir.OCALLINTER, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLINTER, l, nil)
ir.NodAt(xpos, ir.OCALLMETH, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLMETH, l, nil)
ir.NodAt(xpos, ir.OAPPEND, l, nil) -> ir.NewCallExpr(xpos, ir.OAPPEND, l, nil)
ir.NodAt(xpos, ir.ODELETE, l, nil) -> ir.NewCallExpr(xpos, ir.ODELETE, l, nil)
ir.NodAt(xpos, ir.OGETG, l, nil) -> ir.NewCallExpr(xpos, ir.OGETG, l, nil)
ir.NodAt(xpos, ir.OMAKE, l, nil) -> ir.NewCallExpr(xpos, ir.OMAKE, l, nil)
ir.NodAt(xpos, ir.OPRINT, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINT, l, nil)
ir.NodAt(xpos, ir.OPRINTN, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINTN, l, nil)
ir.NodAt(xpos, ir.ORECOVER, l, nil) -> ir.NewCallExpr(xpos, ir.ORECOVER, l, nil)
ir.NodAt(xpos, ir.OCASE, nil, nil) -> ir.NewCaseStmt(xpos, nil, nil)
ir.NodAt(xpos, ir.OCONV, l, nil) -> ir.NewConvExpr(xpos, ir.OCONV, nil, l)
ir.NodAt(xpos, ir.OCONVIFACE, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVIFACE, nil, l)
ir.NodAt(xpos, ir.OCONVNOP, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVNOP, nil, l)
ir.NodAt(xpos, ir.ORUNESTR, l, nil) -> ir.NewConvExpr(xpos, ir.ORUNESTR, nil, l)
ir.NodAt(xpos, ir.ODCL, l, nil) -> ir.NewDecl(xpos, ir.ODCL, l)
ir.NodAt(xpos, ir.ODCLCONST, l, nil) -> ir.NewDecl(xpos, ir.ODCLCONST, l)
ir.NodAt(xpos, ir.ODCLTYPE, l, nil) -> ir.NewDecl(xpos, ir.ODCLTYPE, l)
ir.NodAt(xpos, ir.ODCLFUNC, nil, nil) -> ir.NewFunc(xpos)
ir.NodAt(xpos, ir.ODEFER, l, nil) -> ir.NewGoDeferStmt(xpos, ir.ODEFER, l)
ir.NodAt(xpos, ir.OGO, l, nil) -> ir.NewGoDeferStmt(xpos, ir.OGO, l)
ir.NodAt(xpos, ir.ODEREF, l, nil) -> ir.NewStarExpr(xpos, l)
ir.NodAt(xpos, ir.ODOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, nil)
ir.NodAt(xpos, ir.ODOTPTR, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, nil)
ir.NodAt(xpos, ir.ODOTMETH, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTMETH, l, nil)
ir.NodAt(xpos, ir.ODOTINTER, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTINTER, l, nil)
ir.NodAt(xpos, ir.OXDOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, nil) -> ir.NewTypeAssertExpr(xpos, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, r) -> ir.NewTypeAssertExpr(xpos, l, r.(ir.Ntype))
ir.NodAt(xpos, ir.OFOR, l, r) -> ir.NewForStmt(xpos, nil, l, r, nil)
ir.NodAt(xpos, ir.OINDEX, l, r) -> ir.NewIndexExpr(xpos, l, r)
ir.NodAt(xpos, ir.OINLMARK, nil, nil) -> ir.NewInlineMarkStmt(xpos, types.BADWIDTH)
ir.NodAt(xpos, ir.OKEY, l, r) -> ir.NewKeyExpr(xpos, l, r)
ir.NodAt(xpos, ir.OLABEL, nil, nil) -> ir.NewLabelStmt(xpos, nil)
ir.NodAt(xpos, ir.OMAKECHAN, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKECHAN, l, r)
ir.NodAt(xpos, ir.OMAKEMAP, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKEMAP, l, r)
ir.NodAt(xpos, ir.OMAKESLICE, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICE, l, r)
ir.NodAt(xpos, ir.OMAKESLICECOPY, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICECOPY, l, r)
ir.NodAt(xpos, ir.ONIL, nil, nil) -> ir.NewNilExpr(xpos)
ir.NodAt(xpos, ir.OPACK, nil, nil) -> ir.NewPkgName(xpos, nil, nil)
ir.NodAt(xpos, ir.OPAREN, l, nil) -> ir.NewParenExpr(xpos, l)
ir.NodAt(xpos, ir.ORANGE, nil, r) -> ir.NewRangeStmt(xpos, nil, r, nil)
ir.NodAt(xpos, ir.ORESULT, nil, nil) -> ir.NewResultExpr(xpos, nil, types.BADWIDTH)
ir.NodAt(xpos, ir.ORETURN, nil, nil) -> ir.NewReturnStmt(xpos, nil)
ir.NodAt(xpos, ir.OSELECT, nil, nil) -> ir.NewSelectStmt(xpos, nil)
ir.NodAt(xpos, ir.OSEND, l, r) -> ir.NewSendStmt(xpos, l, r)
ir.NodAt(xpos, ir.OSLICE, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE, l)
ir.NodAt(xpos, ir.OSLICEARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICEARR, l)
ir.NodAt(xpos, ir.OSLICESTR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICESTR, l)
ir.NodAt(xpos, ir.OSLICE3, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3, l)
ir.NodAt(xpos, ir.OSLICE3ARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3ARR, l)
ir.NodAt(xpos, ir.OSLICEHEADER, l, nil) -> ir.NewSliceHeaderExpr(xpos, nil, l, nil, nil)
ir.NodAt(xpos, ir.OSWITCH, l, nil) -> ir.NewSwitchStmt(xpos, l, nil)
ir.NodAt(xpos, ir.OINLCALL, nil, nil) -> ir.NewInlinedCallExpr(xpos, nil, nil)
}
rm noder.nod noder.nodSym nodSym nodlSym ir.NodAt ir.Nod
'
Change-Id: Ibf1eb708de8463ae74ccc47d7966cc263a18295e
Reviewed-on: https://go-review.googlesource.com/c/go/+/277933
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:55:29 -05:00
|
|
|
nif := ir.NewIfStmt(base.Pos, r, nil, nil)
|
2020-11-22 09:59:15 -05:00
|
|
|
if n.Op() == ir.OANDAND {
|
2021-01-02 01:27:29 -08:00
|
|
|
nif.Body = gen
|
2019-03-05 17:42:48 -08:00
|
|
|
} else {
|
2021-01-02 01:27:29 -08:00
|
|
|
nif.Else = gen
|
2019-03-05 17:42:48 -08:00
|
|
|
}
|
|
|
|
|
o.out = append(o.out, nif)
|
2020-12-10 18:45:35 -05:00
|
|
|
return r
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OCALLFUNC,
|
|
|
|
|
ir.OCALLINTER,
|
|
|
|
|
ir.OCALLMETH,
|
|
|
|
|
ir.OCAP,
|
|
|
|
|
ir.OCOMPLEX,
|
|
|
|
|
ir.OCOPY,
|
|
|
|
|
ir.OIMAG,
|
|
|
|
|
ir.OLEN,
|
|
|
|
|
ir.OMAKECHAN,
|
|
|
|
|
ir.OMAKEMAP,
|
|
|
|
|
ir.OMAKESLICE,
|
|
|
|
|
ir.OMAKESLICECOPY,
|
|
|
|
|
ir.ONEW,
|
|
|
|
|
ir.OREAL,
|
|
|
|
|
ir.ORECOVER,
|
|
|
|
|
ir.OSTR2BYTES,
|
|
|
|
|
ir.OSTR2BYTESTMP,
|
|
|
|
|
ir.OSTR2RUNES:
|
2018-04-24 15:13:08 +02:00
|
|
|
|
|
|
|
|
if isRuneCount(n) {
|
|
|
|
|
// len([]rune(s)) is rewritten to runtime.countrunes(s) later.
|
2020-12-23 00:02:08 -05:00
|
|
|
conv := n.(*ir.UnaryExpr).X.(*ir.ConvExpr)
|
|
|
|
|
conv.X = o.expr(conv.X, nil)
|
2018-04-24 15:13:08 +02:00
|
|
|
} else {
|
|
|
|
|
o.call(n)
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 00:05:23 -05:00
|
|
|
if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
|
2020-12-10 18:45:35 -05:00
|
|
|
return o.copyExpr(n)
|
cmd/internal/gc: avoid turning 'x = f()' into 'tmp = f(); x = tmp' for simple x
This slows down more things than I expected, but it also speeds things up,
and it reduces stack frame sizes and the load on the optimizer, so it's still
likely a net win.
name old mean new mean delta
BenchmarkBinaryTree17 13.2s × (0.98,1.03) 13.2s × (0.98,1.02) ~ (p=0.795)
BenchmarkFannkuch11 4.41s × (1.00,1.00) 4.45s × (0.99,1.01) +0.88% (p=0.000)
BenchmarkFmtFprintfEmpty 86.4ns × (0.99,1.01) 90.1ns × (0.95,1.05) +4.31% (p=0.000)
BenchmarkFmtFprintfString 318ns × (0.96,1.07) 337ns × (0.98,1.03) +6.05% (p=0.000)
BenchmarkFmtFprintfInt 332ns × (0.97,1.04) 320ns × (0.97,1.02) -3.42% (p=0.000)
BenchmarkFmtFprintfIntInt 562ns × (0.96,1.04) 574ns × (0.96,1.06) +2.00% (p=0.013)
BenchmarkFmtFprintfPrefixedInt 442ns × (0.96,1.06) 450ns × (0.97,1.05) +1.73% (p=0.039)
BenchmarkFmtFprintfFloat 640ns × (0.99,1.02) 659ns × (0.99,1.03) +3.01% (p=0.000)
BenchmarkFmtManyArgs 2.19µs × (0.97,1.06) 2.21µs × (0.98,1.02) ~ (p=0.104)
BenchmarkGobDecode 20.0ms × (0.98,1.03) 19.7ms × (0.97,1.04) -1.35% (p=0.035)
BenchmarkGobEncode 17.8ms × (0.96,1.04) 18.0ms × (0.96,1.06) ~ (p=0.131)
BenchmarkGzip 653ms × (0.99,1.02) 652ms × (0.99,1.01) ~ (p=0.572)
BenchmarkGunzip 143ms × (0.99,1.02) 142ms × (1.00,1.01) -0.52% (p=0.005)
BenchmarkHTTPClientServer 110µs × (0.98,1.03) 108µs × (0.99,1.02) -1.90% (p=0.000)
BenchmarkJSONEncode 40.0ms × (0.98,1.05) 41.5ms × (0.97,1.06) +3.89% (p=0.000)
BenchmarkJSONDecode 118ms × (0.99,1.01) 118ms × (0.98,1.01) +0.69% (p=0.010)
BenchmarkMandelbrot200 6.03ms × (1.00,1.01) 6.03ms × (1.00,1.01) ~ (p=0.924)
BenchmarkGoParse 8.43ms × (0.92,1.11) 8.56ms × (0.93,1.05) ~ (p=0.242)
BenchmarkRegexpMatchEasy0_32 180ns × (0.91,1.07) 163ns × (1.00,1.00) -9.33% (p=0.000)
BenchmarkRegexpMatchEasy0_1K 550ns × (0.98,1.02) 558ns × (0.99,1.01) +1.44% (p=0.000)
BenchmarkRegexpMatchEasy1_32 152ns × (0.94,1.05) 139ns × (0.98,1.02) -8.51% (p=0.000)
BenchmarkRegexpMatchEasy1_1K 909ns × (0.98,1.06) 868ns × (0.99,1.02) -4.52% (p=0.000)
BenchmarkRegexpMatchMedium_32 262ns × (0.97,1.03) 253ns × (0.99,1.02) -3.31% (p=0.000)
BenchmarkRegexpMatchMedium_1K 73.8µs × (0.98,1.04) 72.7µs × (1.00,1.01) -1.61% (p=0.001)
BenchmarkRegexpMatchHard_32 3.87µs × (0.99,1.02) 3.87µs × (1.00,1.01) ~ (p=0.791)
BenchmarkRegexpMatchHard_1K 118µs × (0.98,1.04) 117µs × (0.99,1.02) ~ (p=0.110)
BenchmarkRevcomp 1.00s × (0.94,1.10) 0.99s × (0.94,1.09) ~ (p=0.433)
BenchmarkTemplate 140ms × (0.97,1.04) 140ms × (0.99,1.01) ~ (p=0.303)
BenchmarkTimeParse 622ns × (0.99,1.02) 625ns × (0.99,1.01) +0.51% (p=0.001)
BenchmarkTimeFormat 731ns × (0.98,1.04) 719ns × (0.99,1.01) -1.66% (p=0.000)
Change-Id: Ibc3edb59a178adafda50156f46a341f69a17d83f
Reviewed-on: https://go-review.googlesource.com/9721
Reviewed-by: David Chase <drchase@google.com>
2015-04-30 20:35:47 -04:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OAPPEND:
|
2018-04-26 18:30:11 +02:00
|
|
|
// Check for append(x, make([]T, y)...) .
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.CallExpr)
|
2018-04-26 18:30:11 +02:00
|
|
|
if isAppendOfMake(n) {
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
n.Args[0] = o.expr(n.Args[0], nil) // order x
|
|
|
|
|
mk := n.Args[1].(*ir.MakeExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
mk.Len = o.expr(mk.Len, nil) // order y
|
2018-04-26 18:30:11 +02:00
|
|
|
} else {
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.Args)
|
2018-04-26 18:30:11 +02:00
|
|
|
}
|
|
|
|
|
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) {
|
2020-12-10 18:45:35 -05:00
|
|
|
return o.copyExpr(n)
|
cmd/internal/gc: optimize append + write barrier
The code generated for x = append(x, v) is roughly:
t := x
if len(t)+1 > cap(t) {
t = grow(t)
}
t[len(t)] = v
len(t)++
x = t
We used to generate this code as Go pseudocode during walk.
Generate it instead as actual instructions during gen.
Doing so lets us apply a few optimizations. The most important
is that when, as in the above example, the source slice and the
destination slice are the same, the code can instead do:
t := x
if len(t)+1 > cap(t) {
t = grow(t)
x = {base(t), len(t)+1, cap(t)}
} else {
len(x)++
}
t[len(t)] = v
That is, in the fast path that does not reallocate the array,
only the updated length needs to be written back to x,
not the array pointer and not the capacity. This is more like
what you'd write by hand in C. It's faster in general, since
the fast path elides two of the three stores, but it's especially
faster when the form of x is such that the base pointer write
would turn into a write barrier. No write, no barrier.
name old mean new mean delta
BinaryTree17 5.68s × (0.97,1.04) 5.81s × (0.98,1.03) +2.35% (p=0.023)
Fannkuch11 4.41s × (0.98,1.03) 4.35s × (1.00,1.00) ~ (p=0.090)
FmtFprintfEmpty 92.7ns × (0.91,1.16) 86.0ns × (0.94,1.11) -7.31% (p=0.038)
FmtFprintfString 281ns × (0.96,1.08) 276ns × (0.98,1.04) ~ (p=0.219)
FmtFprintfInt 288ns × (0.97,1.06) 274ns × (0.98,1.06) -4.94% (p=0.002)
FmtFprintfIntInt 493ns × (0.97,1.04) 506ns × (0.99,1.01) +2.65% (p=0.009)
FmtFprintfPrefixedInt 423ns × (0.97,1.04) 391ns × (0.99,1.01) -7.52% (p=0.000)
FmtFprintfFloat 598ns × (0.99,1.01) 566ns × (0.99,1.01) -5.27% (p=0.000)
FmtManyArgs 1.89µs × (0.98,1.05) 1.91µs × (0.99,1.01) ~ (p=0.231)
GobDecode 14.8ms × (0.98,1.03) 15.3ms × (0.99,1.02) +3.01% (p=0.000)
GobEncode 12.3ms × (0.98,1.01) 11.5ms × (0.97,1.03) -5.93% (p=0.000)
Gzip 656ms × (0.99,1.05) 645ms × (0.99,1.01) ~ (p=0.055)
Gunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) -0.32% (p=0.034)
HTTPClientServer 91.2µs × (0.97,1.04) 90.5µs × (0.97,1.04) ~ (p=0.468)
JSONEncode 32.6ms × (0.97,1.08) 32.0ms × (0.98,1.03) ~ (p=0.190)
JSONDecode 114ms × (0.97,1.05) 114ms × (0.99,1.01) ~ (p=0.887)
Mandelbrot200 6.11ms × (0.98,1.04) 6.04ms × (1.00,1.01) ~ (p=0.167)
GoParse 6.66ms × (0.97,1.04) 6.47ms × (0.97,1.05) -2.81% (p=0.014)
RegexpMatchEasy0_32 159ns × (0.99,1.00) 171ns × (0.93,1.07) +7.19% (p=0.002)
RegexpMatchEasy0_1K 538ns × (1.00,1.01) 550ns × (0.98,1.01) +2.30% (p=0.000)
RegexpMatchEasy1_32 138ns × (1.00,1.00) 135ns × (0.99,1.02) -1.60% (p=0.000)
RegexpMatchEasy1_1K 869ns × (0.99,1.01) 879ns × (1.00,1.01) +1.08% (p=0.000)
RegexpMatchMedium_32 252ns × (0.99,1.01) 243ns × (1.00,1.00) -3.71% (p=0.000)
RegexpMatchMedium_1K 72.7µs × (1.00,1.00) 70.3µs × (1.00,1.00) -3.34% (p=0.000)
RegexpMatchHard_32 3.85µs × (1.00,1.00) 3.82µs × (1.00,1.01) -0.81% (p=0.000)
RegexpMatchHard_1K 118µs × (1.00,1.00) 117µs × (1.00,1.00) -0.56% (p=0.000)
Revcomp 920ms × (0.97,1.07) 917ms × (0.97,1.04) ~ (p=0.808)
Template 129ms × (0.98,1.03) 114ms × (0.99,1.01) -12.06% (p=0.000)
TimeParse 619ns × (0.99,1.01) 622ns × (0.99,1.01) ~ (p=0.062)
TimeFormat 661ns × (0.98,1.04) 665ns × (0.99,1.01) ~ (p=0.524)
See next CL for combination with a similar optimization for slice.
The benchmarks that are slower in this CL are still faster overall
with the combination of the two.
Change-Id: I2a7421658091b2488c64741b4db15ab6c3b4cb7e
Reviewed-on: https://go-review.googlesource.com/9812
Reviewed-by: David Chase <drchase@google.com>
2015-05-06 12:34:30 -04:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
cmd/internal/gc: optimize append + write barrier
The code generated for x = append(x, v) is roughly:
t := x
if len(t)+1 > cap(t) {
t = grow(t)
}
t[len(t)] = v
len(t)++
x = t
We used to generate this code as Go pseudocode during walk.
Generate it instead as actual instructions during gen.
Doing so lets us apply a few optimizations. The most important
is that when, as in the above example, the source slice and the
destination slice are the same, the code can instead do:
t := x
if len(t)+1 > cap(t) {
t = grow(t)
x = {base(t), len(t)+1, cap(t)}
} else {
len(x)++
}
t[len(t)] = v
That is, in the fast path that does not reallocate the array,
only the updated length needs to be written back to x,
not the array pointer and not the capacity. This is more like
what you'd write by hand in C. It's faster in general, since
the fast path elides two of the three stores, but it's especially
faster when the form of x is such that the base pointer write
would turn into a write barrier. No write, no barrier.
name old mean new mean delta
BinaryTree17 5.68s × (0.97,1.04) 5.81s × (0.98,1.03) +2.35% (p=0.023)
Fannkuch11 4.41s × (0.98,1.03) 4.35s × (1.00,1.00) ~ (p=0.090)
FmtFprintfEmpty 92.7ns × (0.91,1.16) 86.0ns × (0.94,1.11) -7.31% (p=0.038)
FmtFprintfString 281ns × (0.96,1.08) 276ns × (0.98,1.04) ~ (p=0.219)
FmtFprintfInt 288ns × (0.97,1.06) 274ns × (0.98,1.06) -4.94% (p=0.002)
FmtFprintfIntInt 493ns × (0.97,1.04) 506ns × (0.99,1.01) +2.65% (p=0.009)
FmtFprintfPrefixedInt 423ns × (0.97,1.04) 391ns × (0.99,1.01) -7.52% (p=0.000)
FmtFprintfFloat 598ns × (0.99,1.01) 566ns × (0.99,1.01) -5.27% (p=0.000)
FmtManyArgs 1.89µs × (0.98,1.05) 1.91µs × (0.99,1.01) ~ (p=0.231)
GobDecode 14.8ms × (0.98,1.03) 15.3ms × (0.99,1.02) +3.01% (p=0.000)
GobEncode 12.3ms × (0.98,1.01) 11.5ms × (0.97,1.03) -5.93% (p=0.000)
Gzip 656ms × (0.99,1.05) 645ms × (0.99,1.01) ~ (p=0.055)
Gunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) -0.32% (p=0.034)
HTTPClientServer 91.2µs × (0.97,1.04) 90.5µs × (0.97,1.04) ~ (p=0.468)
JSONEncode 32.6ms × (0.97,1.08) 32.0ms × (0.98,1.03) ~ (p=0.190)
JSONDecode 114ms × (0.97,1.05) 114ms × (0.99,1.01) ~ (p=0.887)
Mandelbrot200 6.11ms × (0.98,1.04) 6.04ms × (1.00,1.01) ~ (p=0.167)
GoParse 6.66ms × (0.97,1.04) 6.47ms × (0.97,1.05) -2.81% (p=0.014)
RegexpMatchEasy0_32 159ns × (0.99,1.00) 171ns × (0.93,1.07) +7.19% (p=0.002)
RegexpMatchEasy0_1K 538ns × (1.00,1.01) 550ns × (0.98,1.01) +2.30% (p=0.000)
RegexpMatchEasy1_32 138ns × (1.00,1.00) 135ns × (0.99,1.02) -1.60% (p=0.000)
RegexpMatchEasy1_1K 869ns × (0.99,1.01) 879ns × (1.00,1.01) +1.08% (p=0.000)
RegexpMatchMedium_32 252ns × (0.99,1.01) 243ns × (1.00,1.00) -3.71% (p=0.000)
RegexpMatchMedium_1K 72.7µs × (1.00,1.00) 70.3µs × (1.00,1.00) -3.34% (p=0.000)
RegexpMatchHard_32 3.85µs × (1.00,1.00) 3.82µs × (1.00,1.01) -0.81% (p=0.000)
RegexpMatchHard_1K 118µs × (1.00,1.00) 117µs × (1.00,1.00) -0.56% (p=0.000)
Revcomp 920ms × (0.97,1.07) 917ms × (0.97,1.04) ~ (p=0.808)
Template 129ms × (0.98,1.03) 114ms × (0.99,1.01) -12.06% (p=0.000)
TimeParse 619ns × (0.99,1.01) 622ns × (0.99,1.01) ~ (p=0.062)
TimeFormat 661ns × (0.98,1.04) 665ns × (0.99,1.01) ~ (p=0.524)
See next CL for combination with a similar optimization for slice.
The benchmarks that are slower in this CL are still faster overall
with the combination of the two.
Change-Id: I2a7421658091b2488c64741b4db15ab6c3b4cb7e
Reviewed-on: https://go-review.googlesource.com/9812
Reviewed-by: David Chase <drchase@google.com>
2015-05-06 12:34:30 -04:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.SliceExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2020-12-23 06:06:31 -08:00
|
|
|
n.Low = o.cheapExpr(o.expr(n.Low, nil))
|
|
|
|
|
n.High = o.cheapExpr(o.expr(n.High, nil))
|
|
|
|
|
n.Max = o.cheapExpr(o.expr(n.Max, nil))
|
[dev.regabi] cmd/compile: move helpers into package ir [generated]
[git-generate]
cd src/cmd/compile/internal/gc
sed -i '' 's/TestBuiltin.*/& t.Skip("mkbuiltin needs fixing")/' builtin_test.go
gofmt -w builtin_test.go
rf '
# Inline a few little-used constructors to avoid bringing them.
ex {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var typ *types.Type
var sym *types.Sym
var str string
symfield(sym, typ) -> ir.NewField(base.Pos, sym, nil, typ)
anonfield(typ) -> ir.NewField(base.Pos, nil, nil, typ)
namedfield(str, typ) -> ir.NewField(base.Pos, lookup(str), nil, typ)
var cp *ir.CallPartExpr
callpartMethod(cp) -> cp.Method
var n ir.Node
callpartMethod(n) -> n.(*ir.CallPartExpr).Method
var ns []ir.Node
liststmt(ns) -> ir.NewBlockStmt(src.NoXPos, ns)
}
rm symfield anonfield namedfield liststmt callpartMethod
mv maxStackVarSize MaxStackVarSize
mv maxImplicitStackVarSize MaxImplicitStackVarSize
mv smallArrayBytes MaxSmallArraySize
mv MaxStackVarSize cfg.go
mv nodbool NewBool
mv nodintconst NewInt
mv nodstr NewString
mv NewBool NewInt NewString const.go
mv Mpprec ConstPrec
mv bigFloatVal BigFloat
mv doesoverflow ConstOverflow
mv isGoConst IsConstNode
mv smallintconst IsSmallIntConst
mv isZero IsZero
mv islvalue IsAssignable
mv staticValue StaticValue
mv samesafeexpr SameSafeExpr
mv checkPtr ShouldCheckPtr
mv isReflectHeaderDataField IsReflectHeaderDataField
mv paramNnames ParamNames
mv methodSym MethodSym
mv methodSymSuffix MethodSymSuffix
mv methodExprFunc MethodExprFunc
mv methodExprName MethodExprName
mv IsZero IsAssignable StaticValue staticValue1 reassigned \
IsIntrinsicCall \
SameSafeExpr ShouldCheckPtr IsReflectHeaderDataField \
ParamNames MethodSym MethodSymSuffix \
MethodExprName MethodExprFunc \
expr.go
mv Curfn CurFunc
mv funcsymname FuncSymName
mv newFuncNameAt NewFuncNameAt
mv setNodeNameFunc MarkFunc
mv CurFunc FuncSymName NewFuncNameAt MarkFunc func.go
mv isParamStackCopy IsParamStackCopy
mv isParamHeapCopy IsParamHeapCopy
mv nodfp RegFP
mv IsParamStackCopy IsParamHeapCopy RegFP name.go
mv hasUniquePos HasUniquePos
mv setlineno SetPos
mv initExpr InitExpr
mv hasNamedResults HasNamedResults
mv outervalue OuterValue
mv HasNamedResults HasUniquePos SetPos InitExpr OuterValue EscNever node.go
mv visitBottomUp VisitFuncsBottomUp # scc.go
mv cfg.go \
NewBool NewInt NewString \ # parts of const.go
ConstPrec BigFloat ConstOverflow IsConstNode IsSmallIntConst \
expr.go func.go name.go node.go scc.go \
cmd/compile/internal/ir
'
Change-Id: I13402c5a2cedbf78d993a1eae2940718f23ac166
Reviewed-on: https://go-review.googlesource.com/c/go/+/279421
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:38:15 -05:00
|
|
|
if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) {
|
2020-12-10 18:45:35 -05:00
|
|
|
return o.copyExpr(n)
|
cmd/internal/gc: optimize slice + write barrier
The code generated for a slice x[i:j] or x[i:j:k] computes the entire
new slice (base, len, cap) and then uses it as the evaluation of the
slice expression.
If the slice is part of an update x = x[i:j] or x = x[i:j:k], there are
opportunities to avoid computing some of these fields.
For x = x[0:i], we know that only the len is changing;
base can be ignored completely, and cap can be left unmodified.
For x = x[0:i:j], we know that only len and cap are changing;
base can be ignored completely.
For x = x[i:i], we know that the resulting cap is zero, and we don't
adjust the base during a slice producing a zero-cap result,
so again base can be ignored completely.
No write to base, no write barrier.
The old slice code was trying to work at a Go syntax level, mainly
because that was how you wrote code just once instead of once
per architecture. Now the compiler is factored a bit better and we
can implement slice during code generation but still have one copy
of the code. So the new code is working at that lower level.
(It must, to update only parts of the result.)
This CL by itself:
name old mean new mean delta
BinaryTree17 5.81s × (0.98,1.03) 5.71s × (0.96,1.05) ~ (p=0.101)
Fannkuch11 4.35s × (1.00,1.00) 4.39s × (1.00,1.00) +0.79% (p=0.000)
FmtFprintfEmpty 86.0ns × (0.94,1.11) 82.6ns × (0.98,1.04) -3.86% (p=0.048)
FmtFprintfString 276ns × (0.98,1.04) 273ns × (0.98,1.02) ~ (p=0.235)
FmtFprintfInt 274ns × (0.98,1.06) 270ns × (0.99,1.01) ~ (p=0.119)
FmtFprintfIntInt 506ns × (0.99,1.01) 475ns × (0.99,1.01) -6.02% (p=0.000)
FmtFprintfPrefixedInt 391ns × (0.99,1.01) 393ns × (1.00,1.01) ~ (p=0.139)
FmtFprintfFloat 566ns × (0.99,1.01) 574ns × (1.00,1.01) +1.33% (p=0.001)
FmtManyArgs 1.91µs × (0.99,1.01) 1.87µs × (0.99,1.02) -1.83% (p=0.000)
GobDecode 15.3ms × (0.99,1.02) 15.0ms × (0.98,1.05) -1.84% (p=0.042)
GobEncode 11.5ms × (0.97,1.03) 11.4ms × (0.99,1.03) ~ (p=0.152)
Gzip 645ms × (0.99,1.01) 647ms × (0.99,1.01) ~ (p=0.265)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.90% (p=0.000)
HTTPClientServer 90.5µs × (0.97,1.04) 88.5µs × (0.99,1.03) -2.27% (p=0.014)
JSONEncode 32.0ms × (0.98,1.03) 29.6ms × (0.98,1.01) -7.51% (p=0.000)
JSONDecode 114ms × (0.99,1.01) 104ms × (1.00,1.01) -8.60% (p=0.000)
Mandelbrot200 6.04ms × (1.00,1.01) 6.02ms × (1.00,1.00) ~ (p=0.057)
GoParse 6.47ms × (0.97,1.05) 6.37ms × (0.97,1.04) ~ (p=0.105)
RegexpMatchEasy0_32 171ns × (0.93,1.07) 152ns × (0.99,1.01) -11.09% (p=0.000)
RegexpMatchEasy0_1K 550ns × (0.98,1.01) 530ns × (1.00,1.00) -3.78% (p=0.000)
RegexpMatchEasy1_32 135ns × (0.99,1.02) 134ns × (0.99,1.01) -1.33% (p=0.002)
RegexpMatchEasy1_1K 879ns × (1.00,1.01) 865ns × (1.00,1.00) -1.58% (p=0.000)
RegexpMatchMedium_32 243ns × (1.00,1.00) 233ns × (1.00,1.00) -4.30% (p=0.000)
RegexpMatchMedium_1K 70.3µs × (1.00,1.00) 69.5µs × (1.00,1.00) -1.13% (p=0.000)
RegexpMatchHard_32 3.82µs × (1.00,1.01) 3.74µs × (1.00,1.00) -1.95% (p=0.000)
RegexpMatchHard_1K 117µs × (1.00,1.00) 115µs × (1.00,1.00) -1.69% (p=0.000)
Revcomp 917ms × (0.97,1.04) 920ms × (0.97,1.04) ~ (p=0.786)
Template 114ms × (0.99,1.01) 117ms × (0.99,1.01) +2.58% (p=0.000)
TimeParse 622ns × (0.99,1.01) 615ns × (0.99,1.00) -1.06% (p=0.000)
TimeFormat 665ns × (0.99,1.01) 654ns × (0.99,1.00) -1.70% (p=0.000)
This CL and previous CL (append) combined:
name old mean new mean delta
BinaryTree17 5.68s × (0.97,1.04) 5.71s × (0.96,1.05) ~ (p=0.638)
Fannkuch11 4.41s × (0.98,1.03) 4.39s × (1.00,1.00) ~ (p=0.474)
FmtFprintfEmpty 92.7ns × (0.91,1.16) 82.6ns × (0.98,1.04) -10.89% (p=0.004)
FmtFprintfString 281ns × (0.96,1.08) 273ns × (0.98,1.02) ~ (p=0.078)
FmtFprintfInt 288ns × (0.97,1.06) 270ns × (0.99,1.01) -6.37% (p=0.000)
FmtFprintfIntInt 493ns × (0.97,1.04) 475ns × (0.99,1.01) -3.53% (p=0.002)
FmtFprintfPrefixedInt 423ns × (0.97,1.04) 393ns × (1.00,1.01) -7.07% (p=0.000)
FmtFprintfFloat 598ns × (0.99,1.01) 574ns × (1.00,1.01) -4.02% (p=0.000)
FmtManyArgs 1.89µs × (0.98,1.05) 1.87µs × (0.99,1.02) ~ (p=0.305)
GobDecode 14.8ms × (0.98,1.03) 15.0ms × (0.98,1.05) ~ (p=0.237)
GobEncode 12.3ms × (0.98,1.01) 11.4ms × (0.99,1.03) -6.95% (p=0.000)
Gzip 656ms × (0.99,1.05) 647ms × (0.99,1.01) ~ (p=0.101)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.58% (p=0.001)
HTTPClientServer 91.2µs × (0.97,1.04) 88.5µs × (0.99,1.03) -3.02% (p=0.003)
JSONEncode 32.6ms × (0.97,1.08) 29.6ms × (0.98,1.01) -9.10% (p=0.000)
JSONDecode 114ms × (0.97,1.05) 104ms × (1.00,1.01) -8.74% (p=0.000)
Mandelbrot200 6.11ms × (0.98,1.04) 6.02ms × (1.00,1.00) ~ (p=0.090)
GoParse 6.66ms × (0.97,1.04) 6.37ms × (0.97,1.04) -4.41% (p=0.000)
RegexpMatchEasy0_32 159ns × (0.99,1.00) 152ns × (0.99,1.01) -4.69% (p=0.000)
RegexpMatchEasy0_1K 538ns × (1.00,1.01) 530ns × (1.00,1.00) -1.57% (p=0.000)
RegexpMatchEasy1_32 138ns × (1.00,1.00) 134ns × (0.99,1.01) -2.91% (p=0.000)
RegexpMatchEasy1_1K 869ns × (0.99,1.01) 865ns × (1.00,1.00) -0.51% (p=0.012)
RegexpMatchMedium_32 252ns × (0.99,1.01) 233ns × (1.00,1.00) -7.85% (p=0.000)
RegexpMatchMedium_1K 72.7µs × (1.00,1.00) 69.5µs × (1.00,1.00) -4.43% (p=0.000)
RegexpMatchHard_32 3.85µs × (1.00,1.00) 3.74µs × (1.00,1.00) -2.74% (p=0.000)
RegexpMatchHard_1K 118µs × (1.00,1.00) 115µs × (1.00,1.00) -2.24% (p=0.000)
Revcomp 920ms × (0.97,1.07) 920ms × (0.97,1.04) ~ (p=0.998)
Template 129ms × (0.98,1.03) 117ms × (0.99,1.01) -9.79% (p=0.000)
TimeParse 619ns × (0.99,1.01) 615ns × (0.99,1.00) -0.57% (p=0.011)
TimeFormat 661ns × (0.98,1.04) 654ns × (0.99,1.00) ~ (p=0.223)
Change-Id: If054d81ab2c71d8d62cf54b5b1fac2af66b387fc
Reviewed-on: https://go-review.googlesource.com/9813
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-05-06 12:35:53 -04:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
cmd/internal/gc: optimize slice + write barrier
The code generated for a slice x[i:j] or x[i:j:k] computes the entire
new slice (base, len, cap) and then uses it as the evaluation of the
slice expression.
If the slice is part of an update x = x[i:j] or x = x[i:j:k], there are
opportunities to avoid computing some of these fields.
For x = x[0:i], we know that only the len is changing;
base can be ignored completely, and cap can be left unmodified.
For x = x[0:i:j], we know that only len and cap are changing;
base can be ignored completely.
For x = x[i:i], we know that the resulting cap is zero, and we don't
adjust the base during a slice producing a zero-cap result,
so again base can be ignored completely.
No write to base, no write barrier.
The old slice code was trying to work at a Go syntax level, mainly
because that was how you wrote code just once instead of once
per architecture. Now the compiler is factored a bit better and we
can implement slice during code generation but still have one copy
of the code. So the new code is working at that lower level.
(It must, to update only parts of the result.)
This CL by itself:
name old mean new mean delta
BinaryTree17 5.81s × (0.98,1.03) 5.71s × (0.96,1.05) ~ (p=0.101)
Fannkuch11 4.35s × (1.00,1.00) 4.39s × (1.00,1.00) +0.79% (p=0.000)
FmtFprintfEmpty 86.0ns × (0.94,1.11) 82.6ns × (0.98,1.04) -3.86% (p=0.048)
FmtFprintfString 276ns × (0.98,1.04) 273ns × (0.98,1.02) ~ (p=0.235)
FmtFprintfInt 274ns × (0.98,1.06) 270ns × (0.99,1.01) ~ (p=0.119)
FmtFprintfIntInt 506ns × (0.99,1.01) 475ns × (0.99,1.01) -6.02% (p=0.000)
FmtFprintfPrefixedInt 391ns × (0.99,1.01) 393ns × (1.00,1.01) ~ (p=0.139)
FmtFprintfFloat 566ns × (0.99,1.01) 574ns × (1.00,1.01) +1.33% (p=0.001)
FmtManyArgs 1.91µs × (0.99,1.01) 1.87µs × (0.99,1.02) -1.83% (p=0.000)
GobDecode 15.3ms × (0.99,1.02) 15.0ms × (0.98,1.05) -1.84% (p=0.042)
GobEncode 11.5ms × (0.97,1.03) 11.4ms × (0.99,1.03) ~ (p=0.152)
Gzip 645ms × (0.99,1.01) 647ms × (0.99,1.01) ~ (p=0.265)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.90% (p=0.000)
HTTPClientServer 90.5µs × (0.97,1.04) 88.5µs × (0.99,1.03) -2.27% (p=0.014)
JSONEncode 32.0ms × (0.98,1.03) 29.6ms × (0.98,1.01) -7.51% (p=0.000)
JSONDecode 114ms × (0.99,1.01) 104ms × (1.00,1.01) -8.60% (p=0.000)
Mandelbrot200 6.04ms × (1.00,1.01) 6.02ms × (1.00,1.00) ~ (p=0.057)
GoParse 6.47ms × (0.97,1.05) 6.37ms × (0.97,1.04) ~ (p=0.105)
RegexpMatchEasy0_32 171ns × (0.93,1.07) 152ns × (0.99,1.01) -11.09% (p=0.000)
RegexpMatchEasy0_1K 550ns × (0.98,1.01) 530ns × (1.00,1.00) -3.78% (p=0.000)
RegexpMatchEasy1_32 135ns × (0.99,1.02) 134ns × (0.99,1.01) -1.33% (p=0.002)
RegexpMatchEasy1_1K 879ns × (1.00,1.01) 865ns × (1.00,1.00) -1.58% (p=0.000)
RegexpMatchMedium_32 243ns × (1.00,1.00) 233ns × (1.00,1.00) -4.30% (p=0.000)
RegexpMatchMedium_1K 70.3µs × (1.00,1.00) 69.5µs × (1.00,1.00) -1.13% (p=0.000)
RegexpMatchHard_32 3.82µs × (1.00,1.01) 3.74µs × (1.00,1.00) -1.95% (p=0.000)
RegexpMatchHard_1K 117µs × (1.00,1.00) 115µs × (1.00,1.00) -1.69% (p=0.000)
Revcomp 917ms × (0.97,1.04) 920ms × (0.97,1.04) ~ (p=0.786)
Template 114ms × (0.99,1.01) 117ms × (0.99,1.01) +2.58% (p=0.000)
TimeParse 622ns × (0.99,1.01) 615ns × (0.99,1.00) -1.06% (p=0.000)
TimeFormat 665ns × (0.99,1.01) 654ns × (0.99,1.00) -1.70% (p=0.000)
This CL and previous CL (append) combined:
name old mean new mean delta
BinaryTree17 5.68s × (0.97,1.04) 5.71s × (0.96,1.05) ~ (p=0.638)
Fannkuch11 4.41s × (0.98,1.03) 4.39s × (1.00,1.00) ~ (p=0.474)
FmtFprintfEmpty 92.7ns × (0.91,1.16) 82.6ns × (0.98,1.04) -10.89% (p=0.004)
FmtFprintfString 281ns × (0.96,1.08) 273ns × (0.98,1.02) ~ (p=0.078)
FmtFprintfInt 288ns × (0.97,1.06) 270ns × (0.99,1.01) -6.37% (p=0.000)
FmtFprintfIntInt 493ns × (0.97,1.04) 475ns × (0.99,1.01) -3.53% (p=0.002)
FmtFprintfPrefixedInt 423ns × (0.97,1.04) 393ns × (1.00,1.01) -7.07% (p=0.000)
FmtFprintfFloat 598ns × (0.99,1.01) 574ns × (1.00,1.01) -4.02% (p=0.000)
FmtManyArgs 1.89µs × (0.98,1.05) 1.87µs × (0.99,1.02) ~ (p=0.305)
GobDecode 14.8ms × (0.98,1.03) 15.0ms × (0.98,1.05) ~ (p=0.237)
GobEncode 12.3ms × (0.98,1.01) 11.4ms × (0.99,1.03) -6.95% (p=0.000)
Gzip 656ms × (0.99,1.05) 647ms × (0.99,1.01) ~ (p=0.101)
Gunzip 142ms × (1.00,1.00) 143ms × (1.00,1.01) +0.58% (p=0.001)
HTTPClientServer 91.2µs × (0.97,1.04) 88.5µs × (0.99,1.03) -3.02% (p=0.003)
JSONEncode 32.6ms × (0.97,1.08) 29.6ms × (0.98,1.01) -9.10% (p=0.000)
JSONDecode 114ms × (0.97,1.05) 104ms × (1.00,1.01) -8.74% (p=0.000)
Mandelbrot200 6.11ms × (0.98,1.04) 6.02ms × (1.00,1.00) ~ (p=0.090)
GoParse 6.66ms × (0.97,1.04) 6.37ms × (0.97,1.04) -4.41% (p=0.000)
RegexpMatchEasy0_32 159ns × (0.99,1.00) 152ns × (0.99,1.01) -4.69% (p=0.000)
RegexpMatchEasy0_1K 538ns × (1.00,1.01) 530ns × (1.00,1.00) -1.57% (p=0.000)
RegexpMatchEasy1_32 138ns × (1.00,1.00) 134ns × (0.99,1.01) -2.91% (p=0.000)
RegexpMatchEasy1_1K 869ns × (0.99,1.01) 865ns × (1.00,1.00) -0.51% (p=0.012)
RegexpMatchMedium_32 252ns × (0.99,1.01) 233ns × (1.00,1.00) -7.85% (p=0.000)
RegexpMatchMedium_1K 72.7µs × (1.00,1.00) 69.5µs × (1.00,1.00) -4.43% (p=0.000)
RegexpMatchHard_32 3.85µs × (1.00,1.00) 3.74µs × (1.00,1.00) -2.74% (p=0.000)
RegexpMatchHard_1K 118µs × (1.00,1.00) 115µs × (1.00,1.00) -2.24% (p=0.000)
Revcomp 920ms × (0.97,1.07) 920ms × (0.97,1.04) ~ (p=0.998)
Template 129ms × (0.98,1.03) 117ms × (0.99,1.01) -9.79% (p=0.000)
TimeParse 619ns × (0.99,1.01) 615ns × (0.99,1.00) -0.57% (p=0.011)
TimeFormat 661ns × (0.98,1.04) 654ns × (0.99,1.00) ~ (p=0.223)
Change-Id: If054d81ab2c71d8d62cf54b5b1fac2af66b387fc
Reviewed-on: https://go-review.googlesource.com/9813
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-05-06 12:35:53 -04:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OCLOSURE:
|
2020-12-10 18:45:35 -05:00
|
|
|
n := n.(*ir.ClosureExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.Transient() && len(n.Func.ClosureVars) > 0 {
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
n.Prealloc = o.newTemp(typecheck.ClosureType(n), false)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
case ir.OCALLPART:
|
2020-12-28 16:14:11 -08:00
|
|
|
n := n.(*ir.SelectorExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
if n.Transient() {
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
t := typecheck.PartialCallType(n)
|
2020-12-17 08:49:22 -05:00
|
|
|
n.Prealloc = o.newTemp(t, false)
|
2020-12-10 18:45:35 -05:00
|
|
|
}
|
|
|
|
|
return n
|
|
|
|
|
|
|
|
|
|
case ir.OSLICELIT:
|
2020-12-17 08:49:22 -05:00
|
|
|
n := n.(*ir.CompLitExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
o.exprList(n.List)
|
2019-10-08 14:21:17 -07:00
|
|
|
if n.Transient() {
|
2020-12-17 18:47:26 -08:00
|
|
|
t := types.NewArray(n.Type().Elem(), n.Len)
|
2020-12-17 08:49:22 -05:00
|
|
|
n.Prealloc = o.newTemp(t, false)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ODOTTYPE, ir.ODOTTYPE2:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.TypeAssertExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2020-12-23 00:08:03 -05:00
|
|
|
if !types.IsDirectIface(n.Type()) || base.Flag.Cfg.Instrumenting {
|
2020-12-10 18:45:35 -05:00
|
|
|
return o.copyExprClear(n)
|
2015-03-20 00:06:10 -04:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2015-03-20 00:06:10 -04:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.ORECV:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.UnaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
2020-12-10 18:45:35 -05:00
|
|
|
return o.copyExprClear(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.BinaryExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.expr(n.X, nil)
|
|
|
|
|
n.Y = o.expr(n.Y, nil)
|
2018-10-10 16:47:47 -07:00
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
t := n.X.Type()
|
2018-10-10 16:47:47 -07:00
|
|
|
switch {
|
|
|
|
|
case t.IsString():
|
|
|
|
|
// Mark string(byteSlice) arguments to reuse byteSlice backing
|
|
|
|
|
// buffer during conversion. String comparison does not
|
|
|
|
|
// memorize the strings for later use, so it is safe.
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.X.Op() == ir.OBYTES2STR {
|
|
|
|
|
n.X.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
|
2018-10-10 16:47:47 -07:00
|
|
|
}
|
2020-12-23 00:02:08 -05:00
|
|
|
if n.Y.Op() == ir.OBYTES2STR {
|
|
|
|
|
n.Y.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
|
2018-10-10 16:47:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case t.IsStruct() || t.IsArray():
|
2015-02-13 14:40:36 -05:00
|
|
|
// for complex comparisons, we need both args to be
|
|
|
|
|
// addressable so we can pass them to the runtime.
|
2020-12-23 00:02:08 -05:00
|
|
|
n.X = o.addrTemp(n.X)
|
|
|
|
|
n.Y = o.addrTemp(n.Y)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
|
|
|
|
|
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-19 21:09:22 -05:00
|
|
|
case ir.OMAPLIT:
|
2019-04-29 12:19:30 -07:00
|
|
|
// Order map by converting:
|
|
|
|
|
// map[int]int{
|
|
|
|
|
// a(): b(),
|
|
|
|
|
// c(): d(),
|
|
|
|
|
// e(): f(),
|
|
|
|
|
// }
|
|
|
|
|
// to
|
|
|
|
|
// m := map[int]int{}
|
|
|
|
|
// m[a()] = b()
|
|
|
|
|
// m[c()] = d()
|
|
|
|
|
// m[e()] = f()
|
|
|
|
|
// Then order the result.
|
|
|
|
|
// Without this special case, order would otherwise compute all
|
|
|
|
|
// the keys and values before storing any of them to the map.
|
|
|
|
|
// See issue 26552.
|
[dev.regabi] cmd/compile: remove Node.Left etc [generated]
This automated CL adds type assertions on the true branches of
n.Op() equality tests, to redeclare n with a more specific type, when
it is safe to do so. (That is, when n is not reassigned with a more
general type, when n is not reassigned and then used outside the
scope, and so on.) All the "unsafe" times that the automated tool
would avoid have been removed or rewritten in earlier CLs, so that
after this CL and the next one, which removes the use of ir.Nod,
every use of the Left, Right, and so on methods is done using concrete
types, never the Node interface.
Having done that, the CL locks in the progress by deleting many of
the access methods, including Left, SetLeft and so on, from the
Node interface.
There are still uses of Name, Func, Sym, some of the tracking
bits, and a few other miscellaneous fields, but all the main access
methods are gone from the Node interface. The others will be cleaned
up in smaller CLs.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf 'typeassert {
import "cmd/compile/internal/ir"
var n ir.Node
n.Op() == ir.OADD -> n.(*ir.BinaryExpr)
n.Op() == ir.OADDR -> n.(*ir.AddrExpr)
n.Op() == ir.OADDSTR -> n.(*ir.AddStringExpr)
n.Op() == ir.OALIGNOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OAND -> n.(*ir.BinaryExpr)
n.Op() == ir.OANDAND -> n.(*ir.LogicalExpr)
n.Op() == ir.OANDNOT -> n.(*ir.BinaryExpr)
n.Op() == ir.OAPPEND -> n.(*ir.CallExpr)
n.Op() == ir.OARRAYLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OAS -> n.(*ir.AssignStmt)
n.Op() == ir.OAS2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2DOTTYPE -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2FUNC -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2MAPR -> n.(*ir.AssignListStmt)
n.Op() == ir.OAS2RECV -> n.(*ir.AssignListStmt)
n.Op() == ir.OASOP -> n.(*ir.AssignOpStmt)
n.Op() == ir.OBITNOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OBLOCK -> n.(*ir.BlockStmt)
n.Op() == ir.OBREAK -> n.(*ir.BranchStmt)
n.Op() == ir.OBYTES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.OBYTES2STRTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OCALL -> n.(*ir.CallExpr)
n.Op() == ir.OCALLFUNC -> n.(*ir.CallExpr)
n.Op() == ir.OCALLINTER -> n.(*ir.CallExpr)
n.Op() == ir.OCALLMETH -> n.(*ir.CallExpr)
n.Op() == ir.OCALLPART -> n.(*ir.CallPartExpr)
n.Op() == ir.OCAP -> n.(*ir.UnaryExpr)
n.Op() == ir.OCASE -> n.(*ir.CaseStmt)
n.Op() == ir.OCFUNC -> n.(*ir.UnaryExpr)
n.Op() == ir.OCHECKNIL -> n.(*ir.UnaryExpr)
n.Op() == ir.OCLOSE -> n.(*ir.UnaryExpr)
n.Op() == ir.OCOMPLEX -> n.(*ir.BinaryExpr)
n.Op() == ir.OCOMPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OCONTINUE -> n.(*ir.BranchStmt)
n.Op() == ir.OCONV -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVIFACE -> n.(*ir.ConvExpr)
n.Op() == ir.OCONVNOP -> n.(*ir.ConvExpr)
n.Op() == ir.OCOPY -> n.(*ir.BinaryExpr)
n.Op() == ir.ODCL -> n.(*ir.Decl)
n.Op() == ir.ODCLCONST -> n.(*ir.Decl)
n.Op() == ir.ODCLFUNC -> n.(*ir.Func)
n.Op() == ir.ODCLTYPE -> n.(*ir.Decl)
n.Op() == ir.ODEFER -> n.(*ir.GoDeferStmt)
n.Op() == ir.ODELETE -> n.(*ir.CallExpr)
n.Op() == ir.ODEREF -> n.(*ir.StarExpr)
n.Op() == ir.ODIV -> n.(*ir.BinaryExpr)
n.Op() == ir.ODOT -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTINTER -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTMETH -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTPTR -> n.(*ir.SelectorExpr)
n.Op() == ir.ODOTTYPE -> n.(*ir.TypeAssertExpr)
n.Op() == ir.ODOTTYPE2 -> n.(*ir.TypeAssertExpr)
n.Op() == ir.OEFACE -> n.(*ir.BinaryExpr)
n.Op() == ir.OEQ -> n.(*ir.BinaryExpr)
n.Op() == ir.OFALL -> n.(*ir.BranchStmt)
n.Op() == ir.OFOR -> n.(*ir.ForStmt)
n.Op() == ir.OFORUNTIL -> n.(*ir.ForStmt)
n.Op() == ir.OGE -> n.(*ir.BinaryExpr)
n.Op() == ir.OGETG -> n.(*ir.CallExpr)
n.Op() == ir.OGO -> n.(*ir.GoDeferStmt)
n.Op() == ir.OGOTO -> n.(*ir.BranchStmt)
n.Op() == ir.OGT -> n.(*ir.BinaryExpr)
n.Op() == ir.OIDATA -> n.(*ir.UnaryExpr)
n.Op() == ir.OIF -> n.(*ir.IfStmt)
n.Op() == ir.OIMAG -> n.(*ir.UnaryExpr)
n.Op() == ir.OINDEX -> n.(*ir.IndexExpr)
n.Op() == ir.OINDEXMAP -> n.(*ir.IndexExpr)
n.Op() == ir.OINLCALL -> n.(*ir.InlinedCallExpr)
n.Op() == ir.OINLMARK -> n.(*ir.InlineMarkStmt)
n.Op() == ir.OITAB -> n.(*ir.UnaryExpr)
n.Op() == ir.OKEY -> n.(*ir.KeyExpr)
n.Op() == ir.OLABEL -> n.(*ir.LabelStmt)
n.Op() == ir.OLE -> n.(*ir.BinaryExpr)
n.Op() == ir.OLEN -> n.(*ir.UnaryExpr)
n.Op() == ir.OLSH -> n.(*ir.BinaryExpr)
n.Op() == ir.OLT -> n.(*ir.BinaryExpr)
n.Op() == ir.OMAKE -> n.(*ir.CallExpr)
n.Op() == ir.OMAKECHAN -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKEMAP -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICE -> n.(*ir.MakeExpr)
n.Op() == ir.OMAKESLICECOPY -> n.(*ir.MakeExpr)
n.Op() == ir.OMAPLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OMETHEXPR -> n.(*ir.MethodExpr)
n.Op() == ir.OMOD -> n.(*ir.BinaryExpr)
n.Op() == ir.OMUL -> n.(*ir.BinaryExpr)
n.Op() == ir.ONAME -> n.(*ir.Name)
n.Op() == ir.ONE -> n.(*ir.BinaryExpr)
n.Op() == ir.ONEG -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEW -> n.(*ir.UnaryExpr)
n.Op() == ir.ONEWOBJ -> n.(*ir.UnaryExpr)
n.Op() == ir.ONIL -> n.(*ir.NilExpr)
n.Op() == ir.ONOT -> n.(*ir.UnaryExpr)
n.Op() == ir.OOFFSETOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OOR -> n.(*ir.BinaryExpr)
n.Op() == ir.OOROR -> n.(*ir.LogicalExpr)
n.Op() == ir.OPACK -> n.(*ir.PkgName)
n.Op() == ir.OPANIC -> n.(*ir.UnaryExpr)
n.Op() == ir.OPAREN -> n.(*ir.ParenExpr)
n.Op() == ir.OPLUS -> n.(*ir.UnaryExpr)
n.Op() == ir.OPRINT -> n.(*ir.CallExpr)
n.Op() == ir.OPRINTN -> n.(*ir.CallExpr)
n.Op() == ir.OPTRLIT -> n.(*ir.AddrExpr)
n.Op() == ir.ORANGE -> n.(*ir.RangeStmt)
n.Op() == ir.OREAL -> n.(*ir.UnaryExpr)
n.Op() == ir.ORECOVER -> n.(*ir.CallExpr)
n.Op() == ir.ORECV -> n.(*ir.UnaryExpr)
n.Op() == ir.ORESULT -> n.(*ir.ResultExpr)
n.Op() == ir.ORETJMP -> n.(*ir.BranchStmt)
n.Op() == ir.ORETURN -> n.(*ir.ReturnStmt)
n.Op() == ir.ORSH -> n.(*ir.BinaryExpr)
n.Op() == ir.ORUNES2STR -> n.(*ir.ConvExpr)
n.Op() == ir.ORUNESTR -> n.(*ir.ConvExpr)
n.Op() == ir.OSELECT -> n.(*ir.SelectStmt)
n.Op() == ir.OSELRECV2 -> n.(*ir.AssignListStmt)
n.Op() == ir.OSEND -> n.(*ir.SendStmt)
n.Op() == ir.OSIZEOF -> n.(*ir.UnaryExpr)
n.Op() == ir.OSLICE -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3 -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICE3ARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEARR -> n.(*ir.SliceExpr)
n.Op() == ir.OSLICEHEADER -> n.(*ir.SliceHeaderExpr)
n.Op() == ir.OSLICELIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSLICESTR -> n.(*ir.SliceExpr)
n.Op() == ir.OSPTR -> n.(*ir.UnaryExpr)
n.Op() == ir.OSTR2BYTES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2BYTESTMP -> n.(*ir.ConvExpr)
n.Op() == ir.OSTR2RUNES -> n.(*ir.ConvExpr)
n.Op() == ir.OSTRUCTLIT -> n.(*ir.CompLitExpr)
n.Op() == ir.OSUB -> n.(*ir.BinaryExpr)
n.Op() == ir.OSWITCH -> n.(*ir.SwitchStmt)
n.Op() == ir.OTYPESW -> n.(*ir.TypeSwitchGuard)
n.Op() == ir.OVARDEF -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARKILL -> n.(*ir.UnaryExpr)
n.Op() == ir.OVARLIVE -> n.(*ir.UnaryExpr)
n.Op() == ir.OXDOT -> n.(*ir.SelectorExpr)
n.Op() == ir.OXOR -> n.(*ir.BinaryExpr)
}
'
cd ../ir
rf '
rm \
Node.SetOp \
miniNode.SetOp \
Node.Func \
miniNode.Func \
Node.Left Node.SetLeft \
miniNode.Left miniNode.SetLeft \
Node.Right Node.SetRight \
miniNode.Right miniNode.SetRight \
Node.List Node.PtrList Node.SetList \
miniNode.List miniNode.PtrList miniNode.SetList \
Node.Rlist Node.PtrRlist Node.SetRlist \
miniNode.Rlist miniNode.PtrRlist miniNode.SetRlist \
Node.Body Node.PtrBody Node.SetBody \
miniNode.Body miniNode.PtrBody miniNode.SetBody \
Node.SubOp Node.SetSubOp \
miniNode.SubOp miniNode.SetSubOp \
Node.SetSym \
miniNode.SetSym \
Node.Offset Node.SetOffset \
miniNode.Offset miniNode.SetOffset \
Node.Class Node.SetClass \
miniNode.Class miniNode.SetClass \
Node.Iota Node.SetIota \
miniNode.Iota miniNode.SetIota \
Node.Colas Node.SetColas \
miniNode.Colas miniNode.SetColas \
Node.Transient Node.SetTransient \
miniNode.Transient miniNode.SetTransient \
Node.Implicit Node.SetImplicit \
miniNode.Implicit miniNode.SetImplicit \
Node.IsDDD Node.SetIsDDD \
miniNode.IsDDD miniNode.SetIsDDD \
Node.MarkReadonly \
miniNode.MarkReadonly \
Node.Likely Node.SetLikely \
miniNode.Likely miniNode.SetLikely \
Node.SliceBounds Node.SetSliceBounds \
miniNode.SliceBounds miniNode.SetSliceBounds \
Node.NoInline Node.SetNoInline \
miniNode.NoInline miniNode.SetNoInline \
Node.IndexMapLValue Node.SetIndexMapLValue \
miniNode.IndexMapLValue miniNode.SetIndexMapLValue \
Node.ResetAux \
miniNode.ResetAux \
Node.HasBreak Node.SetHasBreak \
miniNode.HasBreak miniNode.SetHasBreak \
Node.Bounded Node.SetBounded \
miniNode.Bounded miniNode.SetBounded \
miniNode.Embedded miniNode.SetEmbedded \
miniNode.Int64Val miniNode.Uint64Val miniNode.CanInt64 \
miniNode.BoolVal miniNode.StringVal \
miniNode.TChanDir miniNode.SetTChanDir \
miniNode.Format \
miniNode.copy miniNode.doChildren miniNode.editChildren \
'
Change-Id: I2a05b535963b43f83b1849fcf653f82b99af6035
Reviewed-on: https://go-review.googlesource.com/c/go/+/277934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:56:32 -05:00
|
|
|
n := n.(*ir.CompLitExpr)
|
[dev.regabi] cmd/compile: simplify Nodes usage [generated]
Now that Nodes is a slice, most of the methods can be removed
in favor of direct slice operations, reducing the new API that must
be understood to:
Copy
Take
Append
Prepend
Format
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/ir
rf '
ex . ../gc {
var ns Nodes
var pns *Nodes
var n, n2, n3 Node
var i int
var slice []Node
ns.Len() -> len(ns)
ns.Slice() -> ns
ns.First() -> ns[0]
ns.Second() -> ns[1]
ns.Index(i) -> ns[i]
ns.Addr(i) -> &ns[i]
ns.SetIndex(i, n) -> ns[i] = n
ns.SetFirst(n) -> ns[0] = n
ns.SetSecond(n) -> ns[1] = n
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
ns.Set1(n) -> ns = []Node{n}
ns.Set2(n, n2) -> ns = []Node{n, n2}
ns.Set3(n, n2, n3) -> ns = []Node{n, n2, n3}
AsNodes(slice) -> Nodes(slice)
ns.AppendNodes(pns) -> ns.Append(pns.Take()...)
ns.MoveNodes(pns) -> ns = pns.Take()
}
rm \
Nodes.Len Nodes.Slice \
Nodes.First Nodes.Second Nodes.Index Nodes.Addr \
Nodes.SetIndex Nodes.SetFirst Nodes.SetSecond \
Nodes.Set1 Nodes.Set2 Nodes.Set3 \
AsNodes \
Nodes.AppendNodes Nodes.MoveNodes
'
Change-Id: Iee86434ced52e67861c3fa71bdd6d994a8cba735
Reviewed-on: https://go-review.googlesource.com/c/go/+/277936
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:03:33 -05:00
|
|
|
entries := n.List
|
2019-04-29 12:19:30 -07:00
|
|
|
statics := entries[:0]
|
2020-12-10 18:45:35 -05:00
|
|
|
var dynamics []*ir.KeyExpr
|
2019-04-29 12:19:30 -07:00
|
|
|
for _, r := range entries {
|
2020-12-10 18:45:35 -05:00
|
|
|
r := r.(*ir.KeyExpr)
|
2019-05-01 21:57:52 +07:00
|
|
|
|
2020-12-23 00:02:08 -05:00
|
|
|
if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
|
2019-05-01 21:57:52 +07:00
|
|
|
dynamics = append(dynamics, r)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Recursively ordering some static entries can change them to dynamic;
|
|
|
|
|
// e.g., OCONVIFACE nodes. See #31777.
|
2020-12-10 18:45:35 -05:00
|
|
|
r = o.expr(r, nil).(*ir.KeyExpr)
|
2020-12-23 00:02:08 -05:00
|
|
|
if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
|
2019-04-29 12:19:30 -07:00
|
|
|
dynamics = append(dynamics, r)
|
2019-05-01 21:57:52 +07:00
|
|
|
continue
|
2019-04-29 12:19:30 -07:00
|
|
|
}
|
2019-05-01 21:57:52 +07:00
|
|
|
|
|
|
|
|
statics = append(statics, r)
|
2019-04-29 12:19:30 -07:00
|
|
|
}
|
2021-01-02 01:27:29 -08:00
|
|
|
n.List = statics
|
2019-04-29 12:19:30 -07:00
|
|
|
|
|
|
|
|
if len(dynamics) == 0 {
|
2020-12-10 18:45:35 -05:00
|
|
|
return n
|
2019-04-29 12:19:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Emit the creation of the map (with all its static entries).
|
2020-11-22 09:59:15 -05:00
|
|
|
m := o.newTemp(n.Type(), false)
|
[dev.regabi] cmd/compile: remove ir.Nod [generated]
Rewrite all uses of ir.Nod and friends to call the IR constructors directly.
This gives the results a more specific type and will play nicely with
introduction of more specific types throughout the code in a followup CL.
Passes buildall w/ toolstash -cmp.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/compile/internal/syntax"
import "cmd/internal/src"
var p *noder
var orig syntax.Node
var op ir.Op
var l, r ir.Node
var sym *types.Sym
p.nod(orig, op, l, r) -> ir.NodAt(p.pos(orig), op, l, r)
p.nodSym(orig, op, l, sym) -> nodlSym(p.pos(orig), op, l, sym)
var xpos src.XPos
var ns ir.Nodes
npos(xpos, nodSym(op, l, sym)) -> nodlSym(xpos, op, l, sym)
npos(xpos, liststmt(ns)) -> ir.NewBlockStmt(xpos, ns)
}
ex . ../ir {
import "cmd/compile/internal/base"
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
var op ir.Op
var l, r ir.Node
ir.Nod(op, l, r) -> ir.NodAt(base.Pos, op, l, r)
var sym *types.Sym
nodSym(op, l, sym) -> nodlSym(base.Pos, op, l, sym)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/internal/src"
# rf overlapping match handling is not quite good enough
# for certain nested rewrites, so handle these two - which often contain other ir.NodAt calls - early.
var l, r ir.Node
var xpos src.XPos
ir.NodAt(xpos, ir.OAS, l, r) -> ir.NewAssignStmt(xpos, l, r)
ir.NodAt(xpos, ir.OIF, l, nil) -> ir.NewIfStmt(xpos, l, nil, nil)
}
ex . ../ir {
import "cmd/compile/internal/ir"
import "cmd/compile/internal/types"
import "cmd/internal/src"
var l, r ir.Node
var sym *types.Sym
var xpos src.XPos
nodlSym(xpos, ir.ODOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, sym)
nodlSym(xpos, ir.OXDOT, l, sym) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, sym)
nodlSym(xpos, ir.ODOTPTR, l, sym) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, sym)
nodlSym(xpos, ir.OGOTO, nil, sym) -> ir.NewBranchStmt(xpos, ir.OGOTO, sym)
nodlSym(xpos, ir.ORETJMP, nil, sym) -> ir.NewBranchStmt(xpos, ir.ORETJMP, sym)
nodlSym(xpos, ir.OLABEL, nil, sym) -> ir.NewLabelStmt(xpos, sym)
nodlSym(xpos, ir.OSTRUCTKEY, l, sym) -> ir.NewStructKeyExpr(xpos, sym, l)
ir.NodAt(xpos, ir.OADD, l, r) -> ir.NewBinaryExpr(xpos, ir.OADD, l, r)
ir.NodAt(xpos, ir.OAND, l, r) -> ir.NewBinaryExpr(xpos, ir.OAND, l, r)
ir.NodAt(xpos, ir.OANDNOT, l, r) -> ir.NewBinaryExpr(xpos, ir.OANDNOT, l, r)
ir.NodAt(xpos, ir.ODIV, l, r) -> ir.NewBinaryExpr(xpos, ir.ODIV, l, r)
ir.NodAt(xpos, ir.OEQ, l, r) -> ir.NewBinaryExpr(xpos, ir.OEQ, l, r)
ir.NodAt(xpos, ir.OGE, l, r) -> ir.NewBinaryExpr(xpos, ir.OGE, l, r)
ir.NodAt(xpos, ir.OGT, l, r) -> ir.NewBinaryExpr(xpos, ir.OGT, l, r)
ir.NodAt(xpos, ir.OLE, l, r) -> ir.NewBinaryExpr(xpos, ir.OLE, l, r)
ir.NodAt(xpos, ir.OLSH, l, r) -> ir.NewBinaryExpr(xpos, ir.OLSH, l, r)
ir.NodAt(xpos, ir.OLT, l, r) -> ir.NewBinaryExpr(xpos, ir.OLT, l, r)
ir.NodAt(xpos, ir.OMOD, l, r) -> ir.NewBinaryExpr(xpos, ir.OMOD, l, r)
ir.NodAt(xpos, ir.OMUL, l, r) -> ir.NewBinaryExpr(xpos, ir.OMUL, l, r)
ir.NodAt(xpos, ir.ONE, l, r) -> ir.NewBinaryExpr(xpos, ir.ONE, l, r)
ir.NodAt(xpos, ir.OOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OOR, l, r)
ir.NodAt(xpos, ir.ORSH, l, r) -> ir.NewBinaryExpr(xpos, ir.ORSH, l, r)
ir.NodAt(xpos, ir.OSUB, l, r) -> ir.NewBinaryExpr(xpos, ir.OSUB, l, r)
ir.NodAt(xpos, ir.OXOR, l, r) -> ir.NewBinaryExpr(xpos, ir.OXOR, l, r)
ir.NodAt(xpos, ir.OCOPY, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOPY, l, r)
ir.NodAt(xpos, ir.OCOMPLEX, l, r) -> ir.NewBinaryExpr(xpos, ir.OCOMPLEX, l, r)
ir.NodAt(xpos, ir.OEFACE, l, r) -> ir.NewBinaryExpr(xpos, ir.OEFACE, l, r)
ir.NodAt(xpos, ir.OADDR, l, nil) -> ir.NewAddrExpr(xpos, l)
ir.NodAt(xpos, ir.OADDSTR, nil, nil) -> ir.NewAddStringExpr(xpos, nil)
ir.NodAt(xpos, ir.OANDAND, l, r) -> ir.NewLogicalExpr(xpos, ir.OANDAND, l, r)
ir.NodAt(xpos, ir.OOROR, l, r) -> ir.NewLogicalExpr(xpos, ir.OOROR, l, r)
ir.NodAt(xpos, ir.OARRAYLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, nil, nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, nil, nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, nil, nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, nil, nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, nil) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, nil, nil)
ir.NodAt(xpos, ir.OARRAYLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OARRAYLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OCOMPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OCOMPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OMAPLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OMAPLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSTRUCTLIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSTRUCTLIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OSLICELIT, nil, r) -> ir.NewCompLitExpr(xpos, ir.OSLICELIT, r.(ir.Ntype), nil)
ir.NodAt(xpos, ir.OAS2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2, nil, nil)
ir.NodAt(xpos, ir.OAS2DOTTYPE, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2DOTTYPE, nil, nil)
ir.NodAt(xpos, ir.OAS2FUNC, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2FUNC, nil, nil)
ir.NodAt(xpos, ir.OAS2MAPR, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2MAPR, nil, nil)
ir.NodAt(xpos, ir.OAS2RECV, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OAS2RECV, nil, nil)
ir.NodAt(xpos, ir.OSELRECV2, nil, nil) -> ir.NewAssignListStmt(xpos, ir.OSELRECV2, nil, nil)
ir.NodAt(xpos, ir.OASOP, l, r) -> ir.NewAssignOpStmt(xpos, ir.OXXX, l, r)
ir.NodAt(xpos, ir.OBITNOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.OBITNOT, l)
ir.NodAt(xpos, ir.ONEG, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEG, l)
ir.NodAt(xpos, ir.ONOT, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONOT, l)
ir.NodAt(xpos, ir.OPLUS, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPLUS, l)
ir.NodAt(xpos, ir.ORECV, l, nil) -> ir.NewUnaryExpr(xpos, ir.ORECV, l)
ir.NodAt(xpos, ir.OALIGNOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OALIGNOF, l)
ir.NodAt(xpos, ir.OCAP, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCAP, l)
ir.NodAt(xpos, ir.OCLOSE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCLOSE, l)
ir.NodAt(xpos, ir.OIMAG, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIMAG, l)
ir.NodAt(xpos, ir.OLEN, l, nil) -> ir.NewUnaryExpr(xpos, ir.OLEN, l)
ir.NodAt(xpos, ir.ONEW, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEW, l)
ir.NodAt(xpos, ir.ONEWOBJ, l, nil) -> ir.NewUnaryExpr(xpos, ir.ONEWOBJ, l)
ir.NodAt(xpos, ir.OOFFSETOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OOFFSETOF, l)
ir.NodAt(xpos, ir.OPANIC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OPANIC, l)
ir.NodAt(xpos, ir.OREAL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OREAL, l)
ir.NodAt(xpos, ir.OSIZEOF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSIZEOF, l)
ir.NodAt(xpos, ir.OCHECKNIL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCHECKNIL, l)
ir.NodAt(xpos, ir.OCFUNC, l, nil) -> ir.NewUnaryExpr(xpos, ir.OCFUNC, l)
ir.NodAt(xpos, ir.OIDATA, l, nil) -> ir.NewUnaryExpr(xpos, ir.OIDATA, l)
ir.NodAt(xpos, ir.OITAB, l, nil) -> ir.NewUnaryExpr(xpos, ir.OITAB, l)
ir.NodAt(xpos, ir.OSPTR, l, nil) -> ir.NewUnaryExpr(xpos, ir.OSPTR, l)
ir.NodAt(xpos, ir.OVARDEF, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARDEF, l)
ir.NodAt(xpos, ir.OVARKILL, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARKILL, l)
ir.NodAt(xpos, ir.OVARLIVE, l, nil) -> ir.NewUnaryExpr(xpos, ir.OVARLIVE, l)
ir.NodAt(xpos, ir.OBLOCK, nil, nil) -> ir.NewBlockStmt(xpos, nil)
ir.NodAt(xpos, ir.OBREAK, nil, nil) -> ir.NewBranchStmt(xpos, ir.OBREAK, nil)
ir.NodAt(xpos, ir.OCONTINUE, nil, nil) -> ir.NewBranchStmt(xpos, ir.OCONTINUE, nil)
ir.NodAt(xpos, ir.OFALL, nil, nil) -> ir.NewBranchStmt(xpos, ir.OFALL, nil)
ir.NodAt(xpos, ir.OGOTO, nil, nil) -> ir.NewBranchStmt(xpos, ir.OGOTO, nil)
ir.NodAt(xpos, ir.ORETJMP, nil, nil) -> ir.NewBranchStmt(xpos, ir.ORETJMP, nil)
ir.NodAt(xpos, ir.OCALL, l, nil) -> ir.NewCallExpr(xpos, ir.OCALL, l, nil)
ir.NodAt(xpos, ir.OCALLFUNC, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLFUNC, l, nil)
ir.NodAt(xpos, ir.OCALLINTER, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLINTER, l, nil)
ir.NodAt(xpos, ir.OCALLMETH, l, nil) -> ir.NewCallExpr(xpos, ir.OCALLMETH, l, nil)
ir.NodAt(xpos, ir.OAPPEND, l, nil) -> ir.NewCallExpr(xpos, ir.OAPPEND, l, nil)
ir.NodAt(xpos, ir.ODELETE, l, nil) -> ir.NewCallExpr(xpos, ir.ODELETE, l, nil)
ir.NodAt(xpos, ir.OGETG, l, nil) -> ir.NewCallExpr(xpos, ir.OGETG, l, nil)
ir.NodAt(xpos, ir.OMAKE, l, nil) -> ir.NewCallExpr(xpos, ir.OMAKE, l, nil)
ir.NodAt(xpos, ir.OPRINT, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINT, l, nil)
ir.NodAt(xpos, ir.OPRINTN, l, nil) -> ir.NewCallExpr(xpos, ir.OPRINTN, l, nil)
ir.NodAt(xpos, ir.ORECOVER, l, nil) -> ir.NewCallExpr(xpos, ir.ORECOVER, l, nil)
ir.NodAt(xpos, ir.OCASE, nil, nil) -> ir.NewCaseStmt(xpos, nil, nil)
ir.NodAt(xpos, ir.OCONV, l, nil) -> ir.NewConvExpr(xpos, ir.OCONV, nil, l)
ir.NodAt(xpos, ir.OCONVIFACE, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVIFACE, nil, l)
ir.NodAt(xpos, ir.OCONVNOP, l, nil) -> ir.NewConvExpr(xpos, ir.OCONVNOP, nil, l)
ir.NodAt(xpos, ir.ORUNESTR, l, nil) -> ir.NewConvExpr(xpos, ir.ORUNESTR, nil, l)
ir.NodAt(xpos, ir.ODCL, l, nil) -> ir.NewDecl(xpos, ir.ODCL, l)
ir.NodAt(xpos, ir.ODCLCONST, l, nil) -> ir.NewDecl(xpos, ir.ODCLCONST, l)
ir.NodAt(xpos, ir.ODCLTYPE, l, nil) -> ir.NewDecl(xpos, ir.ODCLTYPE, l)
ir.NodAt(xpos, ir.ODCLFUNC, nil, nil) -> ir.NewFunc(xpos)
ir.NodAt(xpos, ir.ODEFER, l, nil) -> ir.NewGoDeferStmt(xpos, ir.ODEFER, l)
ir.NodAt(xpos, ir.OGO, l, nil) -> ir.NewGoDeferStmt(xpos, ir.OGO, l)
ir.NodAt(xpos, ir.ODEREF, l, nil) -> ir.NewStarExpr(xpos, l)
ir.NodAt(xpos, ir.ODOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOT, l, nil)
ir.NodAt(xpos, ir.ODOTPTR, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTPTR, l, nil)
ir.NodAt(xpos, ir.ODOTMETH, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTMETH, l, nil)
ir.NodAt(xpos, ir.ODOTINTER, l, nil) -> ir.NewSelectorExpr(xpos, ir.ODOTINTER, l, nil)
ir.NodAt(xpos, ir.OXDOT, l, nil) -> ir.NewSelectorExpr(xpos, ir.OXDOT, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, nil) -> ir.NewTypeAssertExpr(xpos, l, nil)
ir.NodAt(xpos, ir.ODOTTYPE, l, r) -> ir.NewTypeAssertExpr(xpos, l, r.(ir.Ntype))
ir.NodAt(xpos, ir.OFOR, l, r) -> ir.NewForStmt(xpos, nil, l, r, nil)
ir.NodAt(xpos, ir.OINDEX, l, r) -> ir.NewIndexExpr(xpos, l, r)
ir.NodAt(xpos, ir.OINLMARK, nil, nil) -> ir.NewInlineMarkStmt(xpos, types.BADWIDTH)
ir.NodAt(xpos, ir.OKEY, l, r) -> ir.NewKeyExpr(xpos, l, r)
ir.NodAt(xpos, ir.OLABEL, nil, nil) -> ir.NewLabelStmt(xpos, nil)
ir.NodAt(xpos, ir.OMAKECHAN, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKECHAN, l, r)
ir.NodAt(xpos, ir.OMAKEMAP, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKEMAP, l, r)
ir.NodAt(xpos, ir.OMAKESLICE, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICE, l, r)
ir.NodAt(xpos, ir.OMAKESLICECOPY, l, r) -> ir.NewMakeExpr(xpos, ir.OMAKESLICECOPY, l, r)
ir.NodAt(xpos, ir.ONIL, nil, nil) -> ir.NewNilExpr(xpos)
ir.NodAt(xpos, ir.OPACK, nil, nil) -> ir.NewPkgName(xpos, nil, nil)
ir.NodAt(xpos, ir.OPAREN, l, nil) -> ir.NewParenExpr(xpos, l)
ir.NodAt(xpos, ir.ORANGE, nil, r) -> ir.NewRangeStmt(xpos, nil, r, nil)
ir.NodAt(xpos, ir.ORESULT, nil, nil) -> ir.NewResultExpr(xpos, nil, types.BADWIDTH)
ir.NodAt(xpos, ir.ORETURN, nil, nil) -> ir.NewReturnStmt(xpos, nil)
ir.NodAt(xpos, ir.OSELECT, nil, nil) -> ir.NewSelectStmt(xpos, nil)
ir.NodAt(xpos, ir.OSEND, l, r) -> ir.NewSendStmt(xpos, l, r)
ir.NodAt(xpos, ir.OSLICE, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE, l)
ir.NodAt(xpos, ir.OSLICEARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICEARR, l)
ir.NodAt(xpos, ir.OSLICESTR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICESTR, l)
ir.NodAt(xpos, ir.OSLICE3, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3, l)
ir.NodAt(xpos, ir.OSLICE3ARR, l, nil) -> ir.NewSliceExpr(xpos, ir.OSLICE3ARR, l)
ir.NodAt(xpos, ir.OSLICEHEADER, l, nil) -> ir.NewSliceHeaderExpr(xpos, nil, l, nil, nil)
ir.NodAt(xpos, ir.OSWITCH, l, nil) -> ir.NewSwitchStmt(xpos, l, nil)
ir.NodAt(xpos, ir.OINLCALL, nil, nil) -> ir.NewInlinedCallExpr(xpos, nil, nil)
}
rm noder.nod noder.nodSym nodSym nodlSym ir.NodAt ir.Nod
'
Change-Id: Ibf1eb708de8463ae74ccc47d7966cc263a18295e
Reviewed-on: https://go-review.googlesource.com/c/go/+/277933
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-22 23:55:29 -05:00
|
|
|
as := ir.NewAssignStmt(base.Pos, m, n)
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
typecheck.Stmt(as)
|
2019-04-29 12:19:30 -07:00
|
|
|
o.stmt(as)
|
|
|
|
|
|
|
|
|
|
// Emit eval+insert of dynamic entries, one at a time.
|
|
|
|
|
for _, r := range dynamics {
|
2020-12-23 00:02:08 -05:00
|
|
|
as := ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, r.Key), r.Value)
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
typecheck.Stmt(as) // Note: this converts the OINDEX to an OINDEXMAP
|
2019-04-29 12:19:30 -07:00
|
|
|
o.stmt(as)
|
|
|
|
|
}
|
2020-12-10 18:45:35 -05:00
|
|
|
return m
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2020-12-10 18:45:35 -05:00
|
|
|
// No return - type-assertions above. Each case must return for itself.
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-08-26 10:50:12 -07:00
|
|
|
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
// as2func orders OAS2FUNC nodes. It creates temporaries to ensure left-to-right assignment.
|
|
|
|
|
// The caller should order the right-hand side of the assignment before calling order.as2func.
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
// It rewrites,
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
// a, b, a = ...
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
// as
|
|
|
|
|
// tmp1, tmp2, tmp3 = ...
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
// a, b, a = tmp1, tmp2, tmp3
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
// This is necessary to ensure left to right assignment order.
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
func (o *orderState) as2func(n *ir.AssignListStmt) {
|
|
|
|
|
results := n.Rhs[0].Type()
|
|
|
|
|
as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
|
|
|
|
|
for i, nl := range n.Lhs {
|
|
|
|
|
if !ir.IsBlank(nl) {
|
|
|
|
|
typ := results.Field(i).Type
|
|
|
|
|
tmp := o.newTemp(typ, typ.HasPointers())
|
|
|
|
|
n.Lhs[i] = tmp
|
|
|
|
|
as.Lhs = append(as.Lhs, nl)
|
|
|
|
|
as.Rhs = append(as.Rhs, tmp)
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
[dev.regabi] cmd/compile: split out package typecheck [generated]
This commit splits the typechecking logic into its own package,
the first of a sequence of CLs to break package gc into more
manageable units.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# The binary import/export has to be part of typechecking,
# because we load inlined function bodies lazily, but "exporter"
# should not be. Move that out of bexport.go.
mv exporter exporter.markObject exporter.markType export.go
# Use the typechecking helpers, so that the calls left behind
# in package gc do not need access to ctxExpr etc.
ex {
import "cmd/compile/internal/ir"
# TODO(rsc): Should not be necessary.
avoid TypecheckExpr
avoid TypecheckStmt
avoid TypecheckExprs
avoid TypecheckStmts
avoid TypecheckAssignExpr
avoid TypecheckCallee
var n ir.Node
var ns []ir.Node
typecheck(n, ctxExpr) -> TypecheckExpr(n)
typecheck(n, ctxStmt) -> TypecheckStmt(n)
typecheckslice(ns, ctxExpr) -> TypecheckExprs(ns)
typecheckslice(ns, ctxStmt) -> TypecheckStmts(ns)
typecheck(n, ctxExpr|ctxAssign) -> TypecheckAssignExpr(n)
typecheck(n, ctxExpr|ctxCallee) -> TypecheckCallee(n)
}
# Move some typechecking API to typecheck.
mv syslook LookupRuntime
mv substArgTypes SubstArgTypes
mv LookupRuntime SubstArgTypes syms.go
mv conv Conv
mv convnop ConvNop
mv Conv ConvNop typecheck.go
mv colasdefn AssignDefn
mv colasname assignableName
mv Target target.go
mv initname autoexport exportsym dcl.go
mv exportsym Export
# Export API to be called from outside typecheck.
# The ones with "Typecheck" prefixes will be renamed later to drop the prefix.
mv adddot AddImplicitDots
mv assignconv AssignConv
mv expandmeth CalcMethods
mv capturevarscomplete CaptureVarsComplete
mv checkMapKeys CheckMapKeys
mv checkreturn CheckReturn
mv dclcontext DeclContext
mv dclfunc DeclFunc
mv declare Declare
mv dotImportRefs DotImportRefs
mv declImporter DeclImporter
mv variter DeclVars
mv defaultlit DefaultLit
mv evalConst EvalConst
mv expandInline ImportBody
mv finishUniverse declareUniverse
mv funcbody FinishFuncBody
mv funchdr StartFuncBody
mv indexconst IndexConst
mv initTodo InitTodoFunc
mv lookup Lookup
mv resolve Resolve
mv lookupN LookupNum
mv nodAddr NodAddr
mv nodAddrAt NodAddrAt
mv nodnil NodNil
mv origBoolConst OrigBool
mv origConst OrigConst
mv origIntConst OrigInt
mv redeclare Redeclared
mv tostruct NewStructType
mv functype NewFuncType
mv methodfunc NewMethodType
mv structargs NewFuncParams
mv temp Temp
mv tempAt TempAt
mv typecheckok TypecheckAllowed
mv typecheck _typecheck # make room for typecheck pkg
mv typecheckinl TypecheckImportedBody
mv typecheckFunc TypecheckFunc
mv iimport ReadImports
mv iexport WriteExports
mv sysfunc LookupRuntimeFunc
mv sysvar LookupRuntimeVar
# Move function constructors to typecheck.
mv mkdotargslice MakeDotArgs
mv fixVariadicCall FixVariadicCall
mv closureType ClosureType
mv partialCallType PartialCallType
mv capturevars CaptureVars
mv MakeDotArgs FixVariadicCall ClosureType PartialCallType CaptureVars typecheckclosure func.go
mv autolabel AutoLabel
mv AutoLabel syms.go
mv Dlist dlist
mv Symlink symlink
mv \
AssignDefn assignableName \
AssignConv \
CaptureVarsComplete \
DeclContext \
DeclFunc \
DeclImporter \
DeclVars \
Declare \
DotImportRefs \
Export \
InitTodoFunc \
Lookup \
LookupNum \
LookupRuntimeFunc \
LookupRuntimeVar \
NewFuncParams \
NewName \
NodAddr \
NodAddrAt \
NodNil \
Redeclared \
StartFuncBody \
FinishFuncBody \
TypecheckImportedBody \
AddImplicitDots \
CalcMethods \
CheckFuncStack \
NewFuncType \
NewMethodType \
NewStructType \
TypecheckAllowed \
Temp \
TempAt \
adddot1 \
dotlist \
addmethod \
assignconvfn \
assignop \
autotmpname \
autoexport \
bexport.go \
checkdupfields \
checkembeddedtype \
closurename \
convertop \
declare_typegen \
decldepth \
dlist \
dotpath \
expand0 \
expand1 \
expandDecl \
fakeRecvField \
fnpkg \
funcStack \
funcStackEnt \
funcarg \
funcarg2 \
funcargs \
funcargs2 \
globClosgen \
ifacelookdot \
implements \
importalias \
importconst \
importfunc \
importobj \
importsym \
importtype \
importvar \
inimport \
initname \
isptrto \
loadsys \
lookdot0 \
lookdot1 \
makepartialcall \
okfor \
okforlen \
operandType \
slist \
symlink \
tointerface \
typeSet \
typeSet.add \
typeSetEntry \
typecheckExprSwitch \
typecheckTypeSwitch \
typecheckpartialcall \
typecheckrange \
typecheckrangeExpr \
typecheckselect \
typecheckswitch \
vargen \
builtin.go \
builtin_test.go \
const.go \
func.go \
iexport.go \
iimport.go \
mapfile_mmap.go \
syms.go \
target.go \
typecheck.go \
unsafe.go \
universe.go \
cmd/compile/internal/typecheck
'
rm gen.go types.go types_acc.go
sed -i '' 's/package gc/package typecheck/' mapfile_read.go mkbuiltin.go
mv mapfile_read.go ../typecheck # not part of default build
mv mkbuiltin.go ../typecheck # package main helper
mv builtin ../typecheck
cd ../typecheck
mv dcl.go dcl1.go
mv typecheck.go typecheck1.go
mv universe.go universe1.go
rf '
# Sweep some small files into larger ones.
# "mv sym... file1.go file.go" (after the mv file1.go file.go above)
# lets us insert sym... at the top of file.go.
mv okfor okforeq universe1.go universe.go
mv DeclContext vargen dcl1.go Temp TempAt autotmpname NewMethodType dcl.go
mv InitTodoFunc inimport decldepth TypecheckAllowed typecheck1.go typecheck.go
mv inl.go closure.go func.go
mv range.go select.go swt.go stmt.go
mv Lookup loadsys LookupRuntimeFunc LookupRuntimeVar syms.go
mv unsafe.go const.go
mv TypecheckAssignExpr AssignExpr
mv TypecheckExpr Expr
mv TypecheckStmt Stmt
mv TypecheckExprs Exprs
mv TypecheckStmts Stmts
mv TypecheckCall Call
mv TypecheckCallee Callee
mv _typecheck check
mv TypecheckFunc Func
mv TypecheckFuncBody FuncBody
mv TypecheckImports AllImportedBodies
mv TypecheckImportedBody ImportedBody
mv TypecheckInit Init
mv TypecheckPackage Package
'
rm gen.go go.go init.go main.go reflect.go
Change-Id: Iea6a7aaf6407d690670ec58aeb36cc0b280f80b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/279236
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-12-23 00:41:49 -05:00
|
|
|
o.stmt(typecheck.Stmt(as))
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
}
|
|
|
|
|
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
// as2ok orders OAS2XXX with ok.
|
|
|
|
|
// Just like as2func, this also adds temporaries to ensure left-to-right assignment.
|
|
|
|
|
func (o *orderState) as2ok(n *ir.AssignListStmt) {
|
|
|
|
|
as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
|
|
|
|
|
|
|
|
|
|
do := func(i int, typ *types.Type) {
|
|
|
|
|
if nl := n.Lhs[i]; !ir.IsBlank(nl) {
|
|
|
|
|
var tmp ir.Node = o.newTemp(typ, typ.HasPointers())
|
|
|
|
|
n.Lhs[i] = tmp
|
|
|
|
|
as.Lhs = append(as.Lhs, nl)
|
|
|
|
|
if i == 1 {
|
|
|
|
|
// The "ok" result is an untyped boolean according to the Go
|
|
|
|
|
// spec. We need to explicitly convert it to the LHS type in
|
|
|
|
|
// case the latter is a defined boolean type (#8475).
|
|
|
|
|
tmp = typecheck.Conv(tmp, nl.Type())
|
|
|
|
|
}
|
|
|
|
|
as.Rhs = append(as.Rhs, tmp)
|
|
|
|
|
}
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
}
|
|
|
|
|
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
do(0, n.Rhs[0].Type())
|
|
|
|
|
do(1, types.Types[types.TBOOL])
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
|
2018-03-04 17:17:55 -08:00
|
|
|
o.out = append(o.out, n)
|
[dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
Currently, to ensure OAS2FUNC results are assigned in the correct
order, they're always assigned to temporary variables. However, these
temporary variables are typed based on the destination type, which may
require an interface conversion. This means walk may have to then
introduce a second set of temporaries to ensure result parameters are
all copied out of the results area, before it emits calls to runtime
conversion functions.
That's just silly. Instead, this CL changes order to allocate the
result temporaries with the same type as the function returns in the
first place, and then assign them one at a time to their destinations,
with conversions as needed.
While here, also fix an order-of-evaluation issue with has-ok
assignments that I almost added to multi-value function call
assignments, and add tests for each.
Change-Id: I9f4e962425fe3c5e3305adbbfeae2c7f253ec365
Reviewed-on: https://go-review.googlesource.com/c/go/+/284220
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-16 03:27:17 -08:00
|
|
|
o.stmt(typecheck.Stmt(as))
|
cmd/compile: Ensure left-to-right assignment
Add temporaries to reorder the assignment for OAS2XXX nodes.
This makes orderstmt(), rewrite
a, b, c = ...
as
tmp1, tmp2, tmp3 = ...
a, b, c = tmp1, tmp2, tmp3
and
a, ok = ...
as
t1, t2 = ...
a = t1
ok = t2
Fixes #13433.
Change-Id: Id0f5956e3a254d0a6f4b89b5f7b0e055b1f0e21f
Reviewed-on: https://go-review.googlesource.com/34713
Run-TryBot: Dhananjay Nakrani <dhananjayn@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-12-23 22:28:45 -08:00
|
|
|
}
|
2021-02-24 12:55:52 -05:00
|
|
|
|
|
|
|
|
var wrapGoDefer_prgen int
|
|
|
|
|
|
|
|
|
|
// wrapGoDefer wraps the target of a "go" or "defer" statement with a
|
|
|
|
|
// new "function with no arguments" closure. Specifically, it converts
|
|
|
|
|
//
|
|
|
|
|
// defer f(x, y)
|
|
|
|
|
//
|
|
|
|
|
// to
|
|
|
|
|
//
|
|
|
|
|
// x1, y1 := x, y
|
|
|
|
|
// defer func() { f(x1, y1) }()
|
|
|
|
|
//
|
|
|
|
|
// This is primarily to enable a quicker bringup of defers under the
|
|
|
|
|
// new register ABI; by doing this conversion, we can simplify the
|
|
|
|
|
// code in the runtime that invokes defers on the panic path.
|
|
|
|
|
func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
|
|
|
|
|
call := n.Call
|
|
|
|
|
|
2021-03-25 08:30:19 -04:00
|
|
|
var callX ir.Node // thing being called
|
|
|
|
|
var callArgs []ir.Node // call arguments
|
|
|
|
|
var keepAlive []*ir.Name // KeepAlive list from call, if present
|
2021-02-24 12:55:52 -05:00
|
|
|
|
|
|
|
|
// A helper to recreate the call within the closure.
|
|
|
|
|
var mkNewCall func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node
|
|
|
|
|
|
|
|
|
|
// Defer calls come in many shapes and sizes; not all of them
|
|
|
|
|
// are ir.CallExpr's. Examine the type to see what we're dealing with.
|
|
|
|
|
switch x := call.(type) {
|
|
|
|
|
case *ir.CallExpr:
|
|
|
|
|
callX = x.X
|
|
|
|
|
callArgs = x.Args
|
2021-03-25 08:30:19 -04:00
|
|
|
keepAlive = x.KeepAlive
|
2021-02-24 12:55:52 -05:00
|
|
|
mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
|
|
|
|
|
newcall := ir.NewCallExpr(pos, op, fun, args)
|
|
|
|
|
newcall.IsDDD = x.IsDDD
|
|
|
|
|
return ir.Node(newcall)
|
|
|
|
|
}
|
|
|
|
|
case *ir.UnaryExpr: // ex: OCLOSE
|
|
|
|
|
callArgs = []ir.Node{x.X}
|
|
|
|
|
mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
|
|
|
|
|
if len(args) != 1 {
|
2021-03-25 13:24:16 -04:00
|
|
|
panic("internal error, expecting single arg")
|
2021-02-24 12:55:52 -05:00
|
|
|
}
|
|
|
|
|
return ir.Node(ir.NewUnaryExpr(pos, op, args[0]))
|
|
|
|
|
}
|
|
|
|
|
case *ir.BinaryExpr: // ex: OCOPY
|
|
|
|
|
callArgs = []ir.Node{x.X, x.Y}
|
|
|
|
|
mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
|
|
|
|
|
if len(args) != 2 {
|
|
|
|
|
panic("internal error, expecting two args")
|
|
|
|
|
}
|
|
|
|
|
return ir.Node(ir.NewBinaryExpr(pos, op, args[0], args[1]))
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
panic("unhandled op")
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-29 14:17:18 -04:00
|
|
|
// No need to wrap if called func has no args, no receiver, and no results.
|
2021-03-25 13:24:16 -04:00
|
|
|
// However in the case of "defer func() { ... }()" we need to
|
|
|
|
|
// protect against the possibility of directClosureCall rewriting
|
|
|
|
|
// things so that the call does have arguments.
|
|
|
|
|
//
|
|
|
|
|
// Do wrap method calls (OCALLMETH, OCALLINTER), because it has
|
|
|
|
|
// a receiver.
|
|
|
|
|
//
|
|
|
|
|
// Also do wrap builtin functions, because they may be expanded to
|
|
|
|
|
// calls with arguments (e.g. ORECOVER).
|
2021-03-29 14:17:18 -04:00
|
|
|
//
|
|
|
|
|
// TODO: maybe not wrap if the called function has no arguments and
|
|
|
|
|
// only in-register results?
|
|
|
|
|
if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 {
|
2021-02-24 12:55:52 -05:00
|
|
|
if c, ok := call.(*ir.CallExpr); ok && callX != nil && callX.Op() == ir.OCLOSURE {
|
|
|
|
|
cloFunc := callX.(*ir.ClosureExpr).Func
|
|
|
|
|
cloFunc.SetClosureCalled(false)
|
|
|
|
|
c.PreserveClosure = true
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c, ok := call.(*ir.CallExpr); ok {
|
|
|
|
|
// To simplify things, turn f(a, b, []T{c, d, e}...) back
|
|
|
|
|
// into f(a, b, c, d, e) -- when the final call is run through the
|
|
|
|
|
// type checker below, it will rebuild the proper slice literal.
|
|
|
|
|
undoVariadic(c)
|
|
|
|
|
callX = c.X
|
|
|
|
|
callArgs = c.Args
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is set to true if the closure we're generating escapes
|
|
|
|
|
// (needs heap allocation).
|
|
|
|
|
cloEscapes := func() bool {
|
|
|
|
|
if n.Op() == ir.OGO {
|
|
|
|
|
// For "go", assume that all closures escape (with an
|
|
|
|
|
// exception for the runtime, which doesn't permit
|
|
|
|
|
// heap-allocated closures).
|
|
|
|
|
return base.Ctxt.Pkgpath != "runtime"
|
|
|
|
|
}
|
|
|
|
|
// For defer, just use whatever result escape analysis
|
|
|
|
|
// has determined for the defer.
|
|
|
|
|
return n.Esc() != ir.EscNever
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
// A helper for making a copy of an argument.
|
|
|
|
|
mkArgCopy := func(arg ir.Node) *ir.Name {
|
|
|
|
|
argCopy := o.copyExpr(arg)
|
|
|
|
|
// The value of 128 below is meant to be consistent with code
|
|
|
|
|
// in escape analysis that picks byval/byaddr based on size.
|
|
|
|
|
argCopy.SetByval(argCopy.Type().Size() <= 128 || cloEscapes)
|
|
|
|
|
return argCopy
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-25 08:30:19 -04:00
|
|
|
// getUnsafeArg looks for an unsafe.Pointer arg that has been
|
|
|
|
|
// previously captured into the call's keepalive list, returning
|
|
|
|
|
// the name node for it if found.
|
|
|
|
|
getUnsafeArg := func(arg ir.Node) *ir.Name {
|
|
|
|
|
// Look for uintptr(unsafe.Pointer(name))
|
|
|
|
|
if arg.Op() != ir.OCONVNOP {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
if !arg.Type().IsUintptr() {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
if !arg.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
arg = arg.(*ir.ConvExpr).X
|
|
|
|
|
argname, ok := arg.(*ir.Name)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
for i := range keepAlive {
|
|
|
|
|
if argname == keepAlive[i] {
|
|
|
|
|
return argname
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2021-02-24 12:55:52 -05:00
|
|
|
|
|
|
|
|
// Copy the arguments to the function into temps.
|
2021-03-25 08:30:19 -04:00
|
|
|
//
|
|
|
|
|
// For calls with uintptr(unsafe.Pointer(...)) args that are being
|
|
|
|
|
// kept alive (see code in (*orderState).call that does this), use
|
|
|
|
|
// the existing arg copy instead of creating a new copy.
|
|
|
|
|
unsafeArgs := make([]*ir.Name, len(callArgs))
|
|
|
|
|
origArgs := callArgs
|
2021-02-24 12:55:52 -05:00
|
|
|
var newNames []*ir.Name
|
|
|
|
|
for i := range callArgs {
|
|
|
|
|
arg := callArgs[i]
|
|
|
|
|
var argname *ir.Name
|
2021-03-25 08:30:19 -04:00
|
|
|
unsafeArgName := getUnsafeArg(arg)
|
|
|
|
|
if unsafeArgName != nil {
|
|
|
|
|
// arg has been copied already, use keepalive copy
|
|
|
|
|
argname = unsafeArgName
|
|
|
|
|
unsafeArgs[i] = unsafeArgName
|
2021-02-24 12:55:52 -05:00
|
|
|
} else {
|
|
|
|
|
argname = mkArgCopy(arg)
|
|
|
|
|
}
|
|
|
|
|
newNames = append(newNames, argname)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deal with cases where the function expression (what we're
|
|
|
|
|
// calling) is not a simple function symbol.
|
|
|
|
|
var fnExpr *ir.Name
|
|
|
|
|
var methSelectorExpr *ir.SelectorExpr
|
|
|
|
|
if callX != nil {
|
|
|
|
|
switch {
|
|
|
|
|
case callX.Op() == ir.ODOTMETH || callX.Op() == ir.ODOTINTER:
|
|
|
|
|
// Handle defer of a method call, e.g. "defer v.MyMethod(x, y)"
|
|
|
|
|
n := callX.(*ir.SelectorExpr)
|
|
|
|
|
n.X = mkArgCopy(n.X)
|
|
|
|
|
methSelectorExpr = n
|
2021-03-29 13:44:08 -04:00
|
|
|
if callX.Op() == ir.ODOTINTER {
|
|
|
|
|
// Currently for "defer i.M()" if i is nil it panics at the
|
|
|
|
|
// point of defer statement, not when deferred function is called.
|
|
|
|
|
// (I think there is an issue discussing what is the intended
|
|
|
|
|
// behavior but I cannot find it.)
|
|
|
|
|
// We need to do the nil check outside of the wrapper.
|
|
|
|
|
tab := typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X))
|
|
|
|
|
c := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, tab)
|
|
|
|
|
c.SetTypecheck(1)
|
|
|
|
|
o.append(c)
|
|
|
|
|
}
|
2021-02-24 12:55:52 -05:00
|
|
|
case !(callX.Op() == ir.ONAME && callX.(*ir.Name).Class == ir.PFUNC):
|
|
|
|
|
// Deal with "defer returnsafunc()(x, y)" (for
|
|
|
|
|
// example) by copying the callee expression.
|
|
|
|
|
fnExpr = mkArgCopy(callX)
|
|
|
|
|
if callX.Op() == ir.OCLOSURE {
|
|
|
|
|
// For "defer func(...)", in addition to copying the
|
|
|
|
|
// closure into a temp, mark it as no longer directly
|
|
|
|
|
// called.
|
|
|
|
|
callX.(*ir.ClosureExpr).Func.SetClosureCalled(false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a new no-argument function that we'll hand off to defer.
|
|
|
|
|
var noFuncArgs []*ir.Field
|
|
|
|
|
noargst := ir.NewFuncType(base.Pos, nil, noFuncArgs, nil)
|
|
|
|
|
wrapGoDefer_prgen++
|
2021-03-25 08:30:19 -04:00
|
|
|
outerfn := ir.CurFunc
|
2021-02-24 12:55:52 -05:00
|
|
|
wrapname := fmt.Sprintf("%v·dwrap·%d", outerfn, wrapGoDefer_prgen)
|
|
|
|
|
sym := types.LocalPkg.Lookup(wrapname)
|
|
|
|
|
fn := typecheck.DeclFunc(sym, noargst)
|
|
|
|
|
fn.SetIsHiddenClosure(true)
|
|
|
|
|
fn.SetWrapper(true)
|
|
|
|
|
|
|
|
|
|
// helper for capturing reference to a var declared in an outer scope.
|
|
|
|
|
capName := func(pos src.XPos, fn *ir.Func, n *ir.Name) *ir.Name {
|
|
|
|
|
t := n.Type()
|
|
|
|
|
cv := ir.CaptureName(pos, fn, n)
|
|
|
|
|
cv.SetType(t)
|
|
|
|
|
return typecheck.Expr(cv).(*ir.Name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Call args (x1, y1) need to be captured as part of the newly
|
|
|
|
|
// created closure.
|
|
|
|
|
newCallArgs := []ir.Node{}
|
|
|
|
|
for i := range newNames {
|
|
|
|
|
var arg ir.Node
|
|
|
|
|
arg = capName(callArgs[i].Pos(), fn, newNames[i])
|
|
|
|
|
if unsafeArgs[i] != nil {
|
|
|
|
|
arg = ir.NewConvExpr(arg.Pos(), origArgs[i].Op(), origArgs[i].Type(), arg)
|
|
|
|
|
}
|
|
|
|
|
newCallArgs = append(newCallArgs, arg)
|
|
|
|
|
}
|
|
|
|
|
// Also capture the function or method expression (if needed) into
|
|
|
|
|
// the closure.
|
|
|
|
|
if fnExpr != nil {
|
|
|
|
|
callX = capName(callX.Pos(), fn, fnExpr)
|
|
|
|
|
}
|
|
|
|
|
if methSelectorExpr != nil {
|
|
|
|
|
methSelectorExpr.X = capName(callX.Pos(), fn, methSelectorExpr.X.(*ir.Name))
|
|
|
|
|
}
|
2021-03-25 08:30:19 -04:00
|
|
|
ir.FinishCaptureNames(n.Pos(), outerfn, fn)
|
2021-02-24 12:55:52 -05:00
|
|
|
|
|
|
|
|
// This flags a builtin as opposed to a regular call.
|
|
|
|
|
irregular := (call.Op() != ir.OCALLFUNC &&
|
|
|
|
|
call.Op() != ir.OCALLMETH &&
|
|
|
|
|
call.Op() != ir.OCALLINTER)
|
|
|
|
|
|
|
|
|
|
// Construct new function body: f(x1, y1)
|
|
|
|
|
op := ir.OCALL
|
|
|
|
|
if irregular {
|
|
|
|
|
op = call.Op()
|
|
|
|
|
}
|
|
|
|
|
newcall := mkNewCall(call.Pos(), op, callX, newCallArgs)
|
|
|
|
|
|
|
|
|
|
// Type-check the result.
|
|
|
|
|
if !irregular {
|
|
|
|
|
typecheck.Call(newcall.(*ir.CallExpr))
|
|
|
|
|
} else {
|
|
|
|
|
typecheck.Stmt(newcall)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Finalize body, register function on the main decls list.
|
|
|
|
|
fn.Body = []ir.Node{newcall}
|
|
|
|
|
typecheck.FinishFuncBody()
|
|
|
|
|
typecheck.Func(fn)
|
|
|
|
|
typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
|
|
|
|
|
|
|
|
|
|
// Create closure expr
|
2021-03-25 08:30:19 -04:00
|
|
|
clo := ir.NewClosureExpr(n.Pos(), fn)
|
2021-02-24 12:55:52 -05:00
|
|
|
fn.OClosure = clo
|
|
|
|
|
clo.SetType(fn.Type())
|
|
|
|
|
|
|
|
|
|
// Set escape properties for closure.
|
|
|
|
|
if n.Op() == ir.OGO {
|
|
|
|
|
// For "go", assume that the closure is going to escape
|
|
|
|
|
// (with an exception for the runtime, which doesn't
|
|
|
|
|
// permit heap-allocated closures).
|
|
|
|
|
if base.Ctxt.Pkgpath != "runtime" {
|
|
|
|
|
clo.SetEsc(ir.EscHeap)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// For defer, just use whatever result escape analysis
|
|
|
|
|
// has determined for the defer.
|
|
|
|
|
if n.Esc() == ir.EscNever {
|
|
|
|
|
clo.SetTransient(true)
|
|
|
|
|
clo.SetEsc(ir.EscNone)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create new top level call to closure over argless function.
|
2021-03-25 08:30:19 -04:00
|
|
|
topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, []ir.Node{})
|
2021-02-24 12:55:52 -05:00
|
|
|
typecheck.Call(topcall)
|
|
|
|
|
|
|
|
|
|
// Tag the call to insure that directClosureCall doesn't undo our work.
|
|
|
|
|
topcall.PreserveClosure = true
|
|
|
|
|
|
|
|
|
|
fn.SetClosureCalled(false)
|
|
|
|
|
|
|
|
|
|
// Finally, point the defer statement at the newly generated call.
|
|
|
|
|
n.Call = topcall
|
|
|
|
|
}
|