From 7bdecbf840978e618665c284d273f81ce639a293 Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Fri, 29 May 2015 13:47:38 -0400 Subject: [PATCH] [dev.ssa] cmd/compile/internal/ssa: remove cgen pass Code generation is now done in genssa. Also remove the asm field in opInfo. It's no longer used. Change-Id: I65fffac267e138fd424b2ef8aa7ed79f0ebb63d5 Reviewed-on: https://go-review.googlesource.com/10539 Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/TODO | 1 - src/cmd/compile/internal/ssa/cgen.go | 135 ------------------------ src/cmd/compile/internal/ssa/compile.go | 3 - src/cmd/compile/internal/ssa/op.go | 6 -- src/cmd/compile/internal/ssa/opamd64.go | 58 +++++----- 5 files changed, 29 insertions(+), 174 deletions(-) delete mode 100644 src/cmd/compile/internal/ssa/cgen.go diff --git a/src/cmd/compile/internal/ssa/TODO b/src/cmd/compile/internal/ssa/TODO index afb723ae4c..e3ffdd2692 100644 --- a/src/cmd/compile/internal/ssa/TODO +++ b/src/cmd/compile/internal/ssa/TODO @@ -25,7 +25,6 @@ Values Opcodes - Rename ops to prevent cross-arch conflicts. MOVQ -> MOVQamd64 (or MOVQ6?). Other option: build opcode table in Config instead of globally. - - Remove asm string from opinfo, no longer needed. - It's annoying to list the opcode both in the opcode list and an opInfo map entry. Specify it one place and use go:generate to produce both? diff --git a/src/cmd/compile/internal/ssa/cgen.go b/src/cmd/compile/internal/ssa/cgen.go deleted file mode 100644 index 51c72aacd9..0000000000 --- a/src/cmd/compile/internal/ssa/cgen.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ssa - -import ( - "bytes" - "fmt" - "os" -) - -// cgen selects machine instructions for the function. -// This pass generates assembly output for now, but should -// TODO(khr): generate binary output (via liblink?) instead of text. -func cgen(f *Func) { - fmt.Printf("TEXT %s(SB),0,$0\n", f.Name) // TODO: frame size / arg size - - // TODO: prolog, allocate stack frame - - for idx, b := range f.Blocks { - fmt.Printf("%d:\n", b.ID) - for _, v := range b.Values { - var buf bytes.Buffer - asm := opcodeTable[v.Op].asm - buf.WriteString(" ") - for i := 0; i < len(asm); i++ { - switch asm[i] { - default: - buf.WriteByte(asm[i]) - case '\t': - buf.WriteByte(' ') - for buf.Len()%8 != 0 { - buf.WriteByte(' ') - } - case '%': - i++ - switch asm[i] { - case '%': - buf.WriteByte('%') - case 'I': - i++ - n := asm[i] - '0' - if f.RegAlloc[v.Args[n].ID] != nil { - buf.WriteString(f.RegAlloc[v.Args[n].ID].Name()) - } else { - fmt.Fprintf(&buf, "v%d", v.Args[n].ID) - } - case 'O': - i++ - n := asm[i] - '0' - if n != 0 { - panic("can only handle 1 output for now") - } - if f.RegAlloc[v.ID] != nil { - buf.WriteString(f.RegAlloc[v.ID].Name()) - } else { - fmt.Fprintf(&buf, "v%d", v.ID) - } - case 'A': - fmt.Fprint(&buf, v.Aux) - } - } - } - for buf.Len() < 40 { - buf.WriteByte(' ') - } - buf.WriteString("; ") - buf.WriteString(v.LongString()) - buf.WriteByte('\n') - os.Stdout.Write(buf.Bytes()) - } - // find next block in layout sequence - var next *Block - if idx < len(f.Blocks)-1 { - next = f.Blocks[idx+1] - } - // emit end of block code - // TODO: this is machine specific - switch b.Kind { - case BlockPlain: - if b.Succs[0] != next { - fmt.Printf("\tJMP\t%d\n", b.Succs[0].ID) - } - case BlockExit: - // TODO: run defers (if any) - // TODO: deallocate frame - fmt.Println("\tRET") - case BlockCall: - // nothing to emit - call instruction already happened - case BlockEQ: - if b.Succs[0] == next { - fmt.Printf("\tJNE\t%d\n", b.Succs[1].ID) - } else if b.Succs[1] == next { - fmt.Printf("\tJEQ\t%d\n", b.Succs[0].ID) - } else { - fmt.Printf("\tJEQ\t%d\n", b.Succs[0].ID) - fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID) - } - case BlockNE: - if b.Succs[0] == next { - fmt.Printf("\tJEQ\t%d\n", b.Succs[1].ID) - } else if b.Succs[1] == next { - fmt.Printf("\tJNE\t%d\n", b.Succs[0].ID) - } else { - fmt.Printf("\tJNE\t%d\n", b.Succs[0].ID) - fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID) - } - case BlockLT: - if b.Succs[0] == next { - fmt.Printf("\tJGE\t%d\n", b.Succs[1].ID) - } else if b.Succs[1] == next { - fmt.Printf("\tJLT\t%d\n", b.Succs[0].ID) - } else { - fmt.Printf("\tJLT\t%d\n", b.Succs[0].ID) - fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID) - } - case BlockULT: - if b.Succs[0] == next { - fmt.Printf("\tJAE\t%d\n", b.Succs[1].ID) - } else if b.Succs[1] == next { - fmt.Printf("\tJB\t%d\n", b.Succs[0].ID) - } else { - fmt.Printf("\tJB\t%d\n", b.Succs[0].ID) - fmt.Printf("\tJMP\t%d\n", b.Succs[1].ID) - } - default: - fmt.Printf("\t%s ->", b.Kind.String()) - for _, s := range b.Succs { - fmt.Printf(" %d", s.ID) - } - fmt.Printf("\n") - } - } -} diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go index c1f7956791..b497beade9 100644 --- a/src/cmd/compile/internal/ssa/compile.go +++ b/src/cmd/compile/internal/ssa/compile.go @@ -65,7 +65,6 @@ var passes = [...]pass{ {"schedule", schedule}, // schedule values {"regalloc", regalloc}, {"stackalloc", stackalloc}, - {"cgen", cgen}, } // Double-check phase ordering constraints. @@ -85,8 +84,6 @@ var passOrder = [...]constraint{ {"schedule", "regalloc"}, // stack allocation requires register allocation {"regalloc", "stackalloc"}, - // code generation requires stack allocation - {"stackalloc", "cgen"}, } func init() { diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go index f02c1ae0c0..75c655758d 100644 --- a/src/cmd/compile/internal/ssa/op.go +++ b/src/cmd/compile/internal/ssa/op.go @@ -118,12 +118,6 @@ func (g GlobalOffset) String() string { type opInfo struct { flags int32 - // assembly template - // %In: location of input n - // %On: location of output n - // %A: print aux with fmt.Print - asm string - // returns a reg constraint for the instruction. [0] gives a reg constraint // for each input, [1] gives a reg constraint for each output. (Values have // exactly one output for now) diff --git a/src/cmd/compile/internal/ssa/opamd64.go b/src/cmd/compile/internal/ssa/opamd64.go index 46a0069a18..517090992a 100644 --- a/src/cmd/compile/internal/ssa/opamd64.go +++ b/src/cmd/compile/internal/ssa/opamd64.go @@ -123,39 +123,39 @@ var ( // Opcodes that appear in an output amd64 program var amd64Table = map[Op]opInfo{ - OpADDQ: {flags: OpFlagCommutative, asm: "ADDQ\t%I0,%I1,%O0", reg: gp21}, // TODO: overwrite - OpADDQconst: {asm: "ADDQ\t$%A,%I0,%O0", reg: gp11}, // aux = int64 constant to add - OpSUBQ: {asm: "SUBQ\t%I0,%I1,%O0", reg: gp21}, - OpSUBQconst: {asm: "SUBQ\t$%A,%I0,%O0", reg: gp11}, - OpMULQ: {asm: "MULQ\t%I0,%I1,%O0", reg: gp21}, - OpMULQconst: {asm: "IMULQ\t$%A,%I0,%O0", reg: gp11}, - OpSHLQ: {asm: "SHLQ\t%I0,%I1,%O0", reg: gp21}, - OpSHLQconst: {asm: "SHLQ\t$%A,%I0,%O0", reg: gp11}, + OpADDQ: {flags: OpFlagCommutative, reg: gp21}, // TODO: overwrite + OpADDQconst: {reg: gp11}, // aux = int64 constant to add + OpSUBQ: {reg: gp21}, + OpSUBQconst: {reg: gp11}, + OpMULQ: {reg: gp21}, + OpMULQconst: {reg: gp11}, + OpSHLQ: {reg: gp21}, + OpSHLQconst: {reg: gp11}, - OpCMPQ: {asm: "CMPQ\t%I0,%I1", reg: gp2_flags}, // compute arg[0]-arg[1] and produce flags - OpCMPQconst: {asm: "CMPQ\t$%A,%I0", reg: gp1_flags}, - OpTESTQ: {asm: "TESTQ\t%I0,%I1", reg: gp2_flags}, - OpTESTB: {asm: "TESTB\t%I0,%I1", reg: gp2_flags}, + OpCMPQ: {reg: gp2_flags}, // compute arg[0]-arg[1] and produce flags + OpCMPQconst: {reg: gp1_flags}, + OpTESTQ: {reg: gp2_flags}, + OpTESTB: {reg: gp2_flags}, - OpLEAQ: {flags: OpFlagCommutative, asm: "LEAQ\t%A(%I0)(%I1*1),%O0", reg: gp21}, // aux = int64 constant to add - OpLEAQ2: {asm: "LEAQ\t%A(%I0)(%I1*2),%O0"}, - OpLEAQ4: {asm: "LEAQ\t%A(%I0)(%I1*4),%O0"}, - OpLEAQ8: {asm: "LEAQ\t%A(%I0)(%I1*8),%O0"}, - OpLEAQglobal: {asm: "LEAQ\t%A(SB),%O0", reg: gp01}, + OpLEAQ: {flags: OpFlagCommutative, reg: gp21}, // aux = int64 constant to add + OpLEAQ2: {}, + OpLEAQ4: {}, + OpLEAQ8: {}, + OpLEAQglobal: {reg: gp01}, // loads and stores - OpMOVBload: {asm: "MOVB\t%A(%I0),%O0", reg: gpload}, - OpMOVQload: {asm: "MOVQ\t%A(%I0),%O0", reg: gpload}, - OpMOVQstore: {asm: "MOVQ\t%I1,%A(%I0)", reg: gpstore}, - OpMOVQloadidx8: {asm: "MOVQ\t%A(%I0)(%I1*8),%O0", reg: gploadidx}, - OpMOVQstoreidx8: {asm: "MOVQ\t%I2,%A(%I0)(%I1*8)", reg: gpstoreidx}, + OpMOVBload: {reg: gpload}, + OpMOVQload: {reg: gpload}, + OpMOVQstore: {reg: gpstore}, + OpMOVQloadidx8: {reg: gploadidx}, + OpMOVQstoreidx8: {reg: gpstoreidx}, - OpMOVQconst: {asm: "MOVQ\t$%A,%O0", reg: gp01}, + OpMOVQconst: {reg: gp01}, - OpStaticCall: {asm: "CALL\t%A(SB)"}, + OpStaticCall: {}, - OpCopy: {asm: "MOVQ\t%I0,%O0", reg: gp11}, // TODO: make arch-specific - OpConvNop: {asm: "MOVQ\t%I0,%O0", reg: gp11}, // TODO: make arch-specific. Or get rid of this altogether. + OpCopy: {reg: gp11}, // TODO: make arch-specific + OpConvNop: {reg: gp11}, // TODO: make arch-specific. Or get rid of this altogether. // convert from flags back to boolean OpSETL: {}, @@ -164,10 +164,10 @@ var amd64Table = map[Op]opInfo{ // unlike regular loads & stores, these take no memory argument. // They are just like OpCopy but we use them during register allocation. // TODO: different widths, float - OpLoadReg8: {asm: "MOVQ\t%I0,%O0"}, - OpStoreReg8: {asm: "MOVQ\t%I0,%O0"}, + OpLoadReg8: {}, + OpStoreReg8: {}, - OpREPMOVSB: {asm: "REP MOVSB", reg: [2][]regMask{{di, si, cx, 0}, {0}}}, // TODO: record that si/di/cx are clobbered + OpREPMOVSB: {reg: [2][]regMask{{di, si, cx, 0}, {0}}}, // TODO: record that si/di/cx are clobbered } func init() {