]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: simplify openDeferSave
authorCherry Mui <cherryyz@google.com>
Tue, 8 Jun 2021 20:55:36 +0000 (16:55 -0400)
committerCherry Mui <cherryyz@google.com>
Wed, 9 Jun 2021 01:30:09 +0000 (01:30 +0000)
Now it is only used to save the deferred the function (closure),
which must be a function type. Simplify the code.

Change-Id: Id4b8f2760fbf39a95883df2327f97378e7edab88
Reviewed-on: https://go-review.googlesource.com/c/go/+/326060
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/compile/internal/ssagen/ssa.go

index 613a5b62119e62b4c08fe44ed6618bc648b6875d..68a06ab4f5f80d3678f2bf83a089e50954e646f0 100644 (file)
@@ -4672,7 +4672,7 @@ func (s *state) openDeferRecord(n *ir.CallExpr) {
        // runtime panic code to use. But in the defer exit code, we will
        // call the function directly if it is a static function.
        closureVal := s.expr(fn)
-       closure := s.openDeferSave(nil, fn.Type(), closureVal)
+       closure := s.openDeferSave(fn.Type(), closureVal)
        opendefer.closureNode = closure.Aux.(*ir.Name)
        if !(fn.Op() == ir.ONAME && fn.(*ir.Name).Class == ir.PFUNC) {
                opendefer.closure = closure
@@ -4690,57 +4690,47 @@ func (s *state) openDeferRecord(n *ir.CallExpr) {
 
 // openDeferSave generates SSA nodes to store a value (with type t) for an
 // open-coded defer at an explicit autotmp location on the stack, so it can be
-// reloaded and used for the appropriate call on exit. If type t is SSAable, then
-// val must be non-nil (and n should be nil) and val is the value to be stored. If
-// type t is non-SSAable, then n must be non-nil (and val should be nil) and n is
-// evaluated (via s.addr() below) to get the value that is to be stored. The
-// function returns an SSA value representing a pointer to the autotmp location.
-func (s *state) openDeferSave(n ir.Node, t *types.Type, val *ssa.Value) *ssa.Value {
-       canSSA := TypeOK(t)
-       var pos src.XPos
-       if canSSA {
-               pos = val.Pos
-       } else {
-               pos = n.Pos()
+// reloaded and used for the appropriate call on exit. Type t must be a function type
+// (therefore SSAable). val is the value to be stored. The function returns an SSA
+// value representing a pointer to the autotmp location.
+func (s *state) openDeferSave(t *types.Type, val *ssa.Value) *ssa.Value {
+       if !TypeOK(t) {
+               s.Fatalf("openDeferSave of non-SSA-able type %v val=%v", t, val)
+       }
+       if !t.HasPointers() {
+               s.Fatalf("openDeferSave of pointerless type %v val=%v", t, val)
        }
-       argTemp := typecheck.TempAt(pos.WithNotStmt(), s.curfn, t)
-       argTemp.SetOpenDeferSlot(true)
-       var addrArgTemp *ssa.Value
-       // Use OpVarLive to make sure stack slots for the args, etc. are not
-       // removed by dead-store elimination
+       pos := val.Pos
+       temp := typecheck.TempAt(pos.WithNotStmt(), s.curfn, t)
+       temp.SetOpenDeferSlot(true)
+       var addrTemp *ssa.Value
+       // Use OpVarLive to make sure stack slot for the closure is not removed by
+       // dead-store elimination
        if s.curBlock.ID != s.f.Entry.ID {
-               // Force the argtmp storing this defer function/receiver/arg to be
-               // declared in the entry block, so that it will be live for the
-               // defer exit code (which will actually access it only if the
-               // associated defer call has been activated).
-               s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarDef, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][memVar])
-               s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarLive, types.TypeMem, argTemp, s.defvars[s.f.Entry.ID][memVar])
-               addrArgTemp = s.f.Entry.NewValue2A(src.NoXPos, ssa.OpLocalAddr, types.NewPtr(argTemp.Type()), argTemp, s.sp, s.defvars[s.f.Entry.ID][memVar])
+               // Force the tmp storing this defer function to be declared in the entry
+               // block, so that it will be live for the defer exit code (which will
+               // actually access it only if the associated defer call has been activated).
+               s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarDef, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
+               s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarLive, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
+               addrTemp = s.f.Entry.NewValue2A(src.NoXPos, ssa.OpLocalAddr, types.NewPtr(temp.Type()), temp, s.sp, s.defvars[s.f.Entry.ID][memVar])
        } else {
                // Special case if we're still in the entry block. We can't use
                // the above code, since s.defvars[s.f.Entry.ID] isn't defined
                // until we end the entry block with s.endBlock().
-               s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, argTemp, s.mem(), false)
-               s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, argTemp, s.mem(), false)
-               addrArgTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(argTemp.Type()), argTemp, s.sp, s.mem(), false)
-       }
-       if t.HasPointers() {
-               // Since we may use this argTemp during exit depending on the
-               // deferBits, we must define it unconditionally on entry.
-               // Therefore, we must make sure it is zeroed out in the entry
-               // block if it contains pointers, else GC may wrongly follow an
-               // uninitialized pointer value.
-               argTemp.SetNeedzero(true)
-       }
-       if !canSSA {
-               a := s.addr(n)
-               s.move(t, addrArgTemp, a)
-               return addrArgTemp
-       }
+               s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, temp, s.mem(), false)
+               s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, temp, s.mem(), false)
+               addrTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(temp.Type()), temp, s.sp, s.mem(), false)
+       }
+       // Since we may use this temp during exit depending on the
+       // deferBits, we must define it unconditionally on entry.
+       // Therefore, we must make sure it is zeroed out in the entry
+       // block if it contains pointers, else GC may wrongly follow an
+       // uninitialized pointer value.
+       temp.SetNeedzero(true)
        // We are storing to the stack, hence we can avoid the full checks in
        // storeType() (no write barrier) and do a simple store().
-       s.store(t, addrArgTemp, val)
-       return addrArgTemp
+       s.store(t, addrTemp, val)
+       return addrTemp
 }
 
 // openDeferExit generates SSA for processing all the open coded defers at exit.