]> Cypherpunks.ru repositories - gostls13.git/commitdiff
Merge remote-tracking branch 'origin/dev.debug' into master
authorAustin Clements <austin@google.com>
Fri, 11 Aug 2017 16:15:47 +0000 (12:15 -0400)
committerAustin Clements <austin@google.com>
Fri, 11 Aug 2017 16:17:43 +0000 (12:17 -0400)
Change-Id: I85df2745af666b533f4f6f1d06f7c8e137590b5b

1  2 
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/opGen.go

index 2400af340710860be52f0276c1db076ad2d2f033,c769efe8cd3144f589d340b1a82cbad79e4c18b7..0d89b6819254aa9ca483ee9d5fed0964c4b56f54
@@@ -70,32 -70,28 +70,32 @@@ func initssaconfig() 
        ssaCaches = make([]ssa.Cache, nBackendWorkers)
  
        // Set up some runtime functions we'll need to call.
 -      Newproc = Sysfunc("newproc")
 -      Deferproc = Sysfunc("deferproc")
 -      Deferreturn = Sysfunc("deferreturn")
 -      Duffcopy = Sysfunc("duffcopy")
 -      Duffzero = Sysfunc("duffzero")
 -      panicindex = Sysfunc("panicindex")
 -      panicslice = Sysfunc("panicslice")
 -      panicdivide = Sysfunc("panicdivide")
 -      growslice = Sysfunc("growslice")
 -      panicdottypeE = Sysfunc("panicdottypeE")
 -      panicdottypeI = Sysfunc("panicdottypeI")
 -      panicnildottype = Sysfunc("panicnildottype")
 -      assertE2I = Sysfunc("assertE2I")
 -      assertE2I2 = Sysfunc("assertE2I2")
 -      assertI2I = Sysfunc("assertI2I")
 -      assertI2I2 = Sysfunc("assertI2I2")
 -      goschedguarded = Sysfunc("goschedguarded")
 -      writeBarrier = Sysfunc("writeBarrier")
 -      writebarrierptr = Sysfunc("writebarrierptr")
 -      typedmemmove = Sysfunc("typedmemmove")
 -      typedmemclr = Sysfunc("typedmemclr")
 -      Udiv = Sysfunc("udiv")
 +      Newproc = sysfunc("newproc")
 +      Deferproc = sysfunc("deferproc")
 +      Deferreturn = sysfunc("deferreturn")
 +      Duffcopy = sysfunc("duffcopy")
 +      Duffzero = sysfunc("duffzero")
 +      panicindex = sysfunc("panicindex")
 +      panicslice = sysfunc("panicslice")
 +      panicdivide = sysfunc("panicdivide")
 +      growslice = sysfunc("growslice")
 +      panicdottypeE = sysfunc("panicdottypeE")
 +      panicdottypeI = sysfunc("panicdottypeI")
 +      panicnildottype = sysfunc("panicnildottype")
 +      assertE2I = sysfunc("assertE2I")
 +      assertE2I2 = sysfunc("assertE2I2")
 +      assertI2I = sysfunc("assertI2I")
 +      assertI2I2 = sysfunc("assertI2I2")
 +      goschedguarded = sysfunc("goschedguarded")
 +      writeBarrier = sysfunc("writeBarrier")
 +      writebarrierptr = sysfunc("writebarrierptr")
 +      typedmemmove = sysfunc("typedmemmove")
 +      typedmemclr = sysfunc("typedmemclr")
 +      Udiv = sysfunc("udiv")
 +
 +      // GO386=387 runtime functions
 +      ControlWord64trunc = sysfunc("controlWord64trunc")
 +      ControlWord32 = sysfunc("controlWord32")
  }
  
  // buildssa builds an SSA function for fn.
@@@ -4386,14 -4382,15 +4386,15 @@@ func genssa(f *ssa.Func, pp *Progs) 
        // Remember where each block starts.
        s.bstart = make([]*obj.Prog, f.NumBlocks())
        s.pp = pp
