diff options
| author | Keith Randall <khr@golang.org> | 2015-06-19 21:02:28 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2015-06-25 17:54:18 +0000 |
| commit | 8c46aa54817063a39dc25bad343d6322e65f8598 (patch) | |
| tree | c0e3902b66baa3c8671b07e6195337d9b85ff572 /src/cmd/compile/internal/ssa/stackalloc.go | |
| parent | 37ddc270ca5360ccde000fd373d49b3450ee8e6e (diff) | |
| download | go-8c46aa54817063a39dc25bad343d6322e65f8598.tar.xz | |
[dev.ssa] cmd/compile/internal/ssa: Handle variables correctly
Use *Node of type ONAME instead of string as the key for variable maps.
This will prevent aliasing between two identically named but
differently scoped variables.
Introduce an Aux value that encodes the offset of a variable
from a base pointer (either global base pointer or stack pointer).
Allow LEAQ and derivatives (MOVQ, etc.) to also have such an Aux field.
Allocate space for AUTO variables in stackalloc.
Change-Id: Ibdccdaea4bbc63a1f4882959ac374f2b467e3acd
Reviewed-on: https://go-review.googlesource.com/11238
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/stackalloc.go')
| -rw-r--r-- | src/cmd/compile/internal/ssa/stackalloc.go | 58 |
1 files changed, 15 insertions, 43 deletions
diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go index e39a3e7a59..85a55ece7c 100644 --- a/src/cmd/compile/internal/ssa/stackalloc.go +++ b/src/cmd/compile/internal/ssa/stackalloc.go @@ -54,7 +54,7 @@ func stackalloc(f *Func) { // v will have been materialized wherever it is needed. continue } - if len(v.Args) == 1 && (v.Args[0].Op == OpFP || v.Args[0].Op == OpSP || v.Args[0].Op == OpGlobal) { + if len(v.Args) == 1 && (v.Args[0].Op == OpSP || v.Args[0].Op == OpSB) { continue } n = align(n, v.Type.Alignment()) @@ -64,54 +64,26 @@ func stackalloc(f *Func) { } } + // Finally, allocate space for all autos that we used + for _, b := range f.Blocks { + for _, v := range b.Values { + s, ok := v.Aux.(*AutoSymbol) + if !ok || s.Offset >= 0 { + continue + } + t := s.Typ + n = align(n, t.Alignment()) + s.Offset = n + n += t.Size() + } + } + n = align(n, f.Config.ptrSize) n += f.Config.ptrSize // space for return address. TODO: arch-dependent f.RegAlloc = home f.FrameSize = n // TODO: share stack slots among noninterfering (& gc type compatible) values - - // adjust all uses of FP to SP now that we have the frame size. - var fp *Value - for _, b := range f.Blocks { - for _, v := range b.Values { - if v.Op == OpFP { - if fp != nil { - b.Fatalf("multiple FP ops: %s %s", fp, v) - } - fp = v - } - for i, a := range v.Args { - if a.Op != OpFP { - continue - } - // TODO: do this with arch-specific rewrite rules somehow? - switch v.Op { - case OpAMD64ADDQ: - // (ADDQ (FP) x) -> (LEAQ [n] (SP) x) - v.Op = OpAMD64LEAQ - v.AuxInt = n - case OpAMD64ADDQconst: - // TODO(matloob): Add LEAQconst op - v.AuxInt = addOff(v.AuxInt, n) - case OpAMD64LEAQ, OpAMD64MOVQload, OpAMD64MOVQstore, OpAMD64MOVLload, OpAMD64MOVLstore, OpAMD64MOVWload, OpAMD64MOVWstore, OpAMD64MOVBload, OpAMD64MOVBstore, OpAMD64MOVQloadidx8: - if v.Op == OpAMD64MOVQloadidx8 && i == 1 { - // Note: we could do it, but it is probably an error - f.Fatalf("can't do FP->SP adjust on index slot of load %s", v.Op) - } - // eg: (MOVQload [c] (FP) mem) -> (MOVQload [c+n] (SP) mem) - v.AuxInt = addOff(v.AuxInt, n) - default: - f.Unimplementedf("can't do FP->SP adjust on %s", v.Op) - // TODO: OpCopy -> ADDQ - } - } - } - } - if fp != nil { - fp.Op = OpSP - home[fp.ID] = ®isters[4] // TODO: arch-dependent - } } // align increases n to the next multiple of a. a must be a power of 2. |
