aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ir
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-07-03 04:53:25 -0700
committerMatthew Dempsky <mdempsky@google.com>2021-07-03 17:45:52 +0000
commitc45d0eaadb77f11061cf9b18f521eb0b27e6bedb (patch)
treeb910e6da7e316f7f2408460a5fb2cbb99ac093f3 /src/cmd/compile/internal/ir
parentad2ba3ff518b9762e3f5497f0a8ce67c0e155aa8 (diff)
downloadgo-c45d0eaadb77f11061cf9b18f521eb0b27e6bedb.tar.gz
go-c45d0eaadb77f11061cf9b18f521eb0b27e6bedb.zip
[dev.typeparams] cmd/compile: flatten OINLCALL in walk
Inlining replaces inlined calls with OINLCALL nodes, and then somewhat clumsily tries to rewrite these in place without messing up order-of-evaluation rules. But handling these rules cleanly is much easier to do during order, and escape analysis is the only major pass between inlining and order. It's simpler to teach escape analysis how to analyze OINLCALL nodes than to try to hide them from escape analysis. Does not pass toolstash -cmp, but seems to just be line number changes. Change-Id: I1986cea39793e3e1ed5e887ba29d46364c6c532e Reviewed-on: https://go-review.googlesource.com/c/go/+/332649 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Trust: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ir')
-rw-r--r--src/cmd/compile/internal/ir/expr.go14
-rw-r--r--src/cmd/compile/internal/ir/fmt.go9
2 files changed, 22 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go
index 919cb3362f..4ff75e616d 100644
--- a/src/cmd/compile/internal/ir/expr.go
+++ b/src/cmd/compile/internal/ir/expr.go
@@ -345,7 +345,7 @@ func (n *StructKeyExpr) Sym() *types.Sym { return n.Field.Sym }
type InlinedCallExpr struct {
miniExpr
Body Nodes
- ReturnVars Nodes
+ ReturnVars Nodes // must be side-effect free
}
func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
@@ -357,6 +357,13 @@ func NewInlinedCallExpr(pos src.XPos, body, retvars []Node) *InlinedCallExpr {
return n
}
+func (n *InlinedCallExpr) SingleResult() Node {
+ if have := len(n.ReturnVars); have != 1 {
+ base.FatalfAt(n.Pos(), "inlined call has %v results, expected 1", have)
+ }
+ return n.ReturnVars[0]
+}
+
// A LogicalExpr is a expression X Op Y where Op is && or ||.
// It is separate from BinaryExpr to make room for statements
// that must be executed before Y but after X.
@@ -800,6 +807,11 @@ func StaticValue(n Node) Node {
continue
}
+ if n.Op() == OINLCALL {
+ n = n.(*InlinedCallExpr).SingleResult()
+ continue
+ }
+
n1 := staticValue1(n)
if n1 == nil {
return n
diff --git a/src/cmd/compile/internal/ir/fmt.go b/src/cmd/compile/internal/ir/fmt.go
index ae62d5f51b..6f6e26dec4 100644
--- a/src/cmd/compile/internal/ir/fmt.go
+++ b/src/cmd/compile/internal/ir/fmt.go
@@ -859,6 +859,15 @@ func exprFmt(n Node, s fmt.State, prec int) {
}
fmt.Fprintf(s, "(%.v)", n.Args)
+ case OINLCALL:
+ n := n.(*InlinedCallExpr)
+ // TODO(mdempsky): Print Init and/or Body?
+ if len(n.ReturnVars) == 1 {
+ fmt.Fprintf(s, "%v", n.ReturnVars[0])
+ return
+ }
+ fmt.Fprintf(s, "(.%v)", n.ReturnVars)
+
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
n := n.(*MakeExpr)
if n.Cap != nil {