Skip to content
3 changes: 3 additions & 0 deletions src/cmd/compile/internal/gc/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"cmd/compile/internal/liveness"
"cmd/compile/internal/objw"
"cmd/compile/internal/pgoir"
"cmd/compile/internal/ssa"
"cmd/compile/internal/ssagen"
"cmd/compile/internal/staticinit"
"cmd/compile/internal/types"
Expand Down Expand Up @@ -189,4 +190,6 @@ func compileFunctions(profile *pgoir.Profile) {

base.Ctxt.InParallel = false
types.CalcSizeDisabled = false

ssa.PostCompile()
}
19 changes: 16 additions & 3 deletions src/cmd/compile/internal/liveness/mergelocals.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,9 +516,22 @@ func (cs *cstate) populateIndirectUseTable(cands []*ir.Name) ([]*ir.Name, []cand
for idx, arg := range v.Args {
if nc, ok := pendingUses[arg.ID]; ok {
if !v.AddrSinkArg(idx) {
// If this op may propagate the argument address to its output,
// then give up. See issue 80127.
continue
// If this op may propagate its input address
// to somewhere else, we must track where that
// somewhere else might be. See issue 80127.
if v.Type.IsMemory() {
// Might be stored to memory. Give up.
continue
}
// Some sort of address arithmetic.
if _, ok := pendingUses[v.ID]; ok {
// v has used multiple addresses, which is something
// we can't keep track of. Give up.
continue
}
// Treat this op as producing the address of the same variable
// that its argument was the address of.
pendingUses[v.ID] = nameCount{n: nc.n, count: v.Uses}
}
// We found a use of some value that took the
// address of nc.n. Record this inst as a
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/ssa/_gen/ARMOps.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ func init() {
clobberFlags: true,
faultOnNilArg0: true,
addrSinkArg0: true,
addrSinkArg1: true,
},

// large or unaligned move
Expand All @@ -533,6 +534,7 @@ func init() {
faultOnNilArg1: true,
addrSinkArg0: true,
addrSinkArg1: true,
// TODO: could use addrSinkArg2 here.
},

// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ func init() {
clobberFlags: true,
faultOnNilArg0: true,
addrSinkArg0: true,
addrSinkArg1: true,
},

// large or unaligned move
Expand Down Expand Up @@ -367,6 +368,7 @@ func init() {
faultOnNilArg1: true,
addrSinkArg0: true,
addrSinkArg1: true,
// TODO: could use addrSinkArg2 here.
},

// atomic and/or.
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/ssa/_gen/MIPSOps.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ func init() {
},
faultOnNilArg0: true,
addrSinkArg0: true,
addrSinkArg1: true,
},

// large or unaligned move
Expand Down Expand Up @@ -379,6 +380,7 @@ func init() {
faultOnNilArg1: true,
addrSinkArg0: true,
addrSinkArg1: true,
// TODO: could use addrSinkArg2 here.
},

// pseudo-ops
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/ssa/_gen/S390XOps.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ func init() {
faultOnNilArg1: true,
addrSinkArg0: true,
addrSinkArg1: true,
// TODO: could use addrSinkArg2 here.
},

// large clear
Expand All @@ -784,6 +785,7 @@ func init() {
typ: "Mem",
faultOnNilArg0: true,
addrSinkArg0: true,
addrSinkArg1: true,
},
}

Expand Down
62 changes: 54 additions & 8 deletions src/cmd/compile/internal/ssa/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package ssa

import (
"cmd/compile/internal/base"
"cmd/internal/src"
"fmt"
"hash/crc32"
Expand All @@ -17,7 +18,9 @@ import (
"regexp"
"runtime"
"sort"
"strconv"
"strings"
"sync"
"time"
)

Expand Down Expand Up @@ -202,12 +205,14 @@ type pass struct {
fn func(*Func)
required bool
disabled bool
time bool // report time to run pass
mem bool // report mem stats to run pass
stats int // pass reports own "stats" (e.g., branches removed)
debug int // pass performs some debugging. =1 should be in error-testing-friendly Warnl format.
test int // pass-specific ad-hoc option, perhaps useful in development
dump map[string]bool // dump if function name matches
time bool // report time to run pass
mem bool // report mem stats to run pass
stats int // pass reports own "stats" (e.g., branches removed)
debug int // pass performs some debugging. =1 should be in error-testing-friendly Warnl format.
test int // pass-specific ad-hoc option, perhaps useful in development
dump map[string]bool // dump if function name matches
keywords map[string]int64 // ad hoc parameters, typically for experiments/tuning
usedKW map[string]bool // if a keyword is supplied to a phase, note that it was used.
}

func (p *pass) addDump(s string) {
Expand All @@ -224,6 +229,21 @@ func (p *pass) String() string {
return p.name
}

var kwMu sync.Mutex

func (p *pass) Val(kw string, ifUnset int64) int64 {
if p == nil || p.keywords == nil {
return ifUnset
}
if v, ok := p.keywords[kw]; ok {
kwMu.Lock()
p.usedKW[kw] = true
kwMu.Unlock()
return v
}
return ifUnset
}

// Run consistency checker between each phase
var (
checkEnabled = false
Expand Down Expand Up @@ -283,7 +303,7 @@ where:
` + phasenames + `

- <flag> is one of:
on, off, debug, mem, time, test, stats, dump, seed
on, off, debug, mem, time, test, stats, dump, seed, @<keyword>

- <value> defaults to 1

Expand Down Expand Up @@ -438,7 +458,19 @@ commas. For example:
case "dump":
p.addDump(valString)
default:
return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option", flag, phase)
if flag != "" && flag[0] == '@' {
if p.keywords == nil {
p.keywords = make(map[string]int64)
p.usedKW = make(map[string]bool)
}
val64, err := strconv.ParseInt(valString, 10, 64)
if err != nil {
return fmt.Sprintf("Failed to parse %s as integer value in -d=ssa/%s/%s=%s option", valString, phase, flag, valString)
}
p.keywords[flag[1:]] = int64(val64)
} else {
return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option", flag, phase)
}
}
if p.disabled && p.required {
return fmt.Sprintf("Cannot disable required SSA phase %s using -d=ssa/%s debug option", phase, phase)
Expand Down Expand Up @@ -612,6 +644,20 @@ var passOrder = [...]constraint{
{"prove", "known bits"},
}

func PostCompile() {
for _, c := range passes {
if c.keywords != nil {
for k := range c.keywords {
if !c.usedKW[k] {
// If someone specified a debugging keyword that was not
// consumed, they might want to know about this.
base.Warn("Keyword %s for pass %s was not used", k, c.name)
}
}
}
}
}

func init() {
for _, c := range passOrder {
a, b := c.a, c.b
Expand Down
4 changes: 4 additions & 0 deletions src/cmd/compile/internal/ssa/opGen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading