aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/gen
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-02-04 16:42:35 -0500
committerDavid Chase <drchase@google.com>2021-02-26 02:52:33 +0000
commite25040d16288563c89cead5e8da8d3b9c74ab655 (patch)
tree4e57425c9764cf01ac69447f06d1bb52f07d9e46 /src/cmd/compile/internal/ssa/gen
parent9a555fc24c318bf1b07bdc07d5c02e372681e401 (diff)
downloadgo-e25040d16288563c89cead5e8da8d3b9c74ab655.tar.gz
go-e25040d16288563c89cead5e8da8d3b9c74ab655.zip
cmd/compile: change StaticCall to return a "Results"
StaticLECall (multiple value in +mem, multiple value result +mem) -> StaticCall (multiple ergister value in +mem, multiple register-sized-value result +mem) -> ARCH CallStatic (multiple ergister value in +mem, multiple register-sized-value result +mem) But the architecture-dependent stuff is indifferent to whether it is mem->mem or (mem)->(mem) until Prog generation. Deal with OpSelectN -> Prog in ssagen/ssa.go, others, as they appear. For #40724. Change-Id: I1d0436f6371054f1881862641d8e7e418e4a6a16 Reviewed-on: https://go-review.googlesource.com/c/go/+/293391 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/gen')
-rw-r--r--src/cmd/compile/internal/ssa/gen/generic.rules54
-rw-r--r--src/cmd/compile/internal/ssa/gen/genericOps.go2
2 files changed, 11 insertions, 45 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index 1784923224..fab45243ed 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -1970,37 +1970,6 @@
(Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(c)) => (Const64F [math.Sqrt(c)])
-// recognize runtime.newobject and don't Zero/Nilcheck it
-(Zero (Load (OffPtr [c] (SP)) mem) mem)
- && mem.Op == OpStaticCall
- && isSameCall(mem.Aux, "runtime.newobject")
- && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
- => mem
-(Store (Load (OffPtr [c] (SP)) mem) x mem)
- && isConstZero(x)
- && mem.Op == OpStaticCall
- && isSameCall(mem.Aux, "runtime.newobject")
- && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
- => mem
-(Store (OffPtr (Load (OffPtr [c] (SP)) mem)) x mem)
- && isConstZero(x)
- && mem.Op == OpStaticCall
- && isSameCall(mem.Aux, "runtime.newobject")
- && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
- => mem
-// nil checks just need to rewrite to something useless.
-// they will be deadcode eliminated soon afterwards.
-(NilCheck (Load (OffPtr [c] (SP)) (StaticCall {sym} _)) _)
- && isSameCall(sym, "runtime.newobject")
- && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
- && warnRule(fe.Debug_checknil(), v, "removed nil check")
- => (Invalid)
-(NilCheck (OffPtr (Load (OffPtr [c] (SP)) (StaticCall {sym} _))) _)
- && isSameCall(sym, "runtime.newobject")
- && c == config.ctxt.FixedFrameSize() + config.RegSize // offset of return value
- && warnRule(fe.Debug_checknil(), v, "removed nil check")
- => (Invalid)
-
// for rewriting results of some late-expanded rewrites (below)
(SelectN [0] (MakeResult a ___)) => a
(SelectN [1] (MakeResult a b ___)) => b
@@ -2021,12 +1990,12 @@
&& isSameCall(call.Aux, "runtime.newobject")
=> mem
-(NilCheck (SelectN [0] call:(StaticLECall _ _)) (SelectN [1] call))
+(NilCheck (SelectN [0] call:(StaticLECall _ _)) _)
&& isSameCall(call.Aux, "runtime.newobject")
&& warnRule(fe.Debug_checknil(), v, "removed nil check")
=> (Invalid)
-(NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) (SelectN [1] call))
+(NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) _)
&& isSameCall(call.Aux, "runtime.newobject")
&& warnRule(fe.Debug_checknil(), v, "removed nil check")
=> (Invalid)
@@ -2083,15 +2052,19 @@
(IsNonNil (Addr _)) => (ConstBool [true])
(IsNonNil (LocalAddr _ _)) => (ConstBool [true])
+// TODO REGISTER ARGS this will need revision.
+// Because expand calls runs after prove, constants useful to this pattern may not appear
+// In the future both versions need to exist; the memory and register variants.
+
// Inline small or disjoint runtime.memmove calls with constant length.
// See the comment in op Move in genericOps.go for discussion of the type.
-(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
+(SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))))
&& sz >= 0
&& isSameCall(sym, "runtime.memmove")
&& t.IsPtr() // avoids TUINTPTR, see issue 30061
&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
&& isInlinableMemmove(dst, src, int64(sz), config)
- && clobber(s1, s2, s3)
+ && clobber(s1, s2, s3, call)
=> (Move {t.Elem()} [int64(sz)] dst src mem)
// Inline small or disjoint runtime.memmove calls with constant length.
@@ -2105,13 +2078,6 @@
&& clobber(call)
=> (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
-// De-virtualize interface calls into static calls.
-// Note that (ITab (IMake)) doesn't get
-// rewritten until after the first opt pass,
-// so this rule should trigger reliably.
-(InterCall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) mem) && devirt(v, auxCall, itab, off) != nil =>
- (StaticCall [int32(argsize)] {devirt(v, auxCall, itab, off)} mem)
-
// De-virtualize late-expanded interface calls into late-expanded static calls.
// Note that (ITab (IMake)) doesn't get rewritten until after the first opt pass,
// so this rule should trigger reliably.
@@ -2499,8 +2465,8 @@
(Store {t5} (OffPtr <tt5> [o5] dst) d4
(Zero {t1} [n] dst mem)))))
-// TODO this does not fire before call expansion; is that acceptable?
-(StaticCall {sym} x) && needRaceCleanup(sym, v) => x
+(SelectN [0] call:(StaticLECall {sym} a x)) && needRaceCleanup(sym, call) && clobber(call) => x
+(SelectN [0] call:(StaticLECall {sym} x)) && needRaceCleanup(sym, call) && clobber(call) => x
// Collapse moving A -> B -> C into just A -> C.
// Later passes (deadstore, elim unread auto) will remove the A -> B move, if possible.
diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go
index 23a2d74b14..043f445c16 100644
--- a/src/cmd/compile/internal/ssa/gen/genericOps.go
+++ b/src/cmd/compile/internal/ssa/gen/genericOps.go
@@ -396,7 +396,7 @@ var genericOps = []opData{
// to match StaticCall's 32 bit arg size limit.
// TODO(drchase,josharian): could the arg size limit be bundled into the rules for CallOff?
{name: "ClosureCall", argLength: 3, aux: "CallOff", call: true}, // arg0=code pointer, arg1=context ptr, arg2=memory. auxint=arg size. Returns memory.
- {name: "StaticCall", argLength: 1, aux: "CallOff", call: true}, // call function aux.(*obj.LSym), arg0=memory. auxint=arg size. Returns memory.
+ {name: "StaticCall", argLength: -1, aux: "CallOff", call: true}, // call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory. auxint=arg size. Returns Result of register results, plus memory.
{name: "InterCall", argLength: 2, aux: "CallOff", call: true}, // interface call. arg0=code pointer, arg1=memory, auxint=arg size. Returns memory.
{name: "ClosureLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded closure call. arg0=code pointer, arg1=context ptr, arg2..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
{name: "StaticLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded static call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.