The comments were mostly duplicated; unify them.
Add a check that the required invariant holds.
Change-Id: I42fe09dcd1fac76d3c4e191f7a58c591c5ce429b
Reviewed-on: https://go-review.googlesource.com/24719
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
case ssa.OpArg:
// input args need no code
case ssa.OpAMD64LoweredGetClosurePtr:
- // Output is hardwired to DX only,
- // and DX contains the closure pointer on
- // closure entry, and this "instruction"
- // is scheduled to the very beginning
- // of the entry block.
+ // Closure pointer is DX.
+ gc.CheckLoweredGetClosurePtr(v)
case ssa.OpAMD64LoweredGetG:
r := gc.SSARegNum(v)
// See the comments in cmd/internal/obj/x86/obj6.go
ssa.OpARMLoweredSelect1:
// nothing to do
case ssa.OpARMLoweredGetClosurePtr:
- // Output is hardwired to R7 (arm.REGCTXT) only,
- // and R7 contains the closure pointer on
- // closure entry, and this "instruction"
- // is scheduled to the very beginning
- // of the entry block.
- // nothing to do here.
+ // Closure pointer is R7 (arm.REGCTXT).
+ gc.CheckLoweredGetClosurePtr(v)
default:
v.Unimplementedf("genValue not implemented: %s", v.LongString())
}
}
}
+// CheckLoweredGetClosurePtr checks that v is the first instruction in the function's entry block.
+// The output of LoweredGetClosurePtr is generally hardwired to the correct register.
+// That register contains the closure pointer on closure entry.
+func CheckLoweredGetClosurePtr(v *ssa.Value) {
+ entry := v.Block.Func.Entry
+ if entry != v.Block || entry.Values[0] != v {
+ Fatalf("badly placed LoweredGetClosurePtr: %v %v", v.Block, v)
+ }
+}
+
// AutoVar returns a *Node and int64 representing the auto variable and offset within it
// where v should be spilled.
func AutoVar(v *ssa.Value) (*Node, int64) {