diff options
author | Cherry Zhang <cherryyz@google.com> | 2021-04-03 20:09:15 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2021-04-06 20:22:15 +0000 |
commit | f5efa5a313cbfdbd86aa342f8bc2a4cc66f51a6e (patch) | |
tree | cdbe97e33471553618e9ef442bbdd134827b8945 /src/cmd/compile/internal/amd64 | |
parent | bcc4422ee1bdb8051a6c870cf00e837814614a0f (diff) | |
download | go-f5efa5a313cbfdbd86aa342f8bc2a4cc66f51a6e.tar.gz go-f5efa5a313cbfdbd86aa342f8bc2a4cc66f51a6e.zip |
cmd/compile: load results into registers on open defer return path
When a function panics then recovers, it needs to return to the
caller with named results having the correct values. For
in-register results, we need to load them into registers at the
defer return path.
For non-open-coded defers, we already generate correct code, as
the defer return path is part of the SSA CFG and contains the
instructions that are the same as an ordinary return statement,
including putting the results to the right places.
For open-coded defers, we have a special code generation that
emits a disconnected block that currently contains only the
deferreturn call and a RET instruction. It leaves the result
registers unset. This CL adds instructions that load the result
registers on that path.
Updates #40724.
Change-Id: I1f60514da644fd5fb4b4871a1153c62f42927282
Reviewed-on: https://go-review.googlesource.com/c/go/+/307231
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/cmd/compile/internal/amd64')
-rw-r--r-- | src/cmd/compile/internal/amd64/galign.go | 1 | ||||
-rw-r--r-- | src/cmd/compile/internal/amd64/ssa.go | 16 |
2 files changed, 17 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/amd64/galign.go b/src/cmd/compile/internal/amd64/galign.go index ce1c402902..7845395538 100644 --- a/src/cmd/compile/internal/amd64/galign.go +++ b/src/cmd/compile/internal/amd64/galign.go @@ -23,4 +23,5 @@ func Init(arch *ssagen.ArchInfo) { arch.SSAMarkMoves = ssaMarkMoves arch.SSAGenValue = ssaGenValue arch.SSAGenBlock = ssaGenBlock + arch.LoadRegResults = loadRegResults } diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go index 8142ba7984..e7b4fae016 100644 --- a/src/cmd/compile/internal/amd64/ssa.go +++ b/src/cmd/compile/internal/amd64/ssa.go @@ -1348,3 +1348,19 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) { b.Fatalf("branch not implemented: %s", b.LongString()) } } + +func loadRegResults(s *ssagen.State, f *ssa.Func) { + for _, o := range f.OwnAux.ABIInfo().OutParams() { + n := o.Name.(*ir.Name) + rts, offs := o.RegisterTypesAndOffsets() + for i := range o.Registers { + p := s.Prog(loadByType(rts[i])) + p.From.Type = obj.TYPE_MEM + p.From.Name = obj.NAME_AUTO + p.From.Sym = n.Linksym() + p.From.Offset = n.FrameOffset() + offs[i] + p.To.Type = obj.TYPE_REG + p.To.Reg = ssa.ObjRegForAbiReg(o.Registers[i], f.Config) + } + } +} |