cmd/compile: remove OFORUNTIL

Not used any more.

Fixes #53860

Change-Id: Id0b1c3ed30b576d6c5f08f064d1262de337262b3
Reviewed-on: https://go-review.googlesource.com/c/go/+/418374
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Keith Randall 2022-07-19 13:15:05 -07:00 committed by Keith Randall
parent 6dc7b060cd
commit a5370d038e
12 changed files with 69 additions and 142 deletions

View file

@ -78,7 +78,7 @@ func (e *escape) stmt(n ir.Node) {
n := n.(*ir.UnaryExpr)
e.discard(n.X)
case ir.OFOR, ir.OFORUNTIL:
case ir.OFOR:
n := n.(*ir.ForStmt)
e.loopDepth++
e.discard(n.Cond)

View file

@ -50,7 +50,6 @@ var OpNames = []string{
OEQ: "==",
OFALL: "fallthrough",
OFOR: "for",
OFORUNTIL: "foruntil", // not actual syntax; used to avoid off-end pointer live on backedge.892
OGE: ">=",
OGOTO: "goto",
OGT: ">",
@ -274,7 +273,6 @@ var OpPrec = []int{
ODEFER: -1,
OFALL: -1,
OFOR: -1,
OFORUNTIL: -1,
OGOTO: -1,
OIF: -1,
OLABEL: -1,
@ -290,7 +288,7 @@ var OpPrec = []int{
// StmtWithInit reports whether op is a statement with an explicit init list.
func StmtWithInit(op Op) bool {
switch op {
case OIF, OFOR, OFORUNTIL, OSWITCH:
case OIF, OFOR, OSWITCH:
return true
}
return false
@ -401,18 +399,14 @@ func stmtFmt(n Node, s fmt.State) {
fmt.Fprintf(s, " else { %v }", n.Else)
}
case OFOR, OFORUNTIL:
case OFOR:
n := n.(*ForStmt)
opname := "for"
if n.Op() == OFORUNTIL {
opname = "foruntil"
}
if !exportFormat { // TODO maybe only if FmtShort, same below
fmt.Fprintf(s, "%s loop", opname)
fmt.Fprintf(s, "for loop")
break
}
fmt.Fprint(s, opname)
fmt.Fprint(s, "for")
if simpleinit {
fmt.Fprintf(s, " %v;", n.Init()[0])
} else if n.Post != nil {
@ -429,10 +423,6 @@ func stmtFmt(n Node, s fmt.State) {
fmt.Fprint(s, ";")
}
if n.Op() == OFORUNTIL && len(n.Late) != 0 {
fmt.Fprintf(s, "; %v", n.Late)
}
fmt.Fprintf(s, " { %v }", n.Body)
case ORANGE:

View file

@ -263,16 +263,6 @@ const (
ODEFER // defer Call
OFALL // fallthrough
OFOR // for Init; Cond; Post { Body }
// OFORUNTIL is like OFOR, but the test (Cond) is applied after the body:
// Init
// top: { Body } // Execute the body at least once
// cont: Post
// if Cond { // And then test the loop condition
// List // Before looping to top, execute List
// goto top
// }
// OFORUNTIL is created by walk. There's no way to write this in Go code.
OFORUNTIL
OGOTO // goto Label
OIF // if Init; Cond { Then } else { Else }
OLABEL // Label:

View file

@ -483,7 +483,6 @@ func (n *ForStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ForStmt) copy() Node {
c := *n
c.init = copyNodes(c.init)
c.Late = copyNodes(c.Late)
c.Body = copyNodes(c.Body)
return &c
}
@ -494,9 +493,6 @@ func (n *ForStmt) doChildren(do func(Node) bool) bool {
if n.Cond != nil && do(n.Cond) {
return true
}
if doNodes(n.Late, do) {
return true
}
if n.Post != nil && do(n.Post) {
return true
}
@ -510,7 +506,6 @@ func (n *ForStmt) editChildren(edit func(Node) Node) {
if n.Cond != nil {
n.Cond = edit(n.Cond).(Node)
}
editNodes(n.Late, edit)
if n.Post != nil {
n.Post = edit(n.Post).(Node)
}

View file

@ -129,44 +129,43 @@ func _() {
_ = x[ODEFER-118]
_ = x[OFALL-119]
_ = x[OFOR-120]
_ = x[OFORUNTIL-121]
_ = x[OGOTO-122]
_ = x[OIF-123]
_ = x[OLABEL-124]
_ = x[OGO-125]
_ = x[ORANGE-126]
_ = x[ORETURN-127]
_ = x[OSELECT-128]
_ = x[OSWITCH-129]
_ = x[OTYPESW-130]
_ = x[OFUNCINST-131]
_ = x[OINLCALL-132]
_ = x[OEFACE-133]
_ = x[OITAB-134]
_ = x[OIDATA-135]
_ = x[OSPTR-136]
_ = x[OCFUNC-137]
_ = x[OCHECKNIL-138]
_ = x[OVARDEF-139]
_ = x[OVARKILL-140]
_ = x[OVARLIVE-141]
_ = x[ORESULT-142]
_ = x[OINLMARK-143]
_ = x[OLINKSYMOFFSET-144]
_ = x[OJUMPTABLE-145]
_ = x[ODYNAMICDOTTYPE-146]
_ = x[ODYNAMICDOTTYPE2-147]
_ = x[ODYNAMICTYPE-148]
_ = x[OTAILCALL-149]
_ = x[OGETG-150]
_ = x[OGETCALLERPC-151]
_ = x[OGETCALLERSP-152]
_ = x[OEND-153]
_ = x[OGOTO-121]
_ = x[OIF-122]
_ = x[OLABEL-123]
_ = x[OGO-124]
_ = x[ORANGE-125]
_ = x[ORETURN-126]
_ = x[OSELECT-127]
_ = x[OSWITCH-128]
_ = x[OTYPESW-129]
_ = x[OFUNCINST-130]
_ = x[OINLCALL-131]
_ = x[OEFACE-132]
_ = x[OITAB-133]
_ = x[OIDATA-134]
_ = x[OSPTR-135]
_ = x[OCFUNC-136]
_ = x[OCHECKNIL-137]
_ = x[OVARDEF-138]
_ = x[OVARKILL-139]
_ = x[OVARLIVE-140]
_ = x[ORESULT-141]
_ = x[OINLMARK-142]
_ = x[OLINKSYMOFFSET-143]
_ = x[OJUMPTABLE-144]
_ = x[ODYNAMICDOTTYPE-145]
_ = x[ODYNAMICDOTTYPE2-146]
_ = x[ODYNAMICTYPE-147]
_ = x[OTAILCALL-148]
_ = x[OGETG-149]
_ = x[OGETCALLERPC-150]
_ = x[OGETCALLERSP-151]
_ = x[OEND-152]
}
const _Op_name = "XXXNAMENONAMETYPELITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVIDATACONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2REALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETJUMPTABLEDYNAMICDOTTYPEDYNAMICDOTTYPE2DYNAMICTYPETAILCALLGETGGETCALLERPCGETCALLERSPEND"
const _Op_name = "XXXNAMENONAMETYPELITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVIDATACONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2REALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETJUMPTABLEDYNAMICDOTTYPEDYNAMICDOTTYPE2DYNAMICTYPETAILCALLGETGGETCALLERPCGETCALLERSPEND"
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 24, 27, 30, 33, 35, 38, 44, 48, 54, 60, 69, 81, 90, 99, 111, 120, 132, 134, 137, 147, 154, 161, 168, 172, 176, 184, 192, 201, 204, 209, 216, 223, 229, 238, 246, 254, 260, 264, 273, 282, 289, 293, 296, 303, 311, 318, 324, 327, 333, 340, 348, 352, 359, 367, 369, 371, 373, 375, 377, 379, 384, 389, 397, 400, 409, 412, 416, 424, 431, 440, 453, 456, 459, 462, 465, 468, 471, 477, 480, 483, 489, 493, 496, 500, 505, 510, 516, 521, 525, 530, 538, 546, 552, 561, 572, 579, 588, 592, 599, 607, 611, 615, 622, 629, 637, 643, 652, 663, 671, 680, 685, 690, 694, 702, 707, 711, 714, 722, 726, 728, 733, 735, 740, 746, 752, 758, 764, 772, 779, 784, 788, 793, 797, 802, 810, 816, 823, 830, 836, 843, 856, 865, 879, 894, 905, 913, 917, 928, 939, 942}
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 24, 27, 30, 33, 35, 38, 44, 48, 54, 60, 69, 81, 90, 99, 111, 120, 132, 134, 137, 147, 154, 161, 168, 172, 176, 184, 192, 201, 204, 209, 216, 223, 229, 238, 246, 254, 260, 264, 273, 282, 289, 293, 296, 303, 311, 318, 324, 327, 333, 340, 348, 352, 359, 367, 369, 371, 373, 375, 377, 379, 384, 389, 397, 400, 409, 412, 416, 424, 431, 440, 453, 456, 459, 462, 465, 468, 471, 477, 480, 483, 489, 493, 496, 500, 505, 510, 516, 521, 525, 530, 538, 546, 552, 561, 572, 579, 588, 592, 599, 607, 611, 615, 622, 629, 637, 643, 652, 663, 671, 680, 685, 690, 694, 702, 707, 711, 714, 718, 720, 725, 727, 732, 738, 744, 750, 756, 764, 771, 776, 780, 785, 789, 794, 802, 808, 815, 822, 828, 835, 848, 857, 871, 886, 897, 905, 909, 920, 931, 934}
func (i Op) String() string {
if i >= Op(len(_Op_index)-1) {

View file

@ -205,12 +205,10 @@ func NewCommStmt(pos src.XPos, comm Node, body []Node) *CommClause {
}
// A ForStmt is a non-range for loop: for Init; Cond; Post { Body }
// Op can be OFOR or OFORUNTIL (!Cond).
type ForStmt struct {
miniStmt
Label *types.Sym
Cond Node
Late Nodes
Post Node
Body Nodes
HasBreak bool
@ -227,13 +225,6 @@ func NewForStmt(pos src.XPos, init Node, cond, post Node, body []Node) *ForStmt
return n
}
func (n *ForStmt) SetOp(op Op) {
if op != OFOR && op != OFORUNTIL {
panic(n.no("SetOp " + op.String()))
}
n.op = op
}
// A GoDeferStmt is a go or defer statement: go Call / defer Call.
//
// The two opcodes use a single syntax because the implementations

View file

@ -1099,8 +1099,7 @@ func addRestrictions(parent *Block, ft *factsTable, t domain, v, w *Value, r rel
// addLocalInductiveFacts adds inductive facts when visiting b, where
// b is a join point in a loop. In contrast with findIndVar, this
// depends on facts established for b, which is why it happens when
// visiting b. addLocalInductiveFacts specifically targets the pattern
// created by OFORUNTIL, which isn't detected by findIndVar.
// visiting b.
//
// TODO: It would be nice to combine this with findIndVar.
func addLocalInductiveFacts(ft *factsTable, b *Block) {

View file

@ -1738,12 +1738,9 @@ func (s *state) stmt(n ir.Node) {
b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
b.AddEdgeTo(to)
case ir.OFOR, ir.OFORUNTIL:
case ir.OFOR:
// OFOR: for Ninit; Left; Right { Nbody }
// cond (Left); body (Nbody); incr (Right)
//
// OFORUNTIL: for Ninit; Left; Right; List { Nbody }
// => body: { Nbody }; incr: Right; if Left { lateincr: List; goto body }; end:
n := n.(*ir.ForStmt)
bCond := s.f.NewBlock(ssa.BlockPlain)
bBody := s.f.NewBlock(ssa.BlockPlain)
@ -1753,10 +1750,10 @@ func (s *state) stmt(n ir.Node) {
// ensure empty for loops have correct position; issue #30167
bBody.Pos = n.Pos()
// first, jump to condition test (OFOR) or body (OFORUNTIL)
// first, jump to condition test
b := s.endBlock()
if n.Op() == ir.OFOR {
b.AddEdgeTo(bCond)
// generate code to test condition
s.startBlock(bCond)
if n.Cond != nil {
@ -1767,10 +1764,6 @@ func (s *state) stmt(n ir.Node) {
b.AddEdgeTo(bBody)
}
} else {
b.AddEdgeTo(bBody)
}
// set up for continue/break in body
prevContinue := s.continueTo
prevBreak := s.breakTo
@ -1801,12 +1794,11 @@ func (s *state) stmt(n ir.Node) {
b.AddEdgeTo(bIncr)
}
// generate incr (and, for OFORUNTIL, condition)
// generate incr
s.startBlock(bIncr)
if n.Post != nil {
s.stmt(n.Post)
}
if n.Op() == ir.OFOR {
if b := s.endBlock(); b != nil {
b.AddEdgeTo(bCond)
// It can happen that bIncr ends in a block containing only VARKILL,
@ -1815,16 +1807,6 @@ func (s *state) stmt(n ir.Node) {
b.Pos = bCond.Pos
}
}
} else {
// bCond is unused in OFORUNTIL, so repurpose it.
bLateIncr := bCond
// test condition
s.condBranch(n.Cond, bLateIncr, bEnd, 1)
// generate late increment
s.startBlock(bLateIncr)
s.stmtList(n.Late)
s.endBlock().AddEdgeTo(bBody)
}
s.startBlock(bEnd)

View file

@ -258,9 +258,6 @@ func tcFor(n *ir.ForStmt) ir.Node {
}
}
n.Post = Stmt(n.Post)
if n.Op() == ir.OFORUNTIL {
Stmts(n.Late)
}
Stmts(n.Body)
return n
}

View file

@ -774,7 +774,7 @@ func typecheck1(n ir.Node, top int) ir.Node {
tcGoDefer(n)
return n
case ir.OFOR, ir.OFORUNTIL:
case ir.OFOR:
n := n.(*ir.ForStmt)
return tcFor(n)
@ -1697,7 +1697,7 @@ func markBreak(fn *ir.Func) {
setHasBreak(labels[n.Label])
}
case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT, ir.ORANGE:
case ir.OFOR, ir.OSWITCH, ir.OSELECT, ir.ORANGE:
old := implicit
implicit = n
var sym *types.Sym
@ -1773,7 +1773,7 @@ func isTermNode(n ir.Node) bool {
case ir.OGOTO, ir.ORETURN, ir.OTAILCALL, ir.OPANIC, ir.OFALL:
return true
case ir.OFOR, ir.OFORUNTIL:
case ir.OFOR:
n := n.(*ir.ForStmt)
if n.Cond != nil {
return false

View file

@ -123,19 +123,6 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
break
}
// TODO(austin): OFORUNTIL is a strange beast, but is
// necessary for expressing the control flow we need
// while also making "break" and "continue" work. It
// would be nice to just lower ORANGE during SSA, but
// racewalk needs to see many of the operations
// involved in ORANGE's implementation. If racewalk
// moves into SSA, consider moving ORANGE into SSA and
// eliminating OFORUNTIL.
// TODO(austin): OFORUNTIL inhibits bounds-check
// elimination on the index variable (see #20711).
// Enhance the prove pass to understand this.
// Slice to iterate over
var hs ir.Node
if t.IsSlice() {

View file

@ -124,7 +124,7 @@ func walkStmt(n ir.Node) ir.Node {
n := n.(*ir.GoDeferStmt)
return walkGoDefer(n)
case ir.OFOR, ir.OFORUNTIL:
case ir.OFOR:
n := n.(*ir.ForStmt)
return walkFor(n)
@ -178,7 +178,7 @@ func walkStmtList(s []ir.Node) {
}
}
// walkFor walks an OFOR or OFORUNTIL node.
// walkFor walks an OFOR node.
func walkFor(n *ir.ForStmt) ir.Node {
if n.Cond != nil {
init := ir.TakeInit(n.Cond)
@ -188,9 +188,6 @@ func walkFor(n *ir.ForStmt) ir.Node {
}
n.Post = walkStmt(n.Post)
if n.Op() == ir.OFORUNTIL {
walkStmtList(n.Late)
}
walkStmtList(n.Body)
return n
}