|
5 | 5 | package walk |
6 | 6 |
|
7 | 7 | import ( |
| 8 | + "go/constant" |
8 | 9 | "internal/buildcfg" |
9 | 10 | "unicode/utf8" |
10 | 11 |
|
@@ -80,6 +81,10 @@ func walkRange(nrange *ir.RangeStmt) ir.Node { |
80 | 81 | base.Fatalf("walkRange") |
81 | 82 |
|
82 | 83 | case types.IsInt[k]: |
| 84 | + if nn := arrayRangeClear(nrange, v1, v2, a); nn != nil { |
| 85 | + base.Pos = lno |
| 86 | + return nn |
| 87 | + } |
83 | 88 | hv1 := typecheck.TempAt(base.Pos, ir.CurFunc, t) |
84 | 89 | hn := typecheck.TempAt(base.Pos, ir.CurFunc, t) |
85 | 90 |
|
@@ -519,21 +524,41 @@ func arrayRangeClear(loop *ir.RangeStmt, v1, v2, a ir.Node) ir.Node { |
519 | 524 | } |
520 | 525 | lhs := stmt.X.(*ir.IndexExpr) |
521 | 526 | x := lhs.X |
522 | | - if a.Type().IsPtr() && a.Type().Elem().IsArray() { |
523 | | - if s, ok := x.(*ir.StarExpr); ok && s.Op() == ir.ODEREF { |
524 | | - x = s.X |
| 527 | + |
| 528 | + // Get constant number of iterations for int and array cases. |
| 529 | + n := int64(-1) |
| 530 | + if ir.IsConst(a, constant.Int) { |
| 531 | + n = ir.Int64Val(a) |
| 532 | + } else if a.Type().IsArray() { |
| 533 | + n = a.Type().NumElem() |
| 534 | + } else if a.Type().IsPtr() && a.Type().Elem().IsArray() { |
| 535 | + n = a.Type().Elem().NumElem() |
| 536 | + } |
| 537 | + |
| 538 | + if n >= 0 { |
| 539 | + // Int/Array case. |
| 540 | + if !x.Type().IsArray() { |
| 541 | + return nil |
| 542 | + } |
| 543 | + if x.Type().NumElem() != n { |
| 544 | + return nil |
| 545 | + } |
| 546 | + } else { |
| 547 | + // Slice case. |
| 548 | + if !ir.SameSafeExpr(x, a) { |
| 549 | + return nil |
525 | 550 | } |
526 | 551 | } |
527 | 552 |
|
528 | | - if !ir.SameSafeExpr(x, a) || !ir.SameSafeExpr(lhs.Index, v1) { |
| 553 | + if !ir.SameSafeExpr(lhs.Index, v1) { |
529 | 554 | return nil |
530 | 555 | } |
531 | 556 |
|
532 | 557 | if !ir.IsZero(stmt.Y) { |
533 | 558 | return nil |
534 | 559 | } |
535 | 560 |
|
536 | | - return arrayClear(stmt.Pos(), a, loop) |
| 561 | + return arrayClear(stmt.Pos(), x, loop) |
537 | 562 | } |
538 | 563 |
|
539 | 564 | // arrayClear constructs a call to runtime.memclr for fast zeroing of slices and arrays. |
|
0 commit comments