]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: insert ' ' and \n at beginning of walkprint
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 21 May 2017 22:18:08 +0000 (15:18 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Tue, 15 Aug 2017 21:54:30 +0000 (21:54 +0000)
Rather than emitting spaces and newlines for println
as we walk the expression, construct it all up front.
This enables further optimizations.

This requires using printstring instead of print in
the implementation of printsp and printnl,
on pain of infinite recursion.
That's ok; it's more efficient anyway, and just as simple.
While we're here, do it for other print routines as well.

Change-Id: I61d7df143810e00710c4d4d948d904007a7fd190
Reviewed-on: https://go-review.googlesource.com/55097
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/walk.go
src/runtime/print.go

index 309470f7b65147b5bf1c0cf355c2559788f1e4bb..b7b27d64d86f0289e2f9e09ce11f9eab736d76af 100644 (file)
@@ -448,6 +448,10 @@ func nodbool(b bool) *Node {
        return c
 }
 
+func nodstr(s string) *Node {
+       return nodlit(Val{s})
+}
+
 // treecopy recursively copies n, with the exception of
 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves.
 // Copies of iota ONONAME nodes are assigned the current
index 482adb9e04af1b306af959ae7b03e8d86f1409cf..667dd2acb17822c6b708304edf7e61ef24ca4e04 100644 (file)
@@ -2022,15 +2022,22 @@ func walkprint(nn *Node, init *Nodes) *Node {
        // Hoist all the argument evaluation up before the lock.
        walkexprlistcheap(nn.List.Slice(), init)
 
-       notfirst := false
-       calls := []*Node{mkcall("printlock", nil, init)}
-       for i, n := range nn.List.Slice() {
-               if notfirst {
-                       calls = append(calls, mkcall("printsp", nil, init))
+       // For println, add " " between elements and "\n" at the end.
+       if nn.Op == OPRINTN {
+               s := nn.List.Slice()
+               t := make([]*Node, 0, len(s)*2)
+               for i, n := range s {
+                       x := " "
+                       if len(s)-1 == i {
+                               x = "\n"
+                       }
+                       t = append(t, n, nodstr(x))
                }
+               nn.List.Set(t)
+       }
 
-               notfirst = nn.Op == OPRINTN
-
+       calls := []*Node{mkcall("printlock", nil, init)}
+       for i, n := range nn.List.Slice() {
                if n.Op == OLITERAL {
                        switch n.Val().Ctype() {
                        case CTRUNE:
@@ -2083,28 +2090,35 @@ func walkprint(nn *Node, init *Nodes) *Node {
                case TBOOL:
                        on = syslook("printbool")
                case TSTRING:
-                       on = syslook("printstring")
+                       cs := ""
+                       if Isconst(n, CTSTR) {
+                               cs = n.Val().U.(string)
+                       }
+                       switch cs {
+                       case " ":
+                               on = syslook("printsp")
+                       case "\n":
+                               on = syslook("printnl")
+                       default:
+                               on = syslook("printstring")
+                       }
                default:
                        badtype(OPRINT, n.Type, nil)
                        continue
                }
 
-               t := on.Type.Params().Field(0).Type
-
-               if !eqtype(t, n.Type) {
-                       n = nod(OCONV, n, nil)
-                       n.Type = t
-               }
-
                r := nod(OCALL, on, nil)
-               r.List.Append(n)
+               if params := on.Type.Params().FieldSlice(); len(params) > 0 {
+                       t := params[0].Type
+                       if !eqtype(t, n.Type) {
+                               n = nod(OCONV, n, nil)
+                               n.Type = t
+                       }
+                       r.List.Append(n)
+               }
                calls = append(calls, r)
        }
 
-       if nn.Op == OPRINTN {
-               calls = append(calls, mkcall("printnl", nil, nil))
-       }
-
        calls = append(calls, mkcall("printunlock", nil, init))
 
        typecheckslice(calls, Etop)
index 8fa3d3990526ada65d96e8ccf27a89f30c696f87..a698fcb0e09ce1f429aea41eef583d36f900ac2b 100644 (file)
@@ -56,7 +56,7 @@ var debuglock mutex
 
 // The compiler emits calls to printlock and printunlock around
 // the multiple calls that implement a single Go print or println
-// statement. Some of the print helpers (printsp, for example)
+// statement. Some of the print helpers (printslice, for example)
 // call print recursively. There is also the problem of a crash
 // happening during the print routines and needing to acquire
 // the print lock to print information about the crash.
@@ -98,31 +98,31 @@ func gwrite(b []byte) {
 }
 
 func printsp() {
-       print(" ")
+       printstring(" ")
 }
 
 func printnl() {
-       print("\n")
+       printstring("\n")
 }
 
 func printbool(v bool) {
        if v {
-               print("true")
+               printstring("true")
        } else {
-               print("false")
+               printstring("false")
        }
 }
 
 func printfloat(v float64) {
        switch {
        case v != v:
-               print("NaN")
+               printstring("NaN")
                return
        case v+v == v && v > 0:
-               print("+Inf")
+               printstring("+Inf")
                return
        case v+v == v && v < 0:
-               print("-Inf")
+               printstring("-Inf")
                return
        }
 
@@ -204,7 +204,7 @@ func printuint(v uint64) {
 
 func printint(v int64) {
        if v < 0 {
-               print("-")
+               printstring("-")
                v = -v
        }
        printuint(uint64(v))