package ssa // stackalloc allocates storage in the stack frame for // all Values that did not get a register. func stackalloc(f *Func) { home := f.RegAlloc var n int64 = 8 // 8 = space for return address. TODO: arch-dependent // Assign stack locations to phis first, because we // must also assign the same locations to the phi copies // introduced during regalloc. for _, b := range f.Blocks { for _, v := range b.Values { if v.Op != OpPhi { continue } n += v.Type.Size() // a := v.Type.Align() // n = (n + a - 1) / a * a TODO loc := &LocalSlot{n} home = setloc(home, v, loc) for _, w := range v.Args { home = setloc(home, w, loc) } } } // Now do all other unassigned values. for _, b := range f.Blocks { for _, v := range b.Values { if v.ID < ID(len(home)) && home[v.ID] != nil { continue } if v.Type.IsMemory() { // TODO: only "regallocable" types continue } if v.Op == OpConst { // don't allocate space for OpConsts. They should // have been rematerialized everywhere. // TODO: is this the right thing to do? continue } // a := v.Type.Align() // n = (n + a - 1) / a * a TODO n += v.Type.Size() loc := &LocalSlot{n} home = setloc(home, v, loc) } } f.RegAlloc = home // TODO: share stack slots among noninterfering (& gc type compatible) values // TODO: align final n // TODO: compute total frame size: n + max paramout space // TODO: save total size somewhere }