-       var valueProgs map[*obj.Prog]*ssa.Value
-       var blockProgs map[*obj.Prog]*ssa.Block
+       var progToValue map[*obj.Prog]*ssa.Value
+       var progToBlock map[*obj.Prog]*ssa.Block
+       var valueToProg []*obj.Prog
        var logProgs = e.log
        if logProgs {
-               valueProgs = make(map[*obj.Prog]*ssa.Value, f.NumValues())
-               blockProgs = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
+               progToValue = make(map[*obj.Prog]*ssa.Value, f.NumValues())
+               progToBlock = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
                f.Logf("genssa %s\n", f.Name)
-               blockProgs[s.pp.next] = f.Blocks[0]
+               progToBlock[s.pp.next] = f.Blocks[0]
        }
  
        if thearch.Use387 {
  
        s.ScratchFpMem = e.scratchFpMem
  
+       logLocationLists := Debug_locationlist != 0
+       if Ctxt.Flag_locationlists {
+               e.curfn.Func.DebugInfo = ssa.BuildFuncDebug(f, logLocationLists)
+               valueToProg = make([]*obj.Prog, f.NumValues())
+       }
        // Emit basic blocks
        for i, b := range f.Blocks {
                s.bstart[b.ID] = s.pp.next
                                }
                        case ssa.OpPhi:
                                CheckLoweredPhi(v)
+                       case ssa.OpRegKill:
+                               // nothing to do
                        default:
                                // let the backend handle it
                                thearch.SSAGenValue(&s, v)
                        }
  
