1
0
mirror of https://github.com/golang/go synced 2024-11-26 10:08:23 -07:00

[dev.regabi] cmd/compile: cleanup for concrete types - ssa

An automated rewrite will add concrete type assertions after
a test of n.Op(), when n can be safely type-asserted
(meaning, n is not reassigned a different type, n is not reassigned
and then used outside the scope of the type assertion,
and so on).

This sequence of CLs handles the code that the automated
rewrite does not: adding specific types to function arguments,
adjusting code not to call n.Left() etc when n may have multiple
representations, and so on.

This CL focuses on ssa.go.

Passes buildall w/ toolstash -cmp.

Change-Id: Iefacc7104dd9469e3c574149791ab0bff29f7fee
Reviewed-on: https://go-review.googlesource.com/c/go/+/277923
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-12-10 18:45:58 -05:00
parent bf9bbbd6ed
commit 846740c17f
5 changed files with 229 additions and 169 deletions

View File

@ -335,7 +335,7 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
} }
} }
if isIntrinsicCall(n) { if isIntrinsicCall(n.(*ir.CallExpr)) {
// Treat like any other node. // Treat like any other node.
break break
} }
@ -583,7 +583,7 @@ func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.No
if base.Flag.LowerM > 3 { if base.Flag.LowerM > 3 {
fmt.Printf("%v:call to func %+v\n", ir.Line(n), n.Left()) fmt.Printf("%v:call to func %+v\n", ir.Line(n), n.Left())
} }
if isIntrinsicCall(n) { if isIntrinsicCall(n.(*ir.CallExpr)) {
break break
} }
if fn := inlCallee(n.Left()); fn != nil && fn.Inl != nil { if fn := inlCallee(n.Left()); fn != nil && fn.Inl != nil {

View File

@ -254,7 +254,9 @@ func (s *phiState) insertVarPhis(n int, var_ ir.Node, defs []*ssa.Block, typ *ty
hasPhi.add(c.ID) hasPhi.add(c.ID)
v := c.NewValue0I(currentRoot.Pos, ssa.OpPhi, typ, int64(n)) // TODO: line number right? v := c.NewValue0I(currentRoot.Pos, ssa.OpPhi, typ, int64(n)) // TODO: line number right?
// Note: we store the variable number in the phi's AuxInt field. Used temporarily by phi building. // Note: we store the variable number in the phi's AuxInt field. Used temporarily by phi building.
s.s.addNamedValue(var_, v) if var_.Op() == ir.ONAME {
s.s.addNamedValue(var_.(*ir.Name), v)
}
for range c.Preds { for range c.Preds {
v.AddArg(s.placeholder) // Actual args will be filled in by resolveFwdRefs. v.AddArg(s.placeholder) // Actual args will be filled in by resolveFwdRefs.
} }
@ -546,7 +548,9 @@ func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t *types.Type, var_ ir.
// Generate a FwdRef for the variable and return that. // Generate a FwdRef for the variable and return that.
v := b.NewValue0A(line, ssa.OpFwdRef, t, FwdRefAux{N: var_}) v := b.NewValue0A(line, ssa.OpFwdRef, t, FwdRefAux{N: var_})
s.defvars[b.ID][var_] = v s.defvars[b.ID][var_] = v
s.s.addNamedValue(var_, v) if var_.Op() == ir.ONAME {
s.s.addNamedValue(var_.(*ir.Name), v)
}
s.fwdrefs = append(s.fwdrefs, v) s.fwdrefs = append(s.fwdrefs, v)
return v return v
} }

View File

@ -206,8 +206,12 @@ type progeffectscache struct {
// nor do we care about non-local variables, // nor do we care about non-local variables,
// nor do we care about empty structs (handled by the pointer check), // nor do we care about empty structs (handled by the pointer check),
// nor do we care about the fake PAUTOHEAP variables. // nor do we care about the fake PAUTOHEAP variables.
func livenessShouldTrack(n ir.Node) bool { func livenessShouldTrack(nn ir.Node) bool {
return n.Op() == ir.ONAME && (n.Class() == ir.PAUTO || n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Type().HasPointers() if nn.Op() != ir.ONAME {
return false
}
n := nn.(*ir.Name)
return (n.Class() == ir.PAUTO || n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Type().HasPointers()
} }
// getvariables returns the list of on-stack variables that we need to track // getvariables returns the list of on-stack variables that we need to track
@ -1165,7 +1169,7 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
// Size args bitmaps to be just large enough to hold the largest pointer. // Size args bitmaps to be just large enough to hold the largest pointer.
// First, find the largest Xoffset node we care about. // First, find the largest Xoffset node we care about.
// (Nodes without pointers aren't in lv.vars; see livenessShouldTrack.) // (Nodes without pointers aren't in lv.vars; see livenessShouldTrack.)
var maxArgNode ir.Node var maxArgNode *ir.Name
for _, n := range lv.vars { for _, n := range lv.vars {
switch n.Class() { switch n.Class() {
case ir.PPARAM, ir.PPARAMOUT: case ir.PPARAM, ir.PPARAMOUT:

File diff suppressed because it is too large Load Diff

View File

@ -743,7 +743,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
walkexprlistsafe(n.List().Slice(), init) walkexprlistsafe(n.List().Slice(), init)
r = walkexpr(r, init) r = walkexpr(r, init)
if isIntrinsicCall(r) { if isIntrinsicCall(r.(*ir.CallExpr)) {
n.PtrRlist().Set1(r) n.PtrRlist().Set1(r)
return n return n
} }