forked from TrueCloudLab/neoneo-go
compiler: do not introduce excessive locals on inline
When function call-site parameter is an identifier, we may load it directly. Currently it can be also modified, this will be fixed in a separate commit.
This commit is contained in:
parent
1ae0d022dd
commit
27e60455c7
3 changed files with 32 additions and 12 deletions
|
@ -27,9 +27,19 @@ func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) {
|
||||||
defer c.scope.vars.dropScope()
|
defer c.scope.vars.dropScope()
|
||||||
for i := range n.Args {
|
for i := range n.Args {
|
||||||
c.scope.vars.locals = oldScope
|
c.scope.vars.locals = oldScope
|
||||||
|
name := sig.Params().At(i).Name()
|
||||||
|
if arg, ok := n.Args[i].(*ast.Ident); ok {
|
||||||
|
// When function argument is variable or const, we may avoid
|
||||||
|
// introducing additional variables for parameters.
|
||||||
|
// This is done by providing additional alias to variable.
|
||||||
|
if vt, index := c.scope.vars.getVarIndex(arg.Name); index != -1 {
|
||||||
|
c.scope.vars.locals = newScope
|
||||||
|
c.scope.vars.addAlias(name, vt, index)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
ast.Walk(c, n.Args[i])
|
ast.Walk(c, n.Args[i])
|
||||||
c.scope.vars.locals = newScope
|
c.scope.vars.locals = newScope
|
||||||
name := sig.Params().At(i).Name()
|
|
||||||
c.scope.newLocal(name)
|
c.scope.newLocal(name)
|
||||||
c.emitStoreVar("", name)
|
c.emitStoreVar("", name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,12 +111,7 @@ func TestInlineConversion(t *testing.T) {
|
||||||
a := 2
|
a := 2
|
||||||
{
|
{
|
||||||
b := 1
|
b := 1
|
||||||
c := a
|
return (b + a) * (b + a)
|
||||||
{
|
|
||||||
bb := b
|
|
||||||
cc := c
|
|
||||||
return (bb + cc) * (b + c)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
b2, err := compiler.Compile("foo.go", strings.NewReader(src2))
|
b2, err := compiler.Compile("foo.go", strings.NewReader(src2))
|
||||||
|
|
|
@ -4,7 +4,12 @@ type varScope struct {
|
||||||
localsCnt int
|
localsCnt int
|
||||||
argCnt int
|
argCnt int
|
||||||
arguments map[string]int
|
arguments map[string]int
|
||||||
locals []map[string]int
|
locals []map[string]varInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type varInfo struct {
|
||||||
|
refType varType
|
||||||
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVarScope() varScope {
|
func newVarScope() varScope {
|
||||||
|
@ -14,17 +19,24 @@ func newVarScope() varScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *varScope) newScope() {
|
func (c *varScope) newScope() {
|
||||||
c.locals = append(c.locals, map[string]int{})
|
c.locals = append(c.locals, map[string]varInfo{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *varScope) dropScope() {
|
func (c *varScope) dropScope() {
|
||||||
c.locals = c.locals[:len(c.locals)-1]
|
c.locals = c.locals[:len(c.locals)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *varScope) addAlias(name string, vt varType, index int) {
|
||||||
|
c.locals[len(c.locals)-1][name] = varInfo{
|
||||||
|
refType: vt,
|
||||||
|
index: index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *varScope) getVarIndex(name string) (varType, int) {
|
func (c *varScope) getVarIndex(name string) (varType, int) {
|
||||||
for i := len(c.locals) - 1; i >= 0; i-- {
|
for i := len(c.locals) - 1; i >= 0; i-- {
|
||||||
if i, ok := c.locals[i][name]; ok {
|
if vi, ok := c.locals[i][name]; ok {
|
||||||
return varLocal, i
|
return vi.refType, vi.index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if i, ok := c.arguments[name]; ok {
|
if i, ok := c.arguments[name]; ok {
|
||||||
|
@ -56,7 +68,10 @@ func (c *varScope) newVariable(t varType, name string) int {
|
||||||
func (c *varScope) newLocal(name string) int {
|
func (c *varScope) newLocal(name string) int {
|
||||||
idx := len(c.locals) - 1
|
idx := len(c.locals) - 1
|
||||||
m := c.locals[idx]
|
m := c.locals[idx]
|
||||||
m[name] = c.localsCnt
|
m[name] = varInfo{
|
||||||
|
refType: varLocal,
|
||||||
|
index: c.localsCnt,
|
||||||
|
}
|
||||||
c.localsCnt++
|
c.localsCnt++
|
||||||
c.locals[idx] = m
|
c.locals[idx] = m
|
||||||
return c.localsCnt - 1
|
return c.localsCnt - 1
|
||||||
|
|
Loading…
Reference in a new issue