+                       if Ctxt.Flag_locationlists {
+                               valueToProg[v.ID] = x
+                       }
                        if logProgs {
                                for ; x != s.pp.next; x = x.Link {
-                                       valueProgs[x] = v
+                                       progToValue[x] = v
                                }
                        }
                }
                thearch.SSAGenBlock(&s, b, next)
                if logProgs {
                        for ; x != s.pp.next; x = x.Link {
-                               blockProgs[x] = b
+                               progToBlock[x] = b
+                       }
+               }
+       }
+       if Ctxt.Flag_locationlists {
+               for _, locList := range e.curfn.Func.DebugInfo.Variables {
+                       for _, loc := range locList.Locations {
+                               loc.StartProg = valueToProg[loc.Start.ID]
+                               if loc.End == nil {
+                                       Fatalf("empty loc %v compiling %v", loc, f.Name)
+                               }
+                               loc.EndProg = valueToProg[loc.End.ID]
+                               if !logLocationLists {
+                                       loc.Start = nil
+                                       loc.End = nil
+                               }
                        }
                }
        }
        if logProgs {
                for p := pp.Text; p != nil; p = p.Link {
                        var s string
-                       if v, ok := valueProgs[p]; ok {
+                       if v, ok := progToValue[p]; ok {
                                s = v.String()
-                       } else if b, ok := blockProgs[p]; ok {
+                       } else if b, ok := progToBlock[p]; ok {
                                s = b.String()
                        } else {
                                s = "   " // most value and branch strings are 2-3 characters long
                        buf.WriteString("<dl class=\"ssa-gen\">")
                        for p := pp.Text; p != nil; p = p.Link {
                                buf.WriteString("<dt class=\"ssa-prog-src\">")
-                               if v, ok := valueProgs[p]; ok {
+                               if v, ok := progToValue[p]; ok {
                                        buf.WriteString(v.HTML())
-                               } else if b, ok := blockProgs[p]; ok {
+                               } else if b, ok := progToBlock[p]; ok {
                                        buf.WriteString(b.HTML())
                                }
                                buf.WriteString("</dt>")
@@@ -4880,9 -4902,9 +4906,9 @@@ func (e *ssafn) SplitString(name ssa.Lo
        lenType := types.Types[TINT]
        if n.Class() == PAUTO && !n.Addrtaken() {
                // Split this string up into two separate variables.
-               p := e.namedAuto(n.Sym.Name+".ptr", ptrType, n.Pos)
-               l := e.namedAuto(n.Sym.Name+".len", lenType, n.Pos)
-               return ssa.LocalSlot{N: p, Type: ptrType, Off: 0}, ssa.LocalSlot{N: l, Type: lenType, Off: 0}
+               p := e.splitSlot(&name, ".ptr", 0, ptrType)
+               l := e.splitSlot(&name, ".len", ptrType.Size(), lenType)
+               return p, l
        }
        // Return the two parts of the larger variable.
        return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off}, ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(Widthptr)}
@@@ -4897,9 -4919,9 +4923,9 @@@ func (e *ssafn) SplitInterface(name ssa
                if n.Type.IsEmptyInterface() {
                        f = ".type"
                }
-               c := e.namedAuto(n.Sym.Name+f, t, n.Pos)
-               d := e.namedAuto(n.Sym.Name+".data", t, n.Pos)
-               return ssa.LocalSlot{N: c, Type: t, Off: 0}, ssa.LocalSlot{N: d, Type: t, Off: 0}
+               c := e.splitSlot(&name, f, 0, t)
+               d := e.splitSlot(&name, ".data", t.Size(), t)
+               return c, d
        }
        // Return the two parts of the larger variable.
        return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + int64(Widthptr)}
@@@ -4911,10 -4933,10 +4937,10 @@@ func (e *ssafn) SplitSlice(name ssa.Loc
        lenType := types.Types[TINT]
        if n.Class() == PAUTO && !n.Addrtaken() {
                // Split this slice up into three separate variables.
-               p := e.namedAuto(n.Sym.Name+".ptr", ptrType, n.Pos)
-               l := e.namedAuto(n.Sym.Name+".len", lenType, n.Pos)
-               c := e.namedAuto(n.Sym.Name+".cap", lenType, n.Pos)
-               return ssa.LocalSlot{N: p, Type: ptrType, Off: 0}, ssa.LocalSlot{N: l, Type: lenType, Off: 0}, ssa.LocalSlot{N: c, Type: lenType, Off: 0}
+               p := e.splitSlot(&name, ".ptr", 0, ptrType)
+               l := e.splitSlot(&name, ".len", ptrType.Size(), lenType)
+               c := e.splitSlot(&name, ".cap", ptrType.Size()+lenType.Size(), lenType)
+               return p, l, c
        }
        // Return the three parts of the larger variable.
        return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off},
@@@ -4933,9 -4955,9 +4959,9 @@@ func (e *ssafn) SplitComplex(name ssa.L
        }
        if n.Class() == PAUTO && !n.Addrtaken() {
                // Split this complex up into two separate variables.
-               c := e.namedAuto(n.Sym.Name+".real", t, n.Pos)
-               d := e.namedAuto(n.Sym.Name+".imag", t, n.Pos)
-               return ssa.LocalSlot{N: c, Type: t, Off: 0}, ssa.LocalSlot{N: d, Type: t, Off: 0}
+               r := e.splitSlot(&name, ".real", 0, t)
+               i := e.splitSlot(&name, ".imag", t.Size(), t)
+               return r, i
        }
        // Return the two parts of the larger variable.
        return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + s}
@@@ -4951,9 -4973,10 +4977,10 @@@ func (e *ssafn) SplitInt64(name ssa.Loc
        }
        if n.Class() == PAUTO && !n.Addrtaken() {
                // Split this int64 up into two separate variables.
-               h := e.namedAuto(n.Sym.Name+".hi", t, n.Pos)
-               l := e.namedAuto(n.Sym.Name+".lo", types.Types[TUINT32], n.Pos)
-               return ssa.LocalSlot{N: h, Type: t, Off: 0}, ssa.LocalSlot{N: l, Type: types.Types[TUINT32], Off: 0}
+               if thearch.LinkArch.ByteOrder == binary.BigEndian {
+                       return e.splitSlot(&name, ".hi", 0, t), e.splitSlot(&name, ".lo", t.Size(), types.Types[TUINT32])
+               }
+               return e.splitSlot(&name, ".hi", t.Size(), t), e.splitSlot(&name, ".lo", 0, types.Types[TUINT32])
        }
        // Return the two parts of the larger variable.
        if thearch.LinkArch.ByteOrder == binary.BigEndian {
@@@ -4966,12 -4989,15 +4993,15 @@@ func (e *ssafn) SplitStruct(name ssa.Lo
        n := name.N.(*Node)
        st := name.Type
        ft := st.FieldType(i)
+       var offset int64
+       for f := 0; f < i; f++ {
+               offset += st.FieldType(f).Size()
+       }
        if n.Class() == PAUTO && !n.Addrtaken() {
                // Note: the _ field may appear several times.  But
                // have no fear, identically-named but distinct Autos are
                // ok, albeit maybe confusing for a debugger.
-               x := e.namedAuto(n.Sym.Name+"."+st.FieldName(i), ft, n.Pos)
-               return ssa.LocalSlot{N: x, Type: ft, Off: 0}
+               return e.splitSlot(&name, "."+st.FieldName(i), offset, ft)
        }
        return ssa.LocalSlot{N: n, Type: ft, Off: name.Off + st.FieldOff(i)}
  }
@@@ -4984,8 -5010,7 +5014,7 @@@ func (e *ssafn) SplitArray(name ssa.Loc
        }
        et := at.ElemType()
        if n.Class() == PAUTO && !n.Addrtaken() {
-               x := e.namedAuto(n.Sym.Name+"[0]", et, n.Pos)
-               return ssa.LocalSlot{N: x, Type: et, Off: 0}
+               return e.splitSlot(&name, "[0]", 0, et)
        }
        return ssa.LocalSlot{N: n, Type: et, Off: name.Off}
  }
@@@ -4994,16 -5019,14 +5023,14 @@@ func (e *ssafn) DerefItab(it *obj.LSym
        return itabsym(it, offset)
  }
  
- // namedAuto returns a new AUTO variable with the given name and type.
- // These are exposed to the debugger.
- func (e *ssafn) namedAuto(name string, typ *types.Type, pos src.XPos) ssa.GCNode {
-       t := typ
-       s := &types.Sym{Name: name, Pkg: localpkg}
+ // splitSlot returns a slot representing the data of parent starting at offset.
+ func (e *ssafn) splitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t *types.Type) ssa.LocalSlot {
+       s := &types.Sym{Name: parent.N.(*Node).Sym.Name + suffix, Pkg: localpkg}
  
        n := new(Node)
        n.Name = new(Name)
        n.Op = ONAME
-       n.Pos = pos
+       n.Pos = parent.N.(*Node).Pos
        n.Orig = n
  
        s.Def = asTypesNode(n)
        n.Name.Curfn = e.curfn
        e.curfn.Func.Dcl = append(e.curfn.Func.Dcl, n)
        dowidth(t)
-       return n
+       return ssa.LocalSlot{N: n, Type: t, Off: 0, SplitOf: parent, SplitOffset: offset}
  }
  
  func (e *ssafn) CanSSA(t *types.Type) bool {
index 17a5e7020440cb0369dc1e8fedd5c375fcd018f3,87a2ea0656a15da6e748b20d34cc6cd5ccdfb4b6..a949ec3b1c71b5eae08446e656ced033e126a488
@@@ -427,8 -427,8 +427,8 @@@ const 
        OpAMD64MOVSSstoreidx4
        OpAMD64MOVSDstoreidx1
        OpAMD64MOVSDstoreidx8
 -      OpAMD64ADDSDmem
        OpAMD64ADDSSmem
 +      OpAMD64ADDSDmem
        OpAMD64SUBSSmem
        OpAMD64SUBSDmem
        OpAMD64MULSSmem
        OpVarKill
        OpVarLive
        OpKeepAlive
+       OpRegKill
        OpInt64Make
        OpInt64Hi
        OpInt64Lo
@@@ -4683,13 -4684,13 +4684,13 @@@ var opcodeTable = [...]opInfo
                },
        },
        {
 -              name:           "ADDSDmem",
 +              name:           "ADDSSmem",
                auxType:        auxSymOff,
                argLen:         3,
                resultInArg0:   true,
                faultOnNilArg1: true,
                symEffect:      SymRead,
 -              asm:            x86.AADDSD,
 +              asm:            x86.AADDSS,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
                },
        },
        {
 -              name:           "ADDSSmem",
 +              name:           "ADDSDmem",
                auxType:        auxSymOff,
                argLen:         3,
                resultInArg0:   true,
                faultOnNilArg1: true,
                symEffect:      SymRead,
 -              asm:            x86.AADDSS,
 +              asm:            x86.AADDSD,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 4294901760}, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
                argLen:  2,
                generic: true,
        },
+       {
+               name:    "RegKill",
+               argLen:  0,
+               generic: true,
+       },
        {
                name:    "Int64Make",
                argLen:  2,