gc: fix order of evaluation

Pulling function calls out to happen before the
expression being evaluated was causing illegal
reorderings even without inlining; with inlining
it got worse.  This CL adds a separate ordering pass
to move things with a fixed order out of expressions
and into the statement sequence, where they will
not be reordered by walk.

Replaces lvd's CL 5534079.

Fixes #2740.

R=lvd
CC=golang-dev
https://golang.org/cl/5569062
diff --git a/test/func8.go b/test/func8.go
new file mode 100644
index 0000000..bb61064
--- /dev/null
+++ b/test/func8.go
@@ -0,0 +1,47 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var calledf int
+
+func f() int {
+	calledf++
+	return 0
+}
+
+func g() int {
+	return calledf
+}
+
+var xy string
+
+func x() bool {
+	for false {
+	} // no inlining
+	xy += "x"
+	return false
+}
+
+func y() string {
+	for false {
+	} // no inlining
+	xy += "y"
+	return "abc"
+}
+
+func main() {
+	if f() == g() {
+		println("wrong f,g order")
+	}
+
+	if x() == (y() == "abc") {
+		panic("wrong compare")
+	}
+	if xy != "xy" {
+		println("wrong x,y order")
+	}
+}