[dev.ssa] cmd/compile: exposed do-log boolean to reduce allocations

From memory profiling, about 3% reduction in allocation count.

Change-Id: I4b662d55b8a94fe724759a2b22f05a08d0bf40f8
Reviewed-on: https://go-review.googlesource.com/19103
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 89286f4..c5be349 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -327,6 +327,7 @@
 }
 
 func (s *state) Logf(msg string, args ...interface{})   { s.config.Logf(msg, args...) }
+func (s *state) Log() bool                              { return s.config.Log() }
 func (s *state) Fatalf(msg string, args ...interface{}) { s.config.Fatalf(s.peekLine(), msg, args...) }
 func (s *state) Unimplementedf(msg string, args ...interface{}) {
 	s.config.Unimplementedf(s.peekLine(), msg, args...)
@@ -4885,6 +4886,10 @@
 	}
 }
 
+func (e *ssaExport) Log() bool {
+	return e.log
+}
+
 // Fatal reports a compiler error and exits.
 func (e *ssaExport) Fatalf(line int32, msg string, args ...interface{}) {
 	// If e was marked as unimplemented, anything could happen. Ignore.
diff --git a/src/cmd/compile/internal/ssa/block.go b/src/cmd/compile/internal/ssa/block.go
index 6585528..7641811 100644
--- a/src/cmd/compile/internal/ssa/block.go
+++ b/src/cmd/compile/internal/ssa/block.go
@@ -105,6 +105,7 @@
 }
 
 func (b *Block) Logf(msg string, args ...interface{})           { b.Func.Logf(msg, args...) }
+func (b *Block) Log() bool                                      { return b.Func.Log() }
 func (b *Block) Fatalf(msg string, args ...interface{})         { b.Func.Fatalf(msg, args...) }
 func (b *Block) Unimplementedf(msg string, args ...interface{}) { b.Func.Unimplementedf(msg, args...) }
 
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index 75c73eb..99e3c2b 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -20,7 +20,9 @@
 func Compile(f *Func) {
 	// TODO: debugging - set flags to control verbosity of compiler,
 	// which phases to dump IR before/after, etc.
-	f.Logf("compiling %s\n", f.Name)
+	if f.Log() {
+		f.Logf("compiling %s\n", f.Name)
+	}
 
 	// hook to print function & phase if panic happens
 	phaseName := "init"
@@ -44,7 +46,9 @@
 			continue
 		}
 		phaseName = p.name
-		f.Logf("  pass %s begin\n", p.name)
+		if f.Log() {
+			f.Logf("  pass %s begin\n", p.name)
+		}
 		// TODO: capture logging during this pass, add it to the HTML
 		var mStart runtime.MemStats
 		if logMemStats {
@@ -67,9 +71,13 @@
 			stats = fmt.Sprintf("[%d ns]", time)
 		}
 
-		f.Logf("  pass %s end %s\n", p.name, stats)
+		if f.Log() {
+			f.Logf("  pass %s end %s\n", p.name, stats)
+		}
 		printFunc(f)
-		f.Config.HTML.WriteFunc(fmt.Sprintf("after %s <span class=\"stats\">%s</span>", phaseName, stats), f)
+		if f.Config.HTML != nil {
+			f.Config.HTML.WriteFunc(fmt.Sprintf("after %s <span class=\"stats\">%s</span>", phaseName, stats), f)
+		}
 		checkFunc(f)
 	}
 
diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go
index 52e772c..060eec2 100644
--- a/src/cmd/compile/internal/ssa/config.go
+++ b/src/cmd/compile/internal/ssa/config.go
@@ -46,9 +46,13 @@
 }
 
 type Logger interface {
-	// Log logs a message from the compiler.
+	// Logf logs a message from the compiler.
 	Logf(string, ...interface{})
 
+	// Log returns true if logging is not a no-op
+	// some logging calls account for more than a few heap allocations.
+	Log() bool
+
 	// Fatal reports a compiler error and exits.
 	Fatalf(line int32, msg string, args ...interface{})
 
@@ -131,6 +135,7 @@
 }
 
 func (c *Config) Logf(msg string, args ...interface{})               { c.fe.Logf(msg, args...) }
+func (c *Config) Log() bool                                          { return c.fe.Log() }
 func (c *Config) Fatalf(line int32, msg string, args ...interface{}) { c.fe.Fatalf(line, msg, args...) }
 func (c *Config) Unimplementedf(line int32, msg string, args ...interface{}) {
 	c.fe.Unimplementedf(line, msg, args...)
diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go
index 962dc52..dae9ed7 100644
--- a/src/cmd/compile/internal/ssa/export_test.go
+++ b/src/cmd/compile/internal/ssa/export_test.go
@@ -36,6 +36,7 @@
 }
 
 func (d DummyFrontend) Logf(msg string, args ...interface{}) { d.t.Logf(msg, args...) }
+func (d DummyFrontend) Log() bool                            { return true }
 
 func (d DummyFrontend) Fatalf(line int32, msg string, args ...interface{}) { d.t.Fatalf(msg, args...) }
 func (d DummyFrontend) Unimplementedf(line int32, msg string, args ...interface{}) {
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go
index 6d20a27..a284840 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -264,6 +264,7 @@
 }
 
 func (f *Func) Logf(msg string, args ...interface{})   { f.Config.Logf(msg, args...) }
+func (f *Func) Log() bool                              { return f.Config.Log() }
 func (f *Func) Fatalf(msg string, args ...interface{}) { f.Config.Fatalf(f.Entry.Line, msg, args...) }
 func (f *Func) Unimplementedf(msg string, args ...interface{}) {
 	f.Config.Unimplementedf(f.Entry.Line, msg, args...)
diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go
index 7e6e544..e338c44 100644
--- a/src/cmd/compile/internal/ssa/value.go
+++ b/src/cmd/compile/internal/ssa/value.go
@@ -147,6 +147,7 @@
 }
 
 func (v *Value) Logf(msg string, args ...interface{}) { v.Block.Logf(msg, args...) }
+func (v *Value) Log() bool                            { return v.Block.Log() }
 func (v *Value) Fatalf(msg string, args ...interface{}) {
 	v.Block.Func.Config.Fatalf(v.Line, msg, args...)
 }