aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/stackalloc.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2015-06-19 21:02:28 -0700
committerKeith Randall <khr@golang.org>2015-06-25 17:54:18 +0000
commit8c46aa54817063a39dc25bad343d6322e65f8598 (patch)
treec0e3902b66baa3c8671b07e6195337d9b85ff572 /src/cmd/compile/internal/ssa/stackalloc.go
parent37ddc270ca5360ccde000fd373d49b3450ee8e6e (diff)
downloadgo-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.go58
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] = &registers[4] // TODO: arch-dependent
- }
}
// align increases n to the next multiple of a. a must be a power of 2.