aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/reflectdata/alg.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/reflectdata/alg.go')
-rw-r--r--src/cmd/compile/internal/reflectdata/alg.go84
1 files changed, 43 insertions, 41 deletions
diff --git a/src/cmd/compile/internal/reflectdata/alg.go b/src/cmd/compile/internal/reflectdata/alg.go
index 69de685ca0..a0f5522153 100644
--- a/src/cmd/compile/internal/reflectdata/alg.go
+++ b/src/cmd/compile/internal/reflectdata/alg.go
@@ -115,7 +115,7 @@ func genhash(t *types.Type) *obj.LSym {
case types.TARRAY:
genhash(t.Elem())
case types.TSTRUCT:
- for _, f := range t.FieldSlice() {
+ for _, f := range t.Fields() {
genhash(f.Type)
}
}
@@ -140,20 +140,25 @@ func hashFunc(t *types.Type) *ir.Func {
return sym.Def.(*ir.Name).Func
}
- base.Pos = base.AutogeneratedPos // less confusing than end of input
- typecheck.DeclContext = ir.PEXTERN
+ pos := base.AutogeneratedPos // less confusing than end of input
+ base.Pos = pos
// func sym(p *T, h uintptr) uintptr
- args := []*ir.Field{
- ir.NewField(base.Pos, typecheck.Lookup("p"), types.NewPtr(t)),
- ir.NewField(base.Pos, typecheck.Lookup("h"), types.Types[types.TUINTPTR]),
- }
- results := []*ir.Field{ir.NewField(base.Pos, nil, types.Types[types.TUINTPTR])}
-
- fn := typecheck.DeclFunc(sym, nil, args, results)
+ fn := ir.NewFunc(pos, pos, sym, types.NewSignature(nil,
+ []*types.Field{
+ types.NewField(pos, typecheck.Lookup("p"), types.NewPtr(t)),
+ types.NewField(pos, typecheck.Lookup("h"), types.Types[types.TUINTPTR]),
+ },
+ []*types.Field{
+ types.NewField(pos, nil, types.Types[types.TUINTPTR]),
+ },
+ ))
sym.Def = fn.Nname
- np := ir.AsNode(fn.Type().Params().Field(0).Nname)
- nh := ir.AsNode(fn.Type().Params().Field(1).Nname)
+ fn.Pragma |= ir.Noinline // TODO(mdempsky): We need to emit this during the unified frontend instead, to allow inlining.
+
+ typecheck.DeclFunc(fn)
+ np := fn.Dcl[0]
+ nh := fn.Dcl[1]
switch t.Kind() {
case types.TARRAY:
@@ -163,7 +168,7 @@ func hashFunc(t *types.Type) *ir.Func {
hashel := hashfor(t.Elem())
// for i := 0; i < nelem; i++
- ni := typecheck.Temp(types.Types[types.TINT])
+ ni := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
init := ir.NewAssignStmt(base.Pos, ni, ir.NewInt(base.Pos, 0))
cond := ir.NewBinaryExpr(base.Pos, ir.OLT, ni, ir.NewInt(base.Pos, t.NumElem()))
post := ir.NewAssignStmt(base.Pos, ni, ir.NewBinaryExpr(base.Pos, ir.OADD, ni, ir.NewInt(base.Pos, 1)))
@@ -185,7 +190,7 @@ func hashFunc(t *types.Type) *ir.Func {
case types.TSTRUCT:
// Walk the struct using memhash for runs of AMEM
// and calling specific hash functions for the others.
- for i, fields := 0, t.FieldSlice(); i < len(fields); {
+ for i, fields := 0, t.Fields(); i < len(fields); {
f := fields[i]
// Skip blank fields.
@@ -198,8 +203,7 @@ func hashFunc(t *types.Type) *ir.Func {
if !compare.IsRegularMemory(f.Type) {
hashel := hashfor(f.Type)
call := ir.NewCallExpr(base.Pos, ir.OCALL, hashel, nil)
- nx := ir.NewSelectorExpr(base.Pos, ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
- na := typecheck.NodAddr(nx)
+ na := typecheck.NodAddr(typecheck.DotField(base.Pos, np, i))
call.Args.Append(na)
call.Args.Append(nh)
fn.Body.Append(ir.NewAssignStmt(base.Pos, nh, call))
@@ -213,8 +217,7 @@ func hashFunc(t *types.Type) *ir.Func {
// h = hashel(&p.first, size, h)
hashel := hashmem(f.Type)
call := ir.NewCallExpr(base.Pos, ir.OCALL, hashel, nil)
- nx := ir.NewSelectorExpr(base.Pos, ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
- na := typecheck.NodAddr(nx)
+ na := typecheck.NodAddr(typecheck.DotField(base.Pos, np, i))
call.Args.Append(na)
call.Args.Append(nh)
call.Args.Append(ir.NewInt(base.Pos, size))
@@ -235,22 +238,18 @@ func hashFunc(t *types.Type) *ir.Func {
typecheck.FinishFuncBody()
fn.SetDupok(true)
- typecheck.Func(fn)
ir.WithFunc(fn, func() {
typecheck.Stmts(fn.Body)
})
fn.SetNilCheckDisabled(true)
- typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
return fn
}
func runtimeHashFor(name string, t *types.Type) *ir.Name {
- n := typecheck.LookupRuntime(name)
- n = typecheck.SubstArgTypes(n, t)
- return n
+ return typecheck.LookupRuntime(name, t)
}
// hashfor returns the function to compute the hash of a value of type t.
@@ -366,18 +365,27 @@ func eqFunc(t *types.Type) *ir.Func {
if sym.Def != nil {
return sym.Def.(*ir.Name).Func
}
- base.Pos = base.AutogeneratedPos // less confusing than end of input
- typecheck.DeclContext = ir.PEXTERN
+
+ pos := base.AutogeneratedPos // less confusing than end of input
+ base.Pos = pos
// func sym(p, q *T) bool
- fn := typecheck.DeclFunc(sym, nil,
- []*ir.Field{ir.NewField(base.Pos, typecheck.Lookup("p"), types.NewPtr(t)), ir.NewField(base.Pos, typecheck.Lookup("q"), types.NewPtr(t))},
- []*ir.Field{ir.NewField(base.Pos, typecheck.Lookup("r"), types.Types[types.TBOOL])},
- )
+ fn := ir.NewFunc(pos, pos, sym, types.NewSignature(nil,
+ []*types.Field{
+ types.NewField(pos, typecheck.Lookup("p"), types.NewPtr(t)),
+ types.NewField(pos, typecheck.Lookup("q"), types.NewPtr(t)),
+ },
+ []*types.Field{
+ types.NewField(pos, typecheck.Lookup("r"), types.Types[types.TBOOL]),
+ },
+ ))
sym.Def = fn.Nname
- np := ir.AsNode(fn.Type().Params().Field(0).Nname)
- nq := ir.AsNode(fn.Type().Params().Field(1).Nname)
- nr := ir.AsNode(fn.Type().Results().Field(0).Nname)
+ fn.Pragma |= ir.Noinline // TODO(mdempsky): We need to emit this during the unified frontend instead, to allow inlining.
+
+ typecheck.DeclFunc(fn)
+ np := fn.Dcl[0]
+ nq := fn.Dcl[1]
+ nr := fn.Dcl[2]
// Label to jump to if an equality test fails.
neq := typecheck.AutoLabel(".neq")
@@ -440,7 +448,7 @@ func eqFunc(t *types.Type) *ir.Func {
if iterateTo > 0 {
// Generate an unrolled for loop.
// for i := 0; i < nelem/unroll*unroll; i += unroll
- i := typecheck.Temp(types.Types[types.TINT])
+ i := typecheck.TempAt(base.Pos, ir.CurFunc, types.Types[types.TINT])
init := ir.NewAssignStmt(base.Pos, i, ir.NewInt(base.Pos, 0))
cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(base.Pos, iterateTo))
loop := ir.NewForStmt(base.Pos, nil, cond, nil, nil, false)
@@ -619,7 +627,6 @@ func eqFunc(t *types.Type) *ir.Func {
typecheck.FinishFuncBody()
fn.SetDupok(true)
- typecheck.Func(fn)
ir.WithFunc(fn, func() {
typecheck.Stmts(fn.Body)
@@ -630,7 +637,6 @@ func eqFunc(t *types.Type) *ir.Func {
// neither of which can be nil, and our comparisons
// are shallow.
fn.SetNilCheckDisabled(true)
- typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
return fn
}
@@ -639,9 +645,7 @@ func eqFunc(t *types.Type) *ir.Func {
func EqFor(t *types.Type) (ir.Node, bool) {
switch a, _ := types.AlgType(t); a {
case types.AMEM:
- n := typecheck.LookupRuntime("memequal")
- n = typecheck.SubstArgTypes(n, t, t)
- return n, true
+ return typecheck.LookupRuntime("memequal", t, t), true
case types.ASPECIAL:
fn := eqFunc(t)
return fn.Nname, false
@@ -659,7 +663,5 @@ func anyCall(fn *ir.Func) bool {
}
func hashmem(t *types.Type) ir.Node {
- n := typecheck.LookupRuntime("memhash")
- n = typecheck.SubstArgTypes(n, t)
- return n
+ return typecheck.LookupRuntime("memhash", t)
}