cmd/compile: clean up ssa.Value memory arg usage

This change adds a method to replace expressions
of the form

   v.Args[len(v.Args)-1]

so that the code's intention to walk memory arguments
is explicit.

Passes toolstash-check.

Change-Id: I0c80d73bc00989dd3cdf72b4f2c8e1075a2515e0
Reviewed-on: https://go-review.googlesource.com/37757
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go
index 00f2454..93172bc 100644
--- a/src/cmd/compile/internal/ssa/value.go
+++ b/src/cmd/compile/internal/ssa/value.go
@@ -311,3 +311,23 @@
 	}
 	return reg.(*Register).name
 }
+
+// MemoryArg returns the memory argument for the Value.
+// The returned value, if non-nil, will be memory-typed,
+// except in the case where v is Select1, in which case
+// the returned value will be a tuple containing a memory
+// type. Otherwise, nil is returned.
+func (v *Value) MemoryArg() *Value {
+	if v.Op == OpPhi {
+		v.Fatalf("MemoryArg on Phi")
+	}
+	na := len(v.Args)
+	if na == 0 {
+		return nil
+	}
+	if m := v.Args[na-1]; m.Type.IsMemory() ||
+		(v.Op == OpSelect1 && m.Type.FieldType(1).IsMemory()) {
+		return m
+	}
+	return nil
+}