mirror of
https://github.com/golang/go
synced 2024-11-26 22:01:27 -07:00
cmd/compile: add ellipsis syntax for op-only rewrite rules
This change introduces a new syntax for rewrite rules that only change a Value's Op. See #36380 for more discussion. Updating rewrite rules to use ellipses will happen in follow-up CLs. Change-Id: I8c56e85de24607579d79729575c89ca80805ba5c Reviewed-on: https://go-review.googlesource.com/c/go/+/213898 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
0f7088ade5
commit
8484d409ac
@ -176,6 +176,15 @@ func genRulesSuffix(arch arch, suff string) {
|
|||||||
|
|
||||||
sw := &Switch{expr: exprf("v.Op")}
|
sw := &Switch{expr: exprf("v.Op")}
|
||||||
for _, op := range ops {
|
for _, op := range ops {
|
||||||
|
eop, ok := parseEllipsisRules(oprules[op], arch)
|
||||||
|
if ok {
|
||||||
|
swc := &Case{expr: exprf(op)}
|
||||||
|
swc.add(stmtf("v.Op = %s", eop))
|
||||||
|
swc.add(stmtf("return true"))
|
||||||
|
sw.add(swc)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var ors []string
|
var ors []string
|
||||||
for chunk := 0; chunk < len(oprules[op]); chunk += chunkSize {
|
for chunk := 0; chunk < len(oprules[op]); chunk += chunkSize {
|
||||||
ors = append(ors, fmt.Sprintf("rewriteValue%s%s_%s_%d(v)", arch.name, suff, op, chunk))
|
ors = append(ors, fmt.Sprintf("rewriteValue%s%s_%s_%d(v)", arch.name, suff, op, chunk))
|
||||||
@ -192,6 +201,11 @@ func genRulesSuffix(arch arch, suff string) {
|
|||||||
// because it is too big for some compilers.
|
// because it is too big for some compilers.
|
||||||
for _, op := range ops {
|
for _, op := range ops {
|
||||||
rules := oprules[op]
|
rules := oprules[op]
|
||||||
|
_, ok := parseEllipsisRules(oprules[op], arch)
|
||||||
|
if ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// rr is kept between chunks, so that a following chunk checks
|
// rr is kept between chunks, so that a following chunk checks
|
||||||
// that the previous one ended with a rule that wasn't
|
// that the previous one ended with a rule that wasn't
|
||||||
// unconditional.
|
// unconditional.
|
||||||
@ -1240,7 +1254,7 @@ func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxi
|
|||||||
if x.name != s {
|
if x.name != s {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if x.argLength != -1 && int(x.argLength) != len(args) {
|
if x.argLength != -1 && int(x.argLength) != len(args) && (len(args) != 1 || args[0] != "...") {
|
||||||
if strict {
|
if strict {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -1507,3 +1521,28 @@ func normalizeMatch(m string, arch arch) string {
|
|||||||
}
|
}
|
||||||
return s.String()
|
return s.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseEllipsisRules(rules []Rule, arch arch) (newop string, ok bool) {
|
||||||
|
if len(rules) != 1 {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
rule := rules[0]
|
||||||
|
match, cond, result := rule.parse()
|
||||||
|
if cond != "" || !isEllipsisValue(match) || !isEllipsisValue(result) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
op, oparch, _, _, _, _ := parseValue(result, arch, rule.loc)
|
||||||
|
return fmt.Sprintf("Op%s%s", oparch, op.name), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// isEllipsisValue reports whether s is of the form (OpX ...).
|
||||||
|
func isEllipsisValue(s string) bool {
|
||||||
|
if len(s) < 2 || s[0] != '(' || s[len(s)-1] != ')' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c := split(s[1 : len(s)-1])
|
||||||
|
if len(c) != 2 || c[1] != "..." {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user