From dee1f2750b544dc2dd109231d5f8347beb142b8d Mon Sep 17 00:00:00 2001 From: Todd Neal Date: Mon, 10 Aug 2015 21:05:35 -0500 Subject: [PATCH] [dev.ssa] cmd/compile/ssa: eliminate Zero with dse Consider OpZero to be a store so it can be eliminated by dse. Change-Id: Idebb6a190657b76966f0c5b20f2ec9f52fe47499 Reviewed-on: https://go-review.googlesource.com/13447 Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/deadstore.go | 20 +++++++++++++++---- .../compile/internal/ssa/deadstore_test.go | 18 +++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/cmd/compile/internal/ssa/deadstore.go b/src/cmd/compile/internal/ssa/deadstore.go index db3808639a..982bd7fa70 100644 --- a/src/cmd/compile/internal/ssa/deadstore.go +++ b/src/cmd/compile/internal/ssa/deadstore.go @@ -30,7 +30,7 @@ func dse(f *Func) { for _, a := range v.Args { if a.Block == b && a.Type.IsMemory() { storeUse.add(a.ID) - if v.Op != OpStore { + if v.Op != OpStore && v.Op != OpZero { // CALL, DUFFCOPY, etc. are both // reads and writes. loadUse.add(a.ID) @@ -77,12 +77,24 @@ func dse(f *Func) { // Clear all shadowed addresses. shadowed.clear() } - if v.Op == OpStore { + if v.Op == OpStore || v.Op == OpZero { if shadowed.contains(v.Args[0].ID) { // Modify store into a copy - v.Op = OpCopy + if v.Op == OpStore { + // store addr value mem + v.SetArgs1(v.Args[2]) + } else { + // zero addr mem + sz := v.Args[0].Type.Elem().Size() + if v.AuxInt != sz { + f.Fatalf("mismatched zero/store sizes: %d and %d [%s]", + v.AuxInt, sz, v.LongString()) + } + v.SetArgs1(v.Args[1]) + } v.Aux = nil - v.SetArgs1(v.Args[2]) + v.AuxInt = 0 + v.Op = OpCopy } else { shadowed.add(v.Args[0].ID) } diff --git a/src/cmd/compile/internal/ssa/deadstore_test.go b/src/cmd/compile/internal/ssa/deadstore_test.go index 8c0a875cad..8d9b4b1298 100644 --- a/src/cmd/compile/internal/ssa/deadstore_test.go +++ b/src/cmd/compile/internal/ssa/deadstore_test.go @@ -4,9 +4,7 @@ package ssa -import ( - "testing" -) +import "testing" func TestDeadStore(t *testing.T) { c := testConfig(t) @@ -18,9 +16,12 @@ func TestDeadStore(t *testing.T) { Valu("v", OpConstBool, TypeBool, 0, true), Valu("addr1", OpAddr, ptrType, 0, nil, "sb"), Valu("addr2", OpAddr, ptrType, 0, nil, "sb"), - Valu("store1", OpStore, TypeMem, 0, nil, "addr1", "v", "start"), + Valu("addr3", OpAddr, ptrType, 0, nil, "sb"), + Valu("zero1", OpZero, TypeMem, 8, nil, "addr3", "start"), + Valu("store1", OpStore, TypeMem, 0, nil, "addr1", "v", "zero1"), Valu("store2", OpStore, TypeMem, 0, nil, "addr2", "v", "store1"), Valu("store3", OpStore, TypeMem, 0, nil, "addr1", "v", "store2"), + Valu("store4", OpStore, TypeMem, 0, nil, "addr3", "v", "store3"), Goto("exit")), Bloc("exit", Exit("store3"))) @@ -29,10 +30,15 @@ func TestDeadStore(t *testing.T) { dse(fun.f) CheckFunc(fun.f) - v := fun.values["store1"] - if v.Op != OpCopy { + v1 := fun.values["store1"] + if v1.Op != OpCopy { t.Errorf("dead store not removed") } + + v2 := fun.values["zero1"] + if v2.Op != OpCopy { + t.Errorf("dead store (zero) not removed") + } } func TestDeadStorePhi(t *testing.T) { // make sure we don't get into an infinite loop with phi values. -- 2.48.1