perf(gengo): elide dead-store inits for const-propagated LOCALs
When collectConstLocals proves a LOCAL is only ever read, not written beyond its literal init, every read site gets the literal substituted inline — which means the init itself has no live reader. Skip emitting the PushXxx/PopLocalFast pair for those LOCALs in both top-of-function and mid-body decls. On a function with `LOCAL nBuf := 100, sTag := "x", bFlag := .T.`, all three inits drop out (6 VM ops saved in the prologue), while the still-written `LOCAL nSum := 0` init stays. Harbour compat 56/56, FiveSql2 43/43. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -939,7 +939,9 @@ func (g *Generator) emitFuncDecl(fn *ast.FuncDecl) {
|
||||
// so reads can be constant-propagated at emit time.
|
||||
g.constLocals = collectConstLocals(fn)
|
||||
|
||||
// Emit LOCAL initializers
|
||||
// Emit LOCAL initializers. LOCALs that were const-propagated have
|
||||
// their reads substituted inline, so the init store has no live
|
||||
// reader — skip it (dead-store elimination).
|
||||
localIdx := nParams + 1 // 1-based, params come first
|
||||
for _, d := range fn.Decls {
|
||||
vd, ok := d.(*ast.VarDecl)
|
||||
@@ -948,8 +950,10 @@ func (g *Generator) emitFuncDecl(fn *ast.FuncDecl) {
|
||||
}
|
||||
for _, v := range vd.Vars {
|
||||
if v.Init != nil {
|
||||
g.emitExpr(v.Init)
|
||||
g.writeln(fmt.Sprintf("t.PopLocalFast(%d)", localIdx))
|
||||
if _, isConst := g.constLocals[strings.ToUpper(v.Name)]; !isConst {
|
||||
g.emitExpr(v.Init)
|
||||
g.writeln(fmt.Sprintf("t.PopLocalFast(%d)", localIdx))
|
||||
}
|
||||
}
|
||||
localIdx++
|
||||
}
|
||||
@@ -1330,8 +1334,10 @@ func (g *Generator) emitMidVarDecl(s *ast.VarDecl, locals localMap) {
|
||||
locals[strings.ToUpper(v.Name)] = idx
|
||||
}
|
||||
if v.Init != nil {
|
||||
g.emitExpr(v.Init)
|
||||
g.writeln(fmt.Sprintf("t.PopLocalFast(%d)", idx))
|
||||
if _, isConst := g.constLocals[strings.ToUpper(v.Name)]; !isConst {
|
||||
g.emitExpr(v.Init)
|
||||
g.writeln(fmt.Sprintf("t.PopLocalFast(%d)", idx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user