Skip to content

Commit f0e4685

Browse files
committed
Specialize exact Go int parameters
1 parent 5cee4fa commit f0e4685

7 files changed

Lines changed: 328 additions & 114 deletions

File tree

pkg/runtime/codegen.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type varScope struct {
3939
localStringStacks map[string]bool // confined string stacks
4040
ownedStringParts map[string]bool // private loop-carried str arguments
4141
ownedMaps map[string]bool // uniquely owned loop-carried maps
42-
localTypes map[string]compiler.IRValueKind
42+
localTypes map[string]compiler.IRType
4343
}
4444

4545
// recurContext represents the context for a loop/recur form
@@ -99,7 +99,9 @@ type aotSpecializationTarget struct {
9999
int64Analysis *int64AOTAnalysis
100100
int64Safe bool
101101
int64ParamFnVar string
102-
int64ParamAnalysis *int64ParamAOTAnalysis
102+
int64ParamAnalysis *exactIntegerParamAOTAnalysis
103+
intParamFnVar string
104+
intParamAnalysis *exactIntegerParamAOTAnalysis
103105
float64FnVar string
104106
float64Analysis *float64AOTAnalysis
105107
vectorFnVar string
@@ -268,7 +270,7 @@ func newGenerator(w io.Writer, directLink bool) *Generator {
268270
localStringStacks: make(map[string]bool),
269271
ownedStringParts: make(map[string]bool),
270272
ownedMaps: make(map[string]bool),
271-
localTypes: make(map[string]compiler.IRValueKind),
273+
localTypes: make(map[string]compiler.IRType),
272274
}},
273275
recurStack: []recurContext{},
274276
imports: make(map[string]string),
@@ -1613,7 +1615,7 @@ func (g *Generator) generateFn(fn *Fn) string {
16131615
!g.generateOwnedVectorSpecializedFixedFn(fn, fnVar, methodNode, paramNames) &&
16141616
!g.generateInt64SpecializedFixedFn(fn, fnVar, methodNode, paramNames) &&
16151617
!g.generateFloat64SpecializedFixedFn(fn, fnVar, methodNode, paramNames) &&
1616-
!g.generateInt64ParameterSpecializedFixedFn(
1618+
!g.generateIntegerParameterSpecializedFixedFn(
16171619
fn,
16181620
fnVar,
16191621
methodNode,
@@ -1883,7 +1885,7 @@ func (g *Generator) generateFnMethodFixed(methodNode *ast.FnMethodNode, paramVar
18831885
func (g *Generator) generateFnMethodFixedWithTypes(
18841886
methodNode *ast.FnMethodNode,
18851887
paramVarNames []string,
1886-
paramTypes []compiler.IRValueKind,
1888+
paramTypes []compiler.IRType,
18871889
) {
18881890
// Push a new scope for the method body
18891891
g.pushVarScope()
@@ -1895,9 +1897,8 @@ func (g *Generator) generateFnMethodFixedWithTypes(
18951897
for i, param := range methodNode.Params {
18961898
paramNode := param.Sub.(*ast.BindingNode)
18971899
paramVar := g.allocateLocal(paramNode.Name.Name())
1898-
if i < len(paramTypes) &&
1899-
paramTypes[i] != compiler.IRDynamic {
1900-
g.markLocalType(paramNode.Name.Name(), paramTypes[i])
1900+
if i < len(paramTypes) && paramTypes[i].Kind != compiler.IRDynamic {
1901+
g.markLocalIRType(paramNode.Name.Name(), paramTypes[i])
19011902
} else if g.currentVector != nil &&
19021903
g.currentVector.paramMask&(uint32(1)<<i) == 0 {
19031904
g.markLocalType(paramNode.Name.Name(), compiler.IRInt)
@@ -2261,7 +2262,7 @@ func (g *Generator) generateInvoke(node *ast.Node) string {
22612262
if result, ok := g.generateAOTMultiFnInvoke(node); ok {
22622263
return result
22632264
}
2264-
if result, ok := g.generateAOTInt64ParameterInvoke(node); ok {
2265+
if result, ok := g.generateAOTIntegerParameterInvoke(node); ok {
22652266
return result
22662267
}
22672268
if result, ok := g.generateAOTSafeInt64Invoke(node); ok {
@@ -2988,6 +2989,7 @@ func (g *Generator) generateLet(node *ast.Node, isLoop bool) string {
29882989
continue
29892990
}
29902991
if bindingFacts.StableType.Kind == compiler.IRInt &&
2992+
bindingFacts.StableType.GoType == reflect.TypeFor[int64]() &&
29912993
(isLoop || g.irHasInt64Representation(init)) {
29922994
initCode := g.generateASTNode(init)
29932995
varName := g.allocateLocal(name)
@@ -3005,6 +3007,7 @@ func (g *Generator) generateLet(node *ast.Node, isLoop bool) string {
30053007
continue
30063008
}
30073009
if bindingFacts.StableType.Kind == compiler.IRFloat &&
3010+
bindingFacts.StableType.GoType == reflect.TypeFor[float64]() &&
30083011
(isLoop || g.irHasFloat64Representation(init)) {
30093012
initCode := g.generateASTNode(init)
30103013
varName := g.allocateLocal(name)
@@ -4219,7 +4222,7 @@ func (g *Generator) pushVarScope() {
42194222
localStringStacks: make(map[string]bool),
42204223
ownedStringParts: make(map[string]bool),
42214224
ownedMaps: make(map[string]bool),
4222-
localTypes: make(map[string]compiler.IRValueKind),
4225+
localTypes: make(map[string]compiler.IRType),
42234226
})
42244227
}
42254228

@@ -4387,17 +4390,36 @@ func (g *Generator) markLocalType(
43874390
name string,
43884391
kind compiler.IRValueKind,
43894392
) {
4390-
g.varScopes[len(g.varScopes)-1].localTypes[name] = kind
4393+
typ := compiler.IRType{Kind: kind}
4394+
switch kind {
4395+
case compiler.IRBool:
4396+
typ.GoType = reflect.TypeFor[bool]()
4397+
case compiler.IRInt:
4398+
typ.GoType = reflect.TypeFor[int64]()
4399+
case compiler.IRFloat:
4400+
typ.GoType = reflect.TypeFor[float64]()
4401+
case compiler.IRString:
4402+
typ.GoType = reflect.TypeFor[string]()
4403+
}
4404+
g.markLocalIRType(name, typ)
43914405
}
43924406

4393-
func (g *Generator) getLocalType(name string) compiler.IRValueKind {
4407+
func (g *Generator) markLocalIRType(name string, typ compiler.IRType) {
4408+
g.varScopes[len(g.varScopes)-1].localTypes[name] = typ
4409+
}
4410+
4411+
func (g *Generator) getLocalIRType(name string) compiler.IRType {
43944412
for i := len(g.varScopes) - 1; i >= 0; i-- {
43954413
scope := &g.varScopes[i]
43964414
if _, ok := scope.names[name]; ok {
43974415
return scope.localTypes[name]
43984416
}
43994417
}
4400-
return compiler.IRDynamic
4418+
return compiler.IRType{Kind: compiler.IRDynamic, Nullable: true}
4419+
}
4420+
4421+
func (g *Generator) getLocalType(name string) compiler.IRValueKind {
4422+
return g.getLocalIRType(name).Kind
44014423
}
44024424

44034425
// allocateTempVar allocates a fresh temporary variable without name tracking

pkg/runtime/codegen_direct.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (g *Generator) prepareAOTCallTargets(vars []namedVar) {
6868
directFnVar: fmt.Sprintf("aotDirectFn%d", index),
6969
int64FnVar: fmt.Sprintf("aotInt64Fn%d", index),
7070
int64ParamFnVar: fmt.Sprintf("aotInt64ParamFn%d", index),
71+
intParamFnVar: fmt.Sprintf("aotIntParamFn%d", index),
7172
float64FnVar: fmt.Sprintf("aotFloat64Fn%d", index),
7273
vectorFnVar: fmt.Sprintf("aotVectorFn%d", index),
7374
ownedVectorFnVar: fmt.Sprintf("aotOwnedVectorFn%d", index),
@@ -234,7 +235,7 @@ func (g *Generator) prepareAOTCallTargets(vars []namedVar) {
234235
break
235236
}
236237
}
237-
g.prepareInt64ParameterSpecializations()
238+
g.prepareIntegerParameterSpecializations()
238239
for _, named := range vars {
239240
target := g.aotCallTargets[named.vr]
240241
if target == nil {
@@ -258,8 +259,22 @@ func (g *Generator) prepareAOTCallTargets(vars []namedVar) {
258259
"var %s func(%s) any\n",
259260
target.int64ParamFnVar,
260261
strings.Join(
261-
int64ParamAOTTypes(
262-
target.int64ParamAnalysis.paramMask,
262+
exactIntegerParamAOTTypes(
263+
target.int64ParamAnalysis,
264+
target.arity,
265+
),
266+
", ",
267+
),
268+
)
269+
}
270+
if target.intParamAnalysis != nil {
271+
fmt.Fprintf(
272+
&g.aotDeclarations,
273+
"var %s func(%s) any\n",
274+
target.intParamFnVar,
275+
strings.Join(
276+
exactIntegerParamAOTTypes(
277+
target.intParamAnalysis,
263278
target.arity,
264279
),
265280
", ",

pkg/runtime/codegen_int64.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ func (g *Generator) generateInt64SpecializedFixedFn(
147147
g.writef("return %s, true\n", result)
148148
g.writef("}\n")
149149
g.writef("%s = %s\n", target.int64FnVar, helper)
150+
if target.intParamAnalysis != nil {
151+
g.generateExactIntegerParameterHelper(
152+
method,
153+
target.intParamAnalysis,
154+
target.intParamFnVar,
155+
)
156+
}
150157

151158
arity := method.FixedArity
152159
signature := ""
@@ -175,6 +182,13 @@ func (g *Generator) generateInt64SpecializedFixedFn(
175182
if arity > 0 {
176183
g.writef("}\n")
177184
}
185+
if target.intParamAnalysis != nil {
186+
g.generateExactIntegerParameterGuard(
187+
target.intParamAnalysis,
188+
target.intParamFnVar,
189+
paramNames,
190+
)
191+
}
178192

179193
g.generateFnMethodFixed(method, paramNames)
180194
g.writef("})\n")

0 commit comments

Comments
 (0)