Skip to content

Commit

Permalink
Merge "Merge branch 'dev.ssa' into mergebranch"
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit Code Review committed Mar 1, 2016
2 parents 998aaf8 + 9d854fd commit a6fb2ae
Show file tree
Hide file tree
Showing 148 changed files with 69,628 additions and 207 deletions.
3 changes: 3 additions & 0 deletions src/cmd/asm/internal/asm/operand_test.go
Expand Up @@ -127,6 +127,9 @@ var amd64OperandTests = []operandTest{
{"(SI)(BX*1)", "(SI)(BX*1)"},
{"(SI)(DX*1)", "(SI)(DX*1)"},
{"(SP)", "(SP)"},
{"(SP)(AX*4)", "(SP)(AX*4)"},
{"32(SP)(BX*2)", "32(SP)(BX*2)"},
{"32323(SP)(R8*4)", "32323(SP)(R8*4)"},
{"+3(PC)", "3(PC)"},
{"-1(DI)(BX*1)", "-1(DI)(BX*1)"},
{"-3(PC)", "-3(PC)"},
Expand Down
14 changes: 14 additions & 0 deletions src/cmd/asm/internal/asm/testdata/amd64.s
Expand Up @@ -127,5 +127,19 @@ loop:
MOVNTDQ X1, (AX) // MOVNTO X1, (AX)
MOVOA (AX), X1 // MOVO (AX), X1

// Tests for SP indexed addresses.
MOVQ foo(SP)(AX*1), BX // 488b1c04
MOVQ foo+32(SP)(CX*2), DX // 488b544c20
MOVQ foo+32323(SP)(R8*4), R9 // 4e8b8c84437e0000
MOVL foo(SP)(SI*8), DI // 8b3cf4
MOVL foo+32(SP)(R10*1), R11 // 468b5c1420
MOVL foo+32323(SP)(R12*2), R13 // 468bac64437e0000
MOVW foo(SP)(AX*4), R8 // 66448b0484
MOVW foo+32(SP)(R9*8), CX // 66428b4ccc20
MOVW foo+32323(SP)(AX*1), DX // 668b9404437e0000
MOVB foo(SP)(AX*2), AL // 8a0444
MOVB foo+32(SP)(CX*4), AH // 8a648c20
MOVB foo+32323(SP)(CX*8), R9 // 448a8ccc437e0000

// LTYPE0 nonnon { outcode($1, &$2); }
RET // c3
3 changes: 2 additions & 1 deletion src/cmd/asm/internal/asm/testdata/amd64error.s
Expand Up @@ -3,5 +3,6 @@
// license that can be found in the LICENSE file.

TEXT errors(SB),$0
MOVL foo<>(SB)(AX), AX // ERROR "invalid instruction"
MOVL foo<>(SB)(AX), AX // ERROR "invalid instruction"
MOVL (AX)(SP*1), AX // ERROR "invalid instruction"
RET
1 change: 1 addition & 0 deletions src/cmd/cgo/out.go
Expand Up @@ -458,6 +458,7 @@ func (p *Package) writeDefsFunc(fgo2 io.Writer, n *Name) {
}

fmt.Fprint(fgo2, "\n")
fmt.Fprint(fgo2, "//go:cgo_unsafe_args\n")
conf.Fprint(fgo2, fset, d)
fmt.Fprint(fgo2, " {\n")

Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/amd64/prog.go
Expand Up @@ -117,6 +117,7 @@ var progtable = [x86.ALAST]obj.ProgInfo{
x86.AJPL: {Flags: gc.Cjmp | gc.UseCarry},
x86.AJPS: {Flags: gc.Cjmp | gc.UseCarry},
obj.AJMP: {Flags: gc.Jump | gc.Break | gc.KillCarry},
x86.ALEAW: {Flags: gc.LeftAddr | gc.RightWrite},
x86.ALEAL: {Flags: gc.LeftAddr | gc.RightWrite},
x86.ALEAQ: {Flags: gc.LeftAddr | gc.RightWrite},
x86.AMOVBLSX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
Expand Down Expand Up @@ -167,6 +168,7 @@ var progtable = [x86.ALAST]obj.ProgInfo{
x86.AORW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry},
x86.APOPQ: {Flags: gc.SizeQ | gc.RightWrite},
x86.APUSHQ: {Flags: gc.SizeQ | gc.LeftRead},
x86.APXOR: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
x86.ARCLB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
x86.ARCLL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
x86.ARCLQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
Expand Down
1 change: 1 addition & 0 deletions src/cmd/compile/internal/gc/closure.go
Expand Up @@ -588,6 +588,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node {
ptr.Ullman = 1
ptr.Used = true
ptr.Name.Curfn = xfunc
ptr.Xoffset = 0
xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr)
var body []*Node
if Isptr[rcvrtype.Etype] || Isinter(rcvrtype) {
Expand Down
1 change: 1 addition & 0 deletions src/cmd/compile/internal/gc/fmt.go
Expand Up @@ -403,6 +403,7 @@ var etnames = []string{
TFORW: "FORW",
TFIELD: "FIELD",
TSTRING: "STRING",
TUNSAFEPTR: "TUNSAFEPTR",
TANY: "ANY",
}

Expand Down
4 changes: 3 additions & 1 deletion src/cmd/compile/internal/gc/gen.go
Expand Up @@ -142,6 +142,8 @@ func newlab(n *Node) *Label {
return lab
}

// There is a copy of checkgoto in the new SSA backend.
// Please keep them in sync.
func checkgoto(from *Node, to *Node) {
if from.Sym == to.Sym {
return
Expand Down Expand Up @@ -840,7 +842,7 @@ func gen(n *Node) {
cgen_dcl(n.Left)

case OAS:
if gen_as_init(n) {
if gen_as_init(n, false) {
break
}
Cgen_as(n.Left, n.Right)
Expand Down
11 changes: 10 additions & 1 deletion src/cmd/compile/internal/gc/go.go
Expand Up @@ -131,7 +131,7 @@ type Type struct {
Note *string // literal string annotation

// TARRAY
Bound int64 // negative is dynamic array
Bound int64 // negative is slice

// TMAP
Bucket *Type // internal type representing a hash bucket
Expand Down Expand Up @@ -759,4 +759,13 @@ var Panicindex *Node

var panicslice *Node

var panicdivide *Node

var throwreturn *Node

var growslice *Node

var writebarrierptr *Node
var typedmemmove *Node

var panicdottype *Node
15 changes: 14 additions & 1 deletion src/cmd/compile/internal/gc/gsubr.go
Expand Up @@ -530,6 +530,16 @@ func newplist() *obj.Plist {
return pl
}

// nodarg does something that depends on the value of
// fp (this was previously completely undocumented).
//
// fp=1 corresponds to input args
// fp=0 corresponds to output args
// fp=-1 is a special case of output args for a
// specific call from walk that previously (and
// incorrectly) passed a 1; the behavior is exactly
// the same as it is for 1, except that PARAMOUT is
// generated instead of PARAM.
func nodarg(t *Type, fp int) *Node {
var n *Node

Expand All @@ -555,7 +565,7 @@ func nodarg(t *Type, fp int) *Node {
Fatalf("nodarg: not field %v", t)
}

if fp == 1 {
if fp == 1 || fp == -1 {
for _, n := range Curfn.Func.Dcl {
if (n.Class == PPARAM || n.Class == PPARAMOUT) && !isblanksym(t.Sym) && n.Sym == t.Sym {
return n
Expand Down Expand Up @@ -592,6 +602,9 @@ fp:
case 1: // input arg
n.Class = PPARAM

case -1: // output arg from paramstoheap
n.Class = PPARAMOUT

case 2: // offset output arg
Fatalf("shouldn't be used")
}
Expand Down
31 changes: 15 additions & 16 deletions src/cmd/compile/internal/gc/init.go
Expand Up @@ -33,10 +33,10 @@ func renameinit() *Sym {
// hand-craft the following initialization code
// var initdone· uint8 (1)
// func init() (2)
// if initdone· != 0 { (3)
// if initdone· == 2 (4)
// return
// throw(); (5)
// if initdone· > 1 { (3)
// return (3a)
// if initdone· == 1 { (4)
// throw(); (4a)
// }
// initdone· = 1; (6)
// // over all matching imported symbols
Expand Down Expand Up @@ -118,22 +118,21 @@ func fninit(n *NodeList) {

// (3)
a := Nod(OIF, nil, nil)

a.Left = Nod(ONE, gatevar, Nodintconst(0))
a.Left = Nod(OGT, gatevar, Nodintconst(1))
a.Likely = 1
r = append(r, a)
// (3a)
a.Nbody.Set([]*Node{Nod(ORETURN, nil, nil)})

// (4)
b := Nod(OIF, nil, nil)

b.Left = Nod(OEQ, gatevar, Nodintconst(2))
b.Nbody.Set([]*Node{Nod(ORETURN, nil, nil)})
a.Nbody.Set([]*Node{b})

// (5)
b = syslook("throwinit", 0)

b = Nod(OCALL, b, nil)
a.Nbody.Append(b)
b.Left = Nod(OEQ, gatevar, Nodintconst(1))
// this actually isn't likely, but code layout is better
// like this: no JMP needed after the call.
b.Likely = 1
r = append(r, b)
// (4a)
b.Nbody.Set([]*Node{Nod(OCALL, syslook("throwinit", 0), nil)})

// (6)
a = Nod(OAS, gatevar, Nodintconst(1))
Expand Down
23 changes: 22 additions & 1 deletion src/cmd/compile/internal/gc/lex.go
Expand Up @@ -7,6 +7,7 @@
package gc

import (
"cmd/compile/internal/ssa"
"cmd/internal/obj"
"flag"
"fmt"
Expand Down Expand Up @@ -286,6 +287,23 @@ func Main() {
}
}
}
// special case for ssa for now
if strings.HasPrefix(name, "ssa/") {
// expect form ssa/phase/flag
// e.g. -d=ssa/generic_cse/time
// _ in phase name also matches space
phase := name[4:]
flag := "debug" // default flag is debug
if i := strings.Index(phase, "/"); i >= 0 {
flag = phase[i+1:]
phase = phase[:i]
}
err := ssa.PhaseOption(phase, flag, val)
if err != "" {
log.Fatalf(err)
}
continue Split
}
log.Fatalf("unknown debug key -d %s\n", name)
}
}
Expand Down Expand Up @@ -844,7 +862,7 @@ func plan9quote(s string) string {
return s
}

type Pragma uint8
type Pragma uint16

const (
Nointerface Pragma = 1 << iota
Expand All @@ -855,6 +873,7 @@ const (
Systemstack // func must run on system stack
Nowritebarrier // emit compiler error instead of write barrier
Nowritebarrierrec // error on write barrier in this or recursive callees
CgoUnsafeArgs // treat a pointer to one arg as a pointer to them all
)

type lexer struct {
Expand Down Expand Up @@ -1677,6 +1696,8 @@ func (l *lexer) getlinepragma() rune {
Yyerror("//go:nowritebarrierrec only allowed in runtime")
}
l.pragma |= Nowritebarrierrec | Nowritebarrier // implies Nowritebarrier
case "go:cgo_unsafe_args":
l.pragma |= CgoUnsafeArgs
}
return c
}
Expand Down
4 changes: 4 additions & 0 deletions src/cmd/compile/internal/gc/opnames.go
Expand Up @@ -160,5 +160,9 @@ var opnames = []string{
OLROT: "LROT",
ORROTC: "RROTC",
ORETJMP: "RETJMP",
OPS: "OPS",
OPC: "OPC",
OSQRT: "OSQRT",
OGETG: "OGETG",
OEND: "END",
}
1 change: 1 addition & 0 deletions src/cmd/compile/internal/gc/order.go
Expand Up @@ -230,6 +230,7 @@ func cleantempnopop(mark ordermarker, order *Order, out *[]*Node) {
n := order.temp[i]
if n.Name.Keepalive {
n.Name.Keepalive = false
n.Addrtaken = true // ensure SSA keeps the n variable
kill = Nod(OVARLIVE, n, nil)
typecheck(&kill, Etop)
*out = append(*out, kill)
Expand Down
20 changes: 20 additions & 0 deletions src/cmd/compile/internal/gc/pgen.go
Expand Up @@ -5,6 +5,7 @@
package gc

import (
"cmd/compile/internal/ssa"
"cmd/internal/obj"
"crypto/md5"
"fmt"
Expand Down Expand Up @@ -341,7 +342,12 @@ func compile(fn *Node) {
Deferreturn = Sysfunc("deferreturn")
Panicindex = Sysfunc("panicindex")
panicslice = Sysfunc("panicslice")
panicdivide = Sysfunc("panicdivide")
throwreturn = Sysfunc("throwreturn")
growslice = Sysfunc("growslice")
writebarrierptr = Sysfunc("writebarrierptr")
typedmemmove = Sysfunc("typedmemmove")
panicdottype = Sysfunc("panicdottype")
}

lno := setlineno(fn)
Expand All @@ -358,6 +364,7 @@ func compile(fn *Node) {
var nam *Node
var gcargs *Sym
var gclocals *Sym
var ssafn *ssa.Func
if len(fn.Nbody.Slice()) == 0 {
if pure_go != 0 || strings.HasPrefix(fn.Func.Nname.Sym.Name, "init.") {
Yyerror("missing function body for %q", fn.Func.Nname.Sym.Name)
Expand Down Expand Up @@ -409,6 +416,11 @@ func compile(fn *Node) {
goto ret
}

// Build an SSA backend function.
if shouldssa(Curfn) {
ssafn = buildssa(Curfn)
}

continpc = nil
breakpc = nil

Expand Down Expand Up @@ -471,6 +483,14 @@ func compile(fn *Node) {
}
}

if ssafn != nil {
genssa(ssafn, ptxt, gcargs, gclocals)
if Curfn.Func.Endlineno != 0 {
lineno = Curfn.Func.Endlineno
}
ssafn.Free()
return
}
Genslice(Curfn.Func.Enter.Slice())
Genslice(Curfn.Nbody.Slice())
gclean()
Expand Down
18 changes: 13 additions & 5 deletions src/cmd/compile/internal/gc/plive.go
Expand Up @@ -19,6 +19,7 @@ import (
"cmd/internal/obj"
"fmt"
"sort"
"strings"
)

const (
Expand Down Expand Up @@ -410,7 +411,7 @@ func newcfg(firstp *obj.Prog) []*BasicBlock {

bb := newblock(firstp)
cfg = append(cfg, bb)
for p := firstp; p != nil; p = p.Link {
for p := firstp; p != nil && p.As != obj.AEND; p = p.Link {
Thearch.Proginfo(p)
if p.To.Type == obj.TYPE_BRANCH {
if p.To.Val == nil {
Expand Down Expand Up @@ -438,7 +439,7 @@ func newcfg(firstp *obj.Prog) []*BasicBlock {
// contained instructions until a label is reached. Add edges
// for branches and fall-through instructions.
for _, bb := range cfg {
for p := bb.last; p != nil; p = p.Link {
for p := bb.last; p != nil && p.As != obj.AEND; p = p.Link {
if p.Opt != nil && p != bb.last {
break
}
Expand All @@ -447,6 +448,8 @@ func newcfg(firstp *obj.Prog) []*BasicBlock {
// Stop before an unreachable RET, to avoid creating
// unreachable control flow nodes.
if p.Link != nil && p.Link.As == obj.ARET && p.Link.Mode == 1 {
// TODO: remove after SSA is done. SSA does not
// generate any unreachable RET instructions.
break
}

Expand Down Expand Up @@ -1364,7 +1367,7 @@ func livenessepilogue(lv *Liveness) {
}
n = lv.vars[j]
if n.Class != PPARAM {
yyerrorl(int(p.Lineno), "internal error: %v %v recorded as live on entry", Curfn.Func.Nname, Nconv(n, obj.FmtLong))
yyerrorl(int(p.Lineno), "internal error: %v %v recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, Nconv(n, obj.FmtLong), p.Pc)
}
}
}
Expand All @@ -1389,8 +1392,13 @@ func livenessepilogue(lv *Liveness) {
if msg != nil {
fmt_ = ""
fmt_ += fmt.Sprintf("%v: live at ", p.Line())
if p.As == obj.ACALL && p.To.Node != nil {
fmt_ += fmt.Sprintf("call to %s:", ((p.To.Node).(*Node)).Sym.Name)
if p.As == obj.ACALL && p.To.Sym != nil {
name := p.To.Sym.Name
i := strings.Index(name, ".")
if i >= 0 {
name = name[i+1:]
}
fmt_ += fmt.Sprintf("call to %s:", name)
} else if p.As == obj.ACALL {
fmt_ += "indirect call:"
} else {
Expand Down

0 comments on commit a6fb2ae

Please sign in to comment.