mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] cmd/internal/ssa: SSA backend compiler skeleton
First pass adding code for SSA backend. It is standalone for now. I've included just a few passes to make the review size manageable - I have more passes coming. cmd/internal/ssa is the library containing the ssa compiler proper. cmd/internal/ssa/ssac is a driver that loads an sexpr-based IR, converts it to SSA form, and calls the above library. It is essentially throwaway code - it will disappear once the Go compiler calls cmd/internal/ssa itself. The .goir files in ssac/ are dumps of fibonacci programs I made from a hacked-up compiler. They are just for testing. Change-Id: I5ee89356ec12c87cd916681097cd3c2cd591040c Reviewed-on: https://go-review.googlesource.com/6681 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
de7f6c77bc
commit
f52b234579
26 changed files with 2438 additions and 0 deletions
117
src/cmd/internal/ssa/value.go
Normal file
117
src/cmd/internal/ssa/value.go
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
// 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 (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Value represents a value in the SSA representation of the program.
|
||||
// The ID and Type fields must not be modified. The remainder may be modified
|
||||
// if they preserve the value of the Value (e.g. changing a (mul 2 x) to an (add x x)).
|
||||
type Value struct {
|
||||
// A unique identifier for the value. For performance we allocate these IDs
|
||||
// densely starting at 0. There is no guarantee that there won't be occasional holes, though.
|
||||
ID ID
|
||||
|
||||
// The operation that computes this value. See op.go.
|
||||
Op Op
|
||||
|
||||
// The type of this value. Normally this will be a Go type, but there
|
||||
// are a few other pseudo-types, see type.go.
|
||||
Type Type
|
||||
|
||||
// Auxiliary info for this value. The type of this information depends on the opcode (& type).
|
||||
Aux interface{}
|
||||
|
||||
// Arguments of this value
|
||||
Args []*Value
|
||||
|
||||
// Containing basic block
|
||||
Block *Block
|
||||
|
||||
// Storage for the first two args
|
||||
argstorage [2]*Value
|
||||
}
|
||||
|
||||
// Examples:
|
||||
// Opcode aux args
|
||||
// OpAdd nil 2
|
||||
// OpConstStr string 0
|
||||
// OpConstInt int64 0
|
||||
// OpAddcq int64 1 amd64 op: v = arg[0] + constant
|
||||
|
||||
// short form print. Just v#.
|
||||
func (v *Value) String() string {
|
||||
return fmt.Sprintf("v%d", v.ID)
|
||||
}
|
||||
|
||||
// long form print. v# = opcode <type> [aux] args [: reg]
|
||||
func (v *Value) LongString() string {
|
||||
s := fmt.Sprintf("v%d = %s", v.ID, strings.TrimPrefix(v.Op.String(), "Op"))
|
||||
s += " <" + v.Type.String() + ">"
|
||||
if v.Aux != nil {
|
||||
s += fmt.Sprintf(" [%v]", v.Aux)
|
||||
}
|
||||
for _, a := range v.Args {
|
||||
s += fmt.Sprintf(" %v", a)
|
||||
}
|
||||
r := v.Block.Func.RegAlloc
|
||||
if r != nil && r[v.ID] != nil {
|
||||
s += " : " + r[v.ID].Name()
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (v *Value) AddArg(w *Value) {
|
||||
v.Args = append(v.Args, w)
|
||||
}
|
||||
func (v *Value) AddArgs(a ...*Value) {
|
||||
v.Args = append(v.Args, a...)
|
||||
}
|
||||
func (v *Value) SetArg(i int, w *Value) {
|
||||
v.Args[i] = w
|
||||
}
|
||||
func (v *Value) RemoveArg(i int) {
|
||||
copy(v.Args[i:], v.Args[i+1:])
|
||||
v.Args = v.Args[:len(v.Args)-1]
|
||||
}
|
||||
func (v *Value) SetArgs1(a *Value) {
|
||||
v.resetArgs()
|
||||
v.AddArg(a)
|
||||
}
|
||||
func (v *Value) SetArgs2(a *Value, b *Value) {
|
||||
v.resetArgs()
|
||||
v.AddArg(a)
|
||||
v.AddArg(b)
|
||||
}
|
||||
|
||||
func (v *Value) resetArgs() {
|
||||
v.argstorage[0] = nil
|
||||
v.argstorage[1] = nil
|
||||
v.Args = v.argstorage[:0]
|
||||
}
|
||||
|
||||
// CopyFrom converts v to be the same value as w. v and w must
|
||||
// have the same type.
|
||||
func (v *Value) CopyFrom(w *Value) {
|
||||
if !typeIdentical(v.Type, w.Type) {
|
||||
panic("copyFrom with unequal types")
|
||||
}
|
||||
v.Op = w.Op
|
||||
v.Aux = w.Aux
|
||||
v.resetArgs()
|
||||
v.AddArgs(w.Args...)
|
||||
}
|
||||
|
||||
// SetType sets the type of v. v must not have had its type
|
||||
// set yet (it must be TypeInvalid).
|
||||
func (v *Value) SetType() {
|
||||
if v.Type != TypeInvalid {
|
||||
panic("setting type when it is already set")
|
||||
}
|
||||
opcodeTable[v.Op].typer(v)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue