diff options
Diffstat (limited to 'src/cmd/compile/internal/reflectdata/alg.go')
-rw-r--r-- | src/cmd/compile/internal/reflectdata/alg.go | 84 |
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) } |