Skip to content

Commit 61d6817

Browse files
rscgopherbot
authored andcommitted
cmd/compile: compile cap(ch) as call to runtime.chancap
An upcoming CL will give this call more to do. For now, separate out the compiler change that stops inlining the computation. For #37196. Change-Id: I965426d446964b9b4958e4613246002a7660e7eb Reviewed-on: https://go-review.googlesource.com/c/go/+/568375 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Auto-Submit: Russ Cox <[email protected]>
1 parent 24fa754 commit 61d6817

File tree

5 files changed

+22
-9
lines changed

5 files changed

+22
-9
lines changed

src/cmd/compile/internal/ssagen/ssa.go

+3
Original file line numberDiff line numberDiff line change
@@ -6350,6 +6350,9 @@ func (s *state) referenceTypeBuiltin(n *ir.UnaryExpr, x *ssa.Value) *ssa.Value {
63506350
if n.X.Type().IsChan() && n.Op() == ir.OLEN {
63516351
s.Fatalf("cannot inline len(chan)") // must use runtime.chanlen now
63526352
}
6353+
if n.X.Type().IsChan() && n.Op() == ir.OCAP {
6354+
s.Fatalf("cannot inline cap(chan)") // must use runtime.chancap now
6355+
}
63536356
// if n == nil {
63546357
// return 0
63556358
// } else {

src/cmd/compile/internal/typecheck/_builtin/runtime.go

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ func chanrecv2(hchan <-chan any, elem *any) bool
161161
func chansend1(hchan chan<- any, elem *any)
162162
func closechan(hchan chan<- any)
163163
func chanlen(hchan any) int
164+
func chancap(hchan any) int
164165

165166
var writeBarrier struct {
166167
enabled bool

src/cmd/compile/internal/typecheck/builtin.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/walk/builtin.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,14 @@ func walkLenCap(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
261261
_, len := backingArrayPtrLen(cheapExpr(conv.X, init))
262262
return len
263263
}
264-
if isChanLen(n) {
264+
if isChanLenCap(n) {
265+
name := "chanlen"
266+
if n.Op() == ir.OCAP {
267+
name = "chancap"
268+
}
265269
// cannot use chanfn - closechan takes any, not chan any,
266270
// because it accepts both send-only and recv-only channels.
267-
fn := typecheck.LookupRuntime("chanlen", n.X.Type())
271+
fn := typecheck.LookupRuntime(name, n.X.Type())
268272
return mkcall1(fn, n.Type(), init, n.X)
269273
}
270274

@@ -892,9 +896,9 @@ func isByteCount(n ir.Node) bool {
892896
(n.(*ir.UnaryExpr).X.Op() == ir.OBYTES2STR || n.(*ir.UnaryExpr).X.Op() == ir.OBYTES2STRTMP)
893897
}
894898

895-
// isChanLen reports whether n is of the form len(c) for a channel c.
899+
// isChanLenCap reports whether n is of the form len(c) or cap(c) for a channel c.
896900
// Note that this does not check for -n or instrumenting because this
897901
// is a correctness rewrite, not an optimization.
898-
func isChanLen(n ir.Node) bool {
899-
return n.Op() == ir.OLEN && n.(*ir.UnaryExpr).X.Type().IsChan()
902+
func isChanLenCap(n ir.Node) bool {
903+
return (n.Op() == ir.OLEN || n.Op() == ir.OCAP) && n.(*ir.UnaryExpr).X.Type().IsChan()
900904
}

src/runtime/chan.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,13 @@ func chanlen(c *hchan) int {
731731
return int(c.qcount)
732732
}
733733

734+
func chancap(c *hchan) int {
735+
if c == nil {
736+
return 0
737+
}
738+
return int(c.dataqsiz)
739+
}
740+
734741
//go:linkname reflect_chanlen reflect.chanlen
735742
func reflect_chanlen(c *hchan) int {
736743
return chanlen(c)
@@ -743,10 +750,7 @@ func reflectlite_chanlen(c *hchan) int {
743750

744751
//go:linkname reflect_chancap reflect.chancap
745752
func reflect_chancap(c *hchan) int {
746-
if c == nil {
747-
return 0
748-
}
749-
return int(c.dataqsiz)
753+
return chancap(c)
750754
}
751755

752756
//go:linkname reflect_chanclose reflect.chanclose

0 commit comments

Comments
 (0)