Commit 6b3d4a53 authored by Todd Neal's avatar Todd Neal

cmd/compile: modify regalloc/stackalloc to use the cmd line debug args

Change the existing flags from compile time consts to be configurable
from the command line.

Change-Id: I4aab4bf3dfcbdd8e2b5a2ff51af95c2543967769
Reviewed-on: https://go-review.googlesource.com/20560Reviewed-by: default avatarKeith Randall <khr@golang.org>
Run-TryBot: Todd Neal <todd@tneal.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 31d13f47
...@@ -45,3 +45,4 @@ Future/other ...@@ -45,3 +45,4 @@ Future/other
- Should we get rid of named types in favor of underlying types during SSA generation? - Should we get rid of named types in favor of underlying types during SSA generation?
- Should we introduce a new type equality routine that is less strict than the frontend's? - Should we introduce a new type equality routine that is less strict than the frontend's?
- Infrastructure for enabling/disabling/configuring passes - Infrastructure for enabling/disabling/configuring passes
- Modify logging for at least pass=1, to be Warnl compatible
...@@ -99,8 +99,11 @@ import ( ...@@ -99,8 +99,11 @@ import (
"unsafe" "unsafe"
) )
const regDebug = false // TODO: compiler flag const (
const logSpills = false logSpills = iota
regDebug
stackDebug
)
// distance is a measure of how far into the future values are used. // distance is a measure of how far into the future values are used.
// distance is measured in units of instructions. // distance is measured in units of instructions.
...@@ -292,7 +295,7 @@ func (s *regAllocState) freeReg(r register) { ...@@ -292,7 +295,7 @@ func (s *regAllocState) freeReg(r register) {
} }
// Mark r as unused. // Mark r as unused.
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf("freeReg %s (dump %s/%s)\n", registers[r].Name(), v, s.regs[r].c) fmt.Printf("freeReg %s (dump %s/%s)\n", registers[r].Name(), v, s.regs[r].c)
} }
s.regs[r] = regState{} s.regs[r] = regState{}
...@@ -322,7 +325,7 @@ func (s *regAllocState) setOrig(c *Value, v *Value) { ...@@ -322,7 +325,7 @@ func (s *regAllocState) setOrig(c *Value, v *Value) {
// assignReg assigns register r to hold c, a copy of v. // assignReg assigns register r to hold c, a copy of v.
// r must be unused. // r must be unused.
func (s *regAllocState) assignReg(r register, v *Value, c *Value) { func (s *regAllocState) assignReg(r register, v *Value, c *Value) {
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf("assignReg %s %s/%s\n", registers[r].Name(), v, c) fmt.Printf("assignReg %s %s/%s\n", registers[r].Name(), v, c)
} }
if s.regs[r].v != nil { if s.regs[r].v != nil {
...@@ -446,7 +449,7 @@ func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool, line ...@@ -446,7 +449,7 @@ func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool, line
switch { switch {
// Load v from its spill location. // Load v from its spill location.
case vi.spill != nil: case vi.spill != nil:
if logSpills { if s.f.pass.debug > logSpills {
fmt.Println("regalloc: load spill") fmt.Println("regalloc: load spill")
} }
c = s.curBlock.NewValue1(line, OpLoadReg, v.Type, vi.spill) c = s.curBlock.NewValue1(line, OpLoadReg, v.Type, vi.spill)
...@@ -613,7 +616,7 @@ func (s *regAllocState) regalloc(f *Func) { ...@@ -613,7 +616,7 @@ func (s *regAllocState) regalloc(f *Func) {
liveSet.add(a.ID) liveSet.add(a.ID)
} }
} }
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf("uses for %s:%s\n", s.f.Name, b) fmt.Printf("uses for %s:%s\n", s.f.Name, b)
for i := range s.values { for i := range s.values {
vi := &s.values[i] vi := &s.values[i]
...@@ -679,7 +682,7 @@ func (s *regAllocState) regalloc(f *Func) { ...@@ -679,7 +682,7 @@ func (s *regAllocState) regalloc(f *Func) {
p := b.Preds[idx] p := b.Preds[idx]
s.setState(s.endRegs[p.ID]) s.setState(s.endRegs[p.ID])
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf("starting merge block %s with end state of %s:\n", b, p) fmt.Printf("starting merge block %s with end state of %s:\n", b, p)
for _, x := range s.endRegs[p.ID] { for _, x := range s.endRegs[p.ID] {
fmt.Printf(" %s: orig:%s cache:%s\n", registers[x.r].Name(), x.v, x.c) fmt.Printf(" %s: orig:%s cache:%s\n", registers[x.r].Name(), x.v, x.c)
...@@ -778,7 +781,7 @@ func (s *regAllocState) regalloc(f *Func) { ...@@ -778,7 +781,7 @@ func (s *regAllocState) regalloc(f *Func) {
} }
s.startRegs[b.ID] = regList s.startRegs[b.ID] = regList
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf("after phis\n") fmt.Printf("after phis\n")
for _, x := range s.startRegs[b.ID] { for _, x := range s.startRegs[b.ID] {
fmt.Printf(" %s: v%d\n", registers[x.r].Name(), x.vid) fmt.Printf(" %s: v%d\n", registers[x.r].Name(), x.vid)
...@@ -854,7 +857,7 @@ func (s *regAllocState) regalloc(f *Func) { ...@@ -854,7 +857,7 @@ func (s *regAllocState) regalloc(f *Func) {
// Process all the non-phi values. // Process all the non-phi values.
for _, v := range oldSched { for _, v := range oldSched {
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf(" processing %s\n", v.LongString()) fmt.Printf(" processing %s\n", v.LongString())
} }
if v.Op == OpPhi { if v.Op == OpPhi {
...@@ -958,7 +961,7 @@ func (s *regAllocState) regalloc(f *Func) { ...@@ -958,7 +961,7 @@ func (s *regAllocState) regalloc(f *Func) {
// Load control value into reg. // Load control value into reg.
if v := b.Control; v != nil && s.values[v.ID].needReg { if v := b.Control; v != nil && s.values[v.ID].needReg {
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf(" processing control %s\n", v.LongString()) fmt.Printf(" processing control %s\n", v.LongString())
} }
// TODO: regspec for block control values, instead of using // TODO: regspec for block control values, instead of using
...@@ -1098,7 +1101,7 @@ func (s *regAllocState) regalloc(f *Func) { ...@@ -1098,7 +1101,7 @@ func (s *regAllocState) regalloc(f *Func) {
for i := range s.values { for i := range s.values {
vi := s.values[i] vi := s.values[i]
if vi.spillUsed { if vi.spillUsed {
if logSpills { if s.f.pass.debug > logSpills {
fmt.Println("regalloc: spilled value") fmt.Println("regalloc: spilled value")
} }
continue continue
...@@ -1138,7 +1141,7 @@ func (s *regAllocState) shuffle(stacklive [][]ID) { ...@@ -1138,7 +1141,7 @@ func (s *regAllocState) shuffle(stacklive [][]ID) {
e.s = s e.s = s
e.cache = map[ID][]*Value{} e.cache = map[ID][]*Value{}
e.contents = map[Location]contentRecord{} e.contents = map[Location]contentRecord{}
if regDebug { if s.f.pass.debug > regDebug {
fmt.Printf("shuffle %s\n", s.f.Name) fmt.Printf("shuffle %s\n", s.f.Name)
fmt.Println(s.f.String()) fmt.Println(s.f.String())
} }
...@@ -1190,7 +1193,7 @@ type dstRecord struct { ...@@ -1190,7 +1193,7 @@ type dstRecord struct {
// setup initializes the edge state for shuffling. // setup initializes the edge state for shuffling.
func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive []ID) { func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive []ID) {
if regDebug { if e.s.f.pass.debug > regDebug {
fmt.Printf("edge %s->%s\n", e.p, e.b) fmt.Printf("edge %s->%s\n", e.p, e.b)
} }
...@@ -1235,7 +1238,7 @@ func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive ...@@ -1235,7 +1238,7 @@ func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive
} }
e.destinations = dsts e.destinations = dsts
if regDebug { if e.s.f.pass.debug > regDebug {
for _, vid := range e.cachedVals { for _, vid := range e.cachedVals {
a := e.cache[vid] a := e.cache[vid]
for _, c := range a { for _, c := range a {
...@@ -1298,7 +1301,7 @@ func (e *edgeState) process() { ...@@ -1298,7 +1301,7 @@ func (e *edgeState) process() {
vid := e.contents[loc].vid vid := e.contents[loc].vid
c := e.contents[loc].c c := e.contents[loc].c
r := e.findRegFor(c.Type) r := e.findRegFor(c.Type)
if regDebug { if e.s.f.pass.debug > regDebug {
fmt.Printf("breaking cycle with v%d in %s:%s\n", vid, loc.Name(), c) fmt.Printf("breaking cycle with v%d in %s:%s\n", vid, loc.Name(), c)
} }
if _, isReg := loc.(*Register); isReg { if _, isReg := loc.(*Register); isReg {
...@@ -1337,13 +1340,13 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value) bool { ...@@ -1337,13 +1340,13 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value) bool {
v := e.s.orig[vid] v := e.s.orig[vid]
var c *Value var c *Value
var src Location var src Location
if regDebug { if e.s.f.pass.debug > regDebug {
fmt.Printf("moving v%d to %s\n", vid, loc.Name()) fmt.Printf("moving v%d to %s\n", vid, loc.Name())
fmt.Printf("sources of v%d:", vid) fmt.Printf("sources of v%d:", vid)
} }
for _, w := range e.cache[vid] { for _, w := range e.cache[vid] {
h := e.s.f.getHome(w.ID) h := e.s.f.getHome(w.ID)
if regDebug { if e.s.f.pass.debug > regDebug {
fmt.Printf(" %s:%s", h.Name(), w) fmt.Printf(" %s:%s", h.Name(), w)
} }
_, isreg := h.(*Register) _, isreg := h.(*Register)
...@@ -1352,7 +1355,7 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value) bool { ...@@ -1352,7 +1355,7 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value) bool {
src = h src = h
} }
} }
if regDebug { if e.s.f.pass.debug > regDebug {
if src != nil { if src != nil {
fmt.Printf(" [use %s]\n", src.Name()) fmt.Printf(" [use %s]\n", src.Name())
} else { } else {
...@@ -1445,7 +1448,7 @@ func (e *edgeState) set(loc Location, vid ID, c *Value, final bool) { ...@@ -1445,7 +1448,7 @@ func (e *edgeState) set(loc Location, vid ID, c *Value, final bool) {
} }
} }
} }
if regDebug { if e.s.f.pass.debug > regDebug {
fmt.Printf("%s\n", c.LongString()) fmt.Printf("%s\n", c.LongString())
fmt.Printf("v%d now available in %s:%s\n", vid, loc.Name(), c) fmt.Printf("v%d now available in %s:%s\n", vid, loc.Name(), c)
} }
...@@ -1470,7 +1473,7 @@ func (e *edgeState) erase(loc Location) { ...@@ -1470,7 +1473,7 @@ func (e *edgeState) erase(loc Location) {
a := e.cache[vid] a := e.cache[vid]
for i, c := range a { for i, c := range a {
if e.s.f.getHome(c.ID) == loc { if e.s.f.getHome(c.ID) == loc {
if regDebug { if e.s.f.pass.debug > regDebug {
fmt.Printf("v%d no longer available in %s:%s\n", vid, loc.Name(), c) fmt.Printf("v%d no longer available in %s:%s\n", vid, loc.Name(), c)
} }
a[i], a = a[len(a)-1], a[:len(a)-1] a[i], a = a[len(a)-1], a[:len(a)-1]
...@@ -1534,7 +1537,7 @@ func (e *edgeState) findRegFor(typ Type) Location { ...@@ -1534,7 +1537,7 @@ func (e *edgeState) findRegFor(typ Type) Location {
if r, ok := e.s.f.getHome(c.ID).(*Register); ok && m>>uint(r.Num)&1 != 0 { if r, ok := e.s.f.getHome(c.ID).(*Register); ok && m>>uint(r.Num)&1 != 0 {
x := e.p.NewValue1(c.Line, OpStoreReg, c.Type, c) x := e.p.NewValue1(c.Line, OpStoreReg, c.Type, c)
e.set(t, vid, x, false) e.set(t, vid, x, false)
if regDebug { if e.s.f.pass.debug > regDebug {
fmt.Printf(" SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString()) fmt.Printf(" SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString())
} }
// r will now be overwritten by the caller. At some point // r will now be overwritten by the caller. At some point
...@@ -1703,7 +1706,7 @@ func (s *regAllocState) computeLive() { ...@@ -1703,7 +1706,7 @@ func (s *regAllocState) computeLive() {
break break
} }
} }
if regDebug { if f.pass.debug > regDebug {
fmt.Println("live values at end of each block") fmt.Println("live values at end of each block")
for _, b := range f.Blocks { for _, b := range f.Blocks {
fmt.Printf(" %s:", b) fmt.Printf(" %s:", b)
......
...@@ -8,8 +8,6 @@ package ssa ...@@ -8,8 +8,6 @@ package ssa
import "fmt" import "fmt"
const stackDebug = false // TODO: compiler flag
type stackAllocState struct { type stackAllocState struct {
f *Func f *Func
values []stackValState values []stackValState
...@@ -27,7 +25,7 @@ type stackValState struct { ...@@ -27,7 +25,7 @@ type stackValState struct {
// all Values that did not get a register. // all Values that did not get a register.
// Returns a map from block ID to the stack values live at the end of that block. // Returns a map from block ID to the stack values live at the end of that block.
func stackalloc(f *Func, spillLive [][]ID) [][]ID { func stackalloc(f *Func, spillLive [][]ID) [][]ID {
if stackDebug { if f.pass.debug > stackDebug {
fmt.Println("before stackalloc") fmt.Println("before stackalloc")
fmt.Println(f.String()) fmt.Println(f.String())
} }
...@@ -46,7 +44,7 @@ func (s *stackAllocState) init(f *Func, spillLive [][]ID) { ...@@ -46,7 +44,7 @@ func (s *stackAllocState) init(f *Func, spillLive [][]ID) {
for _, v := range b.Values { for _, v := range b.Values {
s.values[v.ID].typ = v.Type s.values[v.ID].typ = v.Type
s.values[v.ID].needSlot = !v.Type.IsMemory() && !v.Type.IsVoid() && !v.Type.IsFlags() && f.getHome(v.ID) == nil && !v.rematerializeable() s.values[v.ID].needSlot = !v.Type.IsMemory() && !v.Type.IsVoid() && !v.Type.IsFlags() && f.getHome(v.ID) == nil && !v.rematerializeable()
if stackDebug && s.values[v.ID].needSlot { if f.pass.debug > stackDebug && s.values[v.ID].needSlot {
fmt.Printf("%s needs a stack slot\n", v) fmt.Printf("%s needs a stack slot\n", v)
} }
if v.Op == OpStoreReg { if v.Op == OpStoreReg {
...@@ -83,7 +81,7 @@ func (s *stackAllocState) stackalloc() { ...@@ -83,7 +81,7 @@ func (s *stackAllocState) stackalloc() {
continue continue
} }
loc := LocalSlot{v.Aux.(GCNode), v.Type, v.AuxInt} loc := LocalSlot{v.Aux.(GCNode), v.Type, v.AuxInt}
if stackDebug { if f.pass.debug > stackDebug {
fmt.Printf("stackalloc %s to %s\n", v, loc.Name()) fmt.Printf("stackalloc %s to %s\n", v, loc.Name())
} }
f.setHome(v, loc) f.setHome(v, loc)
...@@ -131,7 +129,7 @@ func (s *stackAllocState) stackalloc() { ...@@ -131,7 +129,7 @@ func (s *stackAllocState) stackalloc() {
goto noname goto noname
} }
} }
if stackDebug { if f.pass.debug > stackDebug {
fmt.Printf("stackalloc %s to %s\n", v, name.Name()) fmt.Printf("stackalloc %s to %s\n", v, name.Name())
} }
f.setHome(v, name) f.setHome(v, name)
...@@ -165,7 +163,7 @@ func (s *stackAllocState) stackalloc() { ...@@ -165,7 +163,7 @@ func (s *stackAllocState) stackalloc() {
} }
// Use the stack variable at that index for v. // Use the stack variable at that index for v.
loc := locs[i] loc := locs[i]
if stackDebug { if f.pass.debug > stackDebug {
fmt.Printf("stackalloc %s to %s\n", v, loc.Name()) fmt.Printf("stackalloc %s to %s\n", v, loc.Name())
} }
f.setHome(v, loc) f.setHome(v, loc)
...@@ -249,7 +247,7 @@ func (s *stackAllocState) computeLive(spillLive [][]ID) { ...@@ -249,7 +247,7 @@ func (s *stackAllocState) computeLive(spillLive [][]ID) {
break break
} }
} }
if stackDebug { if s.f.pass.debug > stackDebug {
for _, b := range s.f.Blocks { for _, b := range s.f.Blocks {
fmt.Printf("stacklive %s %v\n", b, s.live[b.ID]) fmt.Printf("stacklive %s %v\n", b, s.live[b.ID])
} }
...@@ -307,7 +305,7 @@ func (s *stackAllocState) buildInterferenceGraph() { ...@@ -307,7 +305,7 @@ func (s *stackAllocState) buildInterferenceGraph() {
} }
} }
} }
if stackDebug { if f.pass.debug > stackDebug {
for vid, i := range s.interfere { for vid, i := range s.interfere {
if len(i) > 0 { if len(i) > 0 {
fmt.Printf("v%d interferes with", vid) fmt.Printf("v%d interferes with", vid)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment