mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] cmd/compile: use string contents instead of offset from string header
This generates more efficient code. Before: 0x003a 00058 (rr.go:7) LEAQ go.string.hdr."="(SB), BX 0x0041 00065 (rr.go:7) LEAQ 16(BX), BP 0x0045 00069 (rr.go:7) MOVQ BP, 16(SP) After: 0x003a 00058 (rr.go:7) LEAQ go.string."="(SB), BX 0x0041 00065 (rr.go:7) MOVQ BX, 16(SP) It also matches the existing backend and is more robust to other changes, such as CL 11698, which I believe broke the current code. This CL fixes the encoding/base64 tests, as run with: GOGC=off GOSSAPKG=base64 go test -a encoding/base64 Change-Id: I3c475bed1dd3335cc14e13309e11d23f0ed32c17 Reviewed-on: https://go-review.googlesource.com/12654 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
d90e0481bf
commit
8d31df18af
5 changed files with 21 additions and 27 deletions
|
|
@ -1922,12 +1922,12 @@ type ssaExport struct {
|
|||
mustImplement bool
|
||||
}
|
||||
|
||||
// StringSym returns a symbol (a *Sym wrapped in an interface) which
|
||||
// is a global string constant containing s.
|
||||
func (*ssaExport) StringSym(s string) interface{} {
|
||||
// StringData returns a symbol (a *Sym wrapped in an interface) which
|
||||
// is the data component of a global string constant containing s.
|
||||
func (*ssaExport) StringData(s string) interface{} {
|
||||
// TODO: is idealstring correct? It might not matter...
|
||||
hdr, _ := stringsym(s)
|
||||
return &ssa.ExternSymbol{Typ: idealstring, Sym: hdr}
|
||||
_, data := stringsym(s)
|
||||
return &ssa.ExternSymbol{Typ: idealstring, Sym: data}
|
||||
}
|
||||
|
||||
// Log logs a message from the compiler.
|
||||
|
|
|
|||
|
|
@ -17,10 +17,8 @@ type Config struct {
|
|||
}
|
||||
|
||||
type Frontend interface {
|
||||
// StringSym returns a symbol pointing to the given string.
|
||||
// Strings are laid out in read-only memory with one word of pointer,
|
||||
// one word of length, then the contents of the string.
|
||||
StringSym(string) interface{} // returns *gc.Sym
|
||||
// StringData returns a symbol pointing to the given string's contents.
|
||||
StringData(string) interface{} // returns *gc.Sym
|
||||
|
||||
// Log logs a message from the compiler.
|
||||
Logf(string, ...interface{})
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ type DummyFrontend struct {
|
|||
t testing.TB
|
||||
}
|
||||
|
||||
func (DummyFrontend) StringSym(s string) interface{} {
|
||||
func (DummyFrontend) StringData(s string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
(Store dst (Load <t> src mem) mem) && t.Size() > 8 -> (Move [t.Size()] dst src mem)
|
||||
|
||||
// string ops
|
||||
(Const <t> {s}) && t.IsString() -> (StringMake (OffPtr <TypeBytePtr> [2*config.PtrSize] (Addr <TypeBytePtr> {config.fe.StringSym(s.(string))} (SB <config.Uintptr>))) (Const <config.Uintptr> [int64(len(s.(string)))])) // TODO: ptr
|
||||
(Const <t> {s}) && t.IsString() -> (StringMake (Addr <TypeBytePtr> {config.fe.StringData(s.(string))} (SB <config.Uintptr>)) (Const <config.Uintptr> [int64(len(s.(string)))]))
|
||||
(Load <t> ptr mem) && t.IsString() -> (StringMake (Load <TypeBytePtr> ptr mem) (Load <config.Uintptr> (OffPtr <TypeBytePtr> [config.PtrSize] ptr) mem))
|
||||
(StringPtr (StringMake ptr _)) -> ptr
|
||||
(StringLen (StringMake _ len)) -> len
|
||||
|
|
|
|||
|
|
@ -102,36 +102,32 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
|
|||
case OpConst:
|
||||
// match: (Const <t> {s})
|
||||
// cond: t.IsString()
|
||||
// result: (StringMake (OffPtr <TypeBytePtr> [2*config.PtrSize] (Addr <TypeBytePtr> {config.fe.StringSym(s.(string))} (SB <config.Uintptr>))) (Const <config.Uintptr> [int64(len(s.(string)))]))
|
||||
// result: (StringMake (Addr <TypeBytePtr> {config.fe.StringData(s.(string))} (SB <config.Uintptr>)) (Const <config.Uintptr> [int64(len(s.(string)))]))
|
||||
{
|
||||
t := v.Type
|
||||
s := v.Aux
|
||||
if !(t.IsString()) {
|
||||
goto endedcb8bd24122d6a47bdc9b752460c344
|
||||
goto enda6f250a3c775ae5a239ece8074b46cea
|
||||
}
|
||||
v.Op = OpStringMake
|
||||
v.AuxInt = 0
|
||||
v.Aux = nil
|
||||
v.resetArgs()
|
||||
v0 := v.Block.NewValue0(v.Line, OpOffPtr, TypeInvalid)
|
||||
v0 := v.Block.NewValue0(v.Line, OpAddr, TypeInvalid)
|
||||
v0.Type = TypeBytePtr
|
||||
v0.AuxInt = 2 * config.PtrSize
|
||||
v1 := v.Block.NewValue0(v.Line, OpAddr, TypeInvalid)
|
||||
v1.Type = TypeBytePtr
|
||||
v1.Aux = config.fe.StringSym(s.(string))
|
||||
v2 := v.Block.NewValue0(v.Line, OpSB, TypeInvalid)
|
||||
v2.Type = config.Uintptr
|
||||
v1.AddArg(v2)
|
||||
v0.Aux = config.fe.StringData(s.(string))
|
||||
v1 := v.Block.NewValue0(v.Line, OpSB, TypeInvalid)
|
||||
v1.Type = config.Uintptr
|
||||
v0.AddArg(v1)
|
||||
v.AddArg(v0)
|
||||
v3 := v.Block.NewValue0(v.Line, OpConst, TypeInvalid)
|
||||
v3.Type = config.Uintptr
|
||||
v3.AuxInt = int64(len(s.(string)))
|
||||
v.AddArg(v3)
|
||||
v2 := v.Block.NewValue0(v.Line, OpConst, TypeInvalid)
|
||||
v2.Type = config.Uintptr
|
||||
v2.AuxInt = int64(len(s.(string)))
|
||||
v.AddArg(v2)
|
||||
return true
|
||||
}
|
||||
goto endedcb8bd24122d6a47bdc9b752460c344
|
||||
endedcb8bd24122d6a47bdc9b752460c344:
|
||||
goto enda6f250a3c775ae5a239ece8074b46cea
|
||||
enda6f250a3c775ae5a239ece8074b46cea:
|
||||
;
|
||||
case OpIsInBounds:
|
||||
// match: (IsInBounds (Const [c]) (Const [d]))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue