mirror of https://github.com/golang/go.git
[dev.ssa] cmd/compile: split op rewrites into separate functions
The single value rewrite function is too big. Some compilers fail on it (out of memory, branch offset too large). Break it up into a rewrite function per op. Change-Id: Iede697c8a1a3a22b485cd0dc85d3e233160c89c2 Reviewed-on: https://go-review.googlesource.com/16347 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Todd Neal <todd@tneal.org>
This commit is contained in:
parent
e514021153
commit
a347ab7cd1
|
|
@ -134,6 +134,13 @@ func genRules(arch arch) {
|
|||
log.Fatalf("unbalanced rule at line %d: %v\n", lineno, rule)
|
||||
}
|
||||
|
||||
// Order all the ops.
|
||||
var ops []string
|
||||
for op := range oprules {
|
||||
ops = append(ops, op)
|
||||
}
|
||||
sort.Strings(ops)
|
||||
|
||||
// Start output buffer, write header.
|
||||
w := new(bytes.Buffer)
|
||||
fmt.Fprintf(w, "// autogenerated from gen/%s.rules: do not edit!\n", arch.name)
|
||||
|
|
@ -145,18 +152,23 @@ func genRules(arch arch) {
|
|||
fmt.Fprintln(w, "import \"math\"")
|
||||
fmt.Fprintln(w, "var _ = math.MinInt8 // in case not otherwise used")
|
||||
|
||||
// Main rewrite routine is a switch on v.Op.
|
||||
fmt.Fprintf(w, "func rewriteValue%s(v *Value, config *Config) bool {\n", arch.name)
|
||||
fmt.Fprintln(w, "b := v.Block")
|
||||
|
||||
// generate code for each rule
|
||||
fmt.Fprintf(w, "switch v.Op {\n")
|
||||
var ops []string
|
||||
for op := range oprules {
|
||||
ops = append(ops, op)
|
||||
}
|
||||
sort.Strings(ops)
|
||||
for _, op := range ops {
|
||||
fmt.Fprintf(w, "case %s:\n", opName(op, arch))
|
||||
fmt.Fprintf(w, "return rewriteValue%s_%s(v, config)\n", arch.name, opName(op, arch))
|
||||
}
|
||||
fmt.Fprintf(w, "}\n")
|
||||
fmt.Fprintf(w, "return false\n")
|
||||
fmt.Fprintf(w, "}\n")
|
||||
|
||||
// Generate a routine per op. Note that we don't make one giant routine
|
||||
// because it is too big for some compilers.
|
||||
for _, op := range ops {
|
||||
fmt.Fprintf(w, "func rewriteValue%s_%s(v *Value, config *Config) bool {\n", arch.name, opName(op, arch))
|
||||
fmt.Fprintln(w, "b := v.Block")
|
||||
fmt.Fprintln(w, "_ = b")
|
||||
for _, rule := range oprules[op] {
|
||||
// Note: we use a hash to identify the rule so that its
|
||||
// identity is invariant to adding/removing rules elsewhere
|
||||
|
|
@ -188,12 +200,12 @@ func genRules(arch arch) {
|
|||
fmt.Fprintf(w, "goto end%s\n", rulehash) // use label
|
||||
fmt.Fprintf(w, "end%s:;\n", rulehash)
|
||||
}
|
||||
fmt.Fprintf(w, "return false\n")
|
||||
fmt.Fprintf(w, "}\n")
|
||||
}
|
||||
fmt.Fprintf(w, "}\n")
|
||||
fmt.Fprintf(w, "return false\n")
|
||||
fmt.Fprintf(w, "}\n")
|
||||
|
||||
// Generate block rewrite function.
|
||||
// Generate block rewrite function. There are only a few block types
|
||||
// so we can make this one function with a switch.
|
||||
fmt.Fprintf(w, "func rewriteBlock%s(b *Block) bool {\n", arch.name)
|
||||
fmt.Fprintf(w, "switch b.Kind {\n")
|
||||
ops = nil
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue