Commit 3dcc424b authored by Keith Randall's avatar Keith Randall

[dev.ssa] cmd/compile/internal/ssa: compute outarg size correctly

Keep track of the outargs size needed at each call.
Compute the size of the outargs section of the stack frame.  It's just
the max of the outargs size at all the callsites in the function.

Change-Id: I3d0640f654f01307633b1a5f75bab16e211ea6c0
Reviewed-on: https://go-review.googlesource.com/12178Reviewed-by: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 8adc905a
......@@ -626,6 +626,8 @@ func (s *state) expr(n *Node) *ssa.Value {
entry := s.newValue2(ssa.OpLoad, s.config.Uintptr, closure, s.mem())
call = s.newValue3(ssa.OpClosureCall, ssa.TypeMem, entry, closure, s.mem())
}
dowidth(n.Left.Type)
call.AuxInt = n.Left.Type.Argwid // call operations carry the argsize of the callee along with them
b := s.endBlock()
b.Kind = ssa.BlockCall
b.Control = call
......
......@@ -29,7 +29,6 @@ Regalloc
- Make calls clobber all registers
StackAlloc:
- Compute size of outargs section correctly
- Sort variables so all ptr-containing ones are first (so stack
maps are smaller)
- Reuse stack slots for noninterfering and type-compatible variables
......
......@@ -88,8 +88,8 @@
(If (SETB cmp) yes no) -> (ULT cmp yes no)
(If cond yes no) && cond.Op == OpAMD64MOVBload -> (NE (TESTB <TypeFlags> cond cond) yes no)
(StaticCall {target} mem) -> (CALLstatic {target} mem)
(ClosureCall entry closure mem) -> (CALLclosure entry closure mem)
(StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem)
(ClosureCall [argwid] entry closure mem) -> (CALLclosure [argwid] entry closure mem)
// Rules below here apply some simple optimizations after lowering.
// TODO: Should this be a separate pass?
......
......@@ -460,10 +460,11 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
endf8ca12fe79290bc82b11cfa463bc9413:
;
case OpClosureCall:
// match: (ClosureCall entry closure mem)
// match: (ClosureCall [argwid] entry closure mem)
// cond:
// result: (CALLclosure entry closure mem)
// result: (CALLclosure [argwid] entry closure mem)
{
argwid := v.AuxInt
entry := v.Args[0]
closure := v.Args[1]
mem := v.Args[2]
......@@ -471,13 +472,14 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AuxInt = argwid
v.AddArg(entry)
v.AddArg(closure)
v.AddArg(mem)
return true
}
goto endee26da781e813a3c602ccb4f7ade98c7
endee26da781e813a3c602ccb4f7ade98c7:
goto endfd75d26316012d86cb71d0dd1214259b
endfd75d26316012d86cb71d0dd1214259b:
;
case OpConst:
// match: (Const <t> [val])
......@@ -1611,22 +1613,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
end78e66b6fc298684ff4ac8aec5ce873c9:
;
case OpStaticCall:
// match: (StaticCall {target} mem)
// match: (StaticCall [argwid] {target} mem)
// cond:
// result: (CALLstatic {target} mem)
// result: (CALLstatic [argwid] {target} mem)
{
argwid := v.AuxInt
target := v.Aux
mem := v.Args[0]
v.Op = OpAMD64CALLstatic
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AuxInt = argwid
v.Aux = target
v.AddArg(mem)
return true
}
goto end1948857a7cfc2a4f905045e58d3b9ec1
end1948857a7cfc2a4f905045e58d3b9ec1:
goto end32c5cbec813d1c2ae94fc9b1090e4b2a
end32c5cbec813d1c2ae94fc9b1090e4b2a:
;
case OpStore:
// match: (Store ptr val mem)
......
......@@ -9,12 +9,16 @@ package ssa
func stackalloc(f *Func) {
home := f.RegAlloc
// First compute the size of the outargs section.
n := int64(16) //TODO: compute max of all callsites
// Include one slot for deferreturn.
if false && n < f.Config.ptrSize { //TODO: check for deferreturn
n = f.Config.ptrSize
// Start with space for callee arguments/returns.
var n int64
for _, b := range f.Blocks {
if b.Kind != BlockCall {
continue
}
v := b.Control
if n < v.AuxInt {
n = v.AuxInt
}
}
// TODO: group variables by ptr/nonptr, size, etc. Emit ptr vars last
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment