Commit c31b6dd0 authored by Daniel Morsing's avatar Daniel Morsing

[dev.ssa] initial implementation of PAUTO|PHEAP variables

Call to the runtime to generate escaping variables and use the returned
address when accessing these variables.

Fix a couple of errors on the way. The rule for CALLstatic was missed
during the Aux refactor and OCONVNOP wasn't converted.

Change-Id: I2096beff92cca92d648bfb6e8ec0b120f02f44af
Reviewed-on: https://go-review.googlesource.com/11072Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent ea5cd686
...@@ -226,8 +226,23 @@ func (s *state) stmt(n *Node) { ...@@ -226,8 +226,23 @@ func (s *state) stmt(n *Node) {
s.stmtList(n.List) s.stmtList(n.List)
case ODCL: case ODCL:
// TODO: old gen pass uses dcl node as the point where if n.Left.Class&PHEAP == 0 {
// escaping variables' new functions are called. Do that here return
}
if compiling_runtime != 0 {
log.Fatalf("%v escapes to heap, not allowed in runtime.", n)
}
// TODO: the old pass hides the details of PHEAP
// variables behind ONAME nodes. Figure out if it's better
// to rewrite the tree and make the heapaddr construct explicit
// or to keep this detail hidden behind the scenes.
palloc := prealloc[n.Left]
if palloc == nil {
palloc = callnew(n.Left.Type)
prealloc[n.Left] = palloc
}
s.assign(OAS, n.Left.Name.Heapaddr, palloc)
case OLABEL, OGOTO: case OLABEL, OGOTO:
// get block at label, or make one // get block at label, or make one
...@@ -247,32 +262,8 @@ func (s *state) stmt(n *Node) { ...@@ -247,32 +262,8 @@ func (s *state) stmt(n *Node) {
} }
case OAS, OASWB: case OAS, OASWB:
// TODO: do write barrier s.assign(n.Op, n.Left, n.Right)
var val *ssa.Value
if n.Right == nil {
// n.Right == nil means use the zero value of the assigned type.
t := n.Left.Type
switch {
case t.IsString():
val = s.entryNewValue0(ssa.OpConst, n.Left.Type)
case t.IsInteger():
val = s.entryNewValue0(ssa.OpConst, n.Left.Type)
case t.IsBoolean():
val = s.entryNewValue0A(ssa.OpConst, n.Left.Type, false) // TODO: store bools as 0/1 in AuxInt?
default:
log.Fatalf("zero for type %v not implemented", t)
}
} else {
val = s.expr(n.Right)
}
if n.Left.Op == ONAME && canSSA(n.Left) {
// Update variable assignment.
s.vars[n.Left.Sym.Name] = val
return
}
// not ssa-able. Treat as a store.
addr := s.addr(n.Left)
s.vars[".mem"] = s.newValue3(ssa.OpStore, ssa.TypeMem, addr, val, s.mem())
case OIF: case OIF:
cond := s.expr(n.Left) cond := s.expr(n.Left)
b := s.endBlock() b := s.endBlock()
...@@ -478,6 +469,36 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -478,6 +469,36 @@ func (s *state) expr(n *Node) *ssa.Value {
} }
} }
func (s *state) assign(op uint8, left *Node, right *Node) {
// TODO: do write barrier
// if op == OASWB
var val *ssa.Value
if right == nil {
// right == nil means use the zero value of the assigned type.
t := left.Type
switch {
case t.IsString():
val = s.entryNewValue0(ssa.OpConst, left.Type)
case t.IsInteger():
val = s.entryNewValue0(ssa.OpConst, left.Type)
case t.IsBoolean():
val = s.entryNewValue0A(ssa.OpConst, left.Type, false) // TODO: store bools as 0/1 in AuxInt?
default:
log.Fatalf("zero for type %v not implemented", t)
}
} else {
val = s.expr(right)
}
if left.Op == ONAME && canSSA(left) {
// Update variable assignment.
s.vars[left.Sym.Name] = val
return
}
// not ssa-able. Treat as a store.
addr := s.addr(left)
s.vars[".mem"] = s.newValue3(ssa.OpStore, ssa.TypeMem, addr, val, s.mem())
}
// addr converts the address of the expression n to SSA, adds it to s and returns the SSA result. // addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
func (s *state) addr(n *Node) *ssa.Value { func (s *state) addr(n *Node) *ssa.Value {
switch n.Op { switch n.Op {
...@@ -489,6 +510,8 @@ func (s *state) addr(n *Node) *ssa.Value { ...@@ -489,6 +510,8 @@ func (s *state) addr(n *Node) *ssa.Value {
case PPARAMOUT: case PPARAMOUT:
// store to parameter slot // store to parameter slot
return s.entryNewValue1I(ssa.OpOffPtr, Ptrto(n.Type), n.Xoffset, s.fp) return s.entryNewValue1I(ssa.OpOffPtr, Ptrto(n.Type), n.Xoffset, s.fp)
case PAUTO | PHEAP:
return s.expr(n.Name.Heapaddr)
default: default:
// TODO: address of locals // TODO: address of locals
log.Fatalf("variable address of %v not implemented", n) log.Fatalf("variable address of %v not implemented", n)
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
(If (SETB cmp) yes no) -> (ULT cmp yes no) (If (SETB cmp) yes no) -> (ULT cmp yes no)
(If cond yes no) && cond.Op == OpAMD64MOVBload -> (NE (TESTB <TypeFlags> cond cond) yes no) (If cond yes no) && cond.Op == OpAMD64MOVBload -> (NE (TESTB <TypeFlags> cond cond) yes no)
(StaticCall [target] mem) -> (CALLstatic [target] mem) (StaticCall {target} mem) -> (CALLstatic {target} mem)
(ClosureCall entry closure mem) -> (CALLclosure entry closure mem) (ClosureCall entry closure mem) -> (CALLclosure entry closure mem)
// Rules below here apply some simple optimizations after lowering. // Rules below here apply some simple optimizations after lowering.
......
...@@ -1093,22 +1093,22 @@ func rewriteValueAMD64(v *Value, config *Config) bool { ...@@ -1093,22 +1093,22 @@ func rewriteValueAMD64(v *Value, config *Config) bool {
end78e66b6fc298684ff4ac8aec5ce873c9: end78e66b6fc298684ff4ac8aec5ce873c9:
; ;
case OpStaticCall: case OpStaticCall:
// match: (StaticCall [target] mem) // match: (StaticCall {target} mem)
// cond: // cond:
// result: (CALLstatic [target] mem) // result: (CALLstatic {target} mem)
{ {
target := v.AuxInt target := v.Aux
mem := v.Args[0] mem := v.Args[0]
v.Op = OpAMD64CALLstatic v.Op = OpAMD64CALLstatic
v.AuxInt = 0 v.AuxInt = 0
v.Aux = nil v.Aux = nil
v.resetArgs() v.resetArgs()
v.AuxInt = target v.Aux = target
v.AddArg(mem) v.AddArg(mem)
return true return true
} }
goto endcf02eb60d90086f6c42bfdc5842b145d goto end1948857a7cfc2a4f905045e58d3b9ec1
endcf02eb60d90086f6c42bfdc5842b145d: end1948857a7cfc2a4f905045e58d3b9ec1:
; ;
case OpStore: case OpStore:
// match: (Store ptr val mem) // match: (Store ptr val mem)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment