diff options
author | David Chase <drchase@google.com> | 2021-02-04 16:42:35 -0500 |
---|---|---|
committer | David Chase <drchase@google.com> | 2021-02-26 02:52:33 +0000 |
commit | e25040d16288563c89cead5e8da8d3b9c74ab655 (patch) | |
tree | 4e57425c9764cf01ac69447f06d1bb52f07d9e46 /src/cmd/compile/internal/ssa/gen | |
parent | 9a555fc24c318bf1b07bdc07d5c02e372681e401 (diff) | |
download | go-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.rules | 54 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/gen/genericOps.go | 2 |
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. |