]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove stale register use array
authorKeith Randall <khr@golang.org>
Thu, 13 Aug 2015 19:25:19 +0000 (12:25 -0700)
committerRuss Cox <rsc@golang.org>
Sat, 15 Aug 2015 17:37:14 +0000 (17:37 +0000)
The reg[] array in .../gc is where truth lies.  The copy in .../ARCH
is incorrect as it is mostly not updated to reflect regalloc decisions.

This bug was introduced in the rewrite
https://go-review.googlesource.com/#/c/7853/.  The new reg[] array was
introduced in .../gc but not all of the uses were removed in the
.../ARCH directories.

Fixes #12133

Change-Id: I6364fc403cdab92d802d17f2913ba1607734037c
Reviewed-on: https://go-review.googlesource.com/13630
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/compile/internal/amd64/ggen.go
src/cmd/compile/internal/amd64/reg.go
src/cmd/compile/internal/arm64/ggen.go
src/cmd/compile/internal/arm64/reg.go
src/cmd/compile/internal/gc/gsubr.go
src/cmd/compile/internal/x86/ggen.go
src/cmd/compile/internal/x86/reg.go
test/fixedbugs/issue12133.go [new file with mode: 0644]

index 6425633818ce4552736444c374a6c6221fa4b492..65cf6947bed6db24ae4a934b1ddd40c4c07384aa 100644 (file)
@@ -306,7 +306,7 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) {
  * known to be dead.
  */
 func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
-       r := reg[dr]
+       r := uint8(gc.GetReg(dr))
 
        // save current ax and dx if they are live
        // and not the destination
@@ -319,14 +319,14 @@ func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
                gmove(x, oldx)
                x.Type = t
                oldx.Etype = r // squirrel away old r value
-               reg[dr] = 1
+               gc.SetReg(dr, 1)
        }
 }
 
 func restx(x *gc.Node, oldx *gc.Node) {
        if oldx.Op != 0 {
                x.Type = gc.Types[gc.TINT64]
-               reg[x.Reg] = oldx.Etype
+               gc.SetReg(int(x.Reg), int(oldx.Etype))
                gmove(oldx, x)
                gc.Regfree(oldx)
        }
@@ -411,7 +411,7 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
                nr = &n5
        }
 
-       rcx := int(reg[x86.REG_CX])
+       rcx := gc.GetReg(x86.REG_CX)
        var n1 gc.Node
        gc.Nodreg(&n1, gc.Types[gc.TUINT32], x86.REG_CX)
 
index 7d4f40641de72f14b7f5d2c1013ad446516b52c3..8fab6399b1d88c86a08ca92b980eade55f7b0b95 100644 (file)
@@ -40,8 +40,6 @@ const (
        NREGVAR = 32
 )
 
-var reg [x86.MAXREG]uint8
-
 var regname = []string{
        ".AX",
        ".CX",
index 6b0b40efbdb08b5b20f5df217cbafb73279dd6b3..ff223087a105de290199bba7ee878c137fcd2fd2 100644 (file)
@@ -418,7 +418,7 @@ func clearfat(nl *gc.Node) {
        c := uint64(w % 8) // bytes
        q := uint64(w / 8) // dwords
 
-       if reg[arm64.REGRT1-arm64.REG_R0] > 0 {
+       if gc.GetReg(arm64.REGRT1) > 0 {
                gc.Fatal("R%d in use during clearfat", arm64.REGRT1-arm64.REG_R0)
        }
 
@@ -426,7 +426,7 @@ func clearfat(nl *gc.Node) {
        gc.Nodreg(&r0, gc.Types[gc.TUINT64], arm64.REGZERO)
        var dst gc.Node
        gc.Nodreg(&dst, gc.Types[gc.Tptr], arm64.REGRT1)
-       reg[arm64.REGRT1-arm64.REG_R0]++
+       gc.SetReg(arm64.REGRT1, gc.GetReg(arm64.REGRT1)+1)
        gc.Agen(nl, &dst)
 
        var boff uint64
@@ -485,7 +485,7 @@ func clearfat(nl *gc.Node) {
                p.To.Offset = int64(t + boff)
        }
 
-       reg[arm64.REGRT1-arm64.REG_R0]--
+       gc.SetReg(arm64.REGRT1, gc.GetReg(arm64.REGRT1)-1)
 }
 
 // Called after regopt and peep have run.
index 7bc756b7bf0361112fc7bcf409fdd39422b1b750..b84359a63764297bab882636f1bb71798a2ef89f 100644 (file)
@@ -39,8 +39,6 @@ const (
        NREGVAR = 64 /* 32 general + 32 floating */
 )
 
-var reg [arm64.NREG + arm64.NFREG]uint8
-
 var regname = []string{
        ".R0",
        ".R1",
index 14dc927442cce67d48321cc88dd78abb41978bfa..2c575f3d789a21b47379d15fb5fededde903f5fe 100644 (file)
@@ -602,6 +602,13 @@ func unpatch(p *obj.Prog) *obj.Prog {
 var reg [100]int       // count of references to reg
 var regstk [100][]byte // allocation sites, when -v is given
 
+func GetReg(r int) int {
+       return reg[r-Thearch.REGMIN]
+}
+func SetReg(r, v int) {
+       reg[r-Thearch.REGMIN] = v
+}
+
 func ginit() {
        for r := range reg {
                reg[r] = 1
index dabc139f302030e755c0775d39e58ab567534db0..ae9881d2739f7d476f9e1ba3b47921ad398a48ae 100644 (file)
@@ -319,7 +319,7 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node, ax *gc.Node, dx *gc.N
 }
 
 func savex(dr int, x *gc.Node, oldx *gc.Node, res *gc.Node, t *gc.Type) {
-       r := int(reg[dr])
+       r := gc.GetReg(dr)
        gc.Nodreg(x, gc.Types[gc.TINT32], dr)
 
        // save current ax and dx if they are live
@@ -408,7 +408,7 @@ func cgen_shift(op int, bounded bool, nl *gc.Node, nr *gc.Node, res *gc.Node) {
        var oldcx gc.Node
        var cx gc.Node
        gc.Nodreg(&cx, gc.Types[gc.TUINT32], x86.REG_CX)
-       if reg[x86.REG_CX] > 1 && !gc.Samereg(&cx, res) {
+       if gc.GetReg(x86.REG_CX) > 1 && !gc.Samereg(&cx, res) {
                gc.Tempname(&oldcx, gc.Types[gc.TUINT32])
                gmove(&cx, &oldcx)
        }
index 8c97171e47dfe8e374360afd9d5c5c2a0077f77f..b3a5fdf4e054385ba21412b74efdd7265ae42d93 100644 (file)
@@ -37,8 +37,6 @@ const (
        NREGVAR = 16 /* 8 integer + 8 floating */
 )
 
-var reg [x86.MAXREG]uint8
-
 var regname = []string{
        ".ax",
        ".cx",
diff --git a/test/fixedbugs/issue12133.go b/test/fixedbugs/issue12133.go
new file mode 100644 (file)
index 0000000..0b66c56
--- /dev/null
@@ -0,0 +1,26 @@
+// run
+
+// Copyright 2015 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 12133.  The CX register was getting clobbered
+// because we did not keep track of its allocation correctly.
+
+package main
+
+import "fmt"
+
+func main() {
+       want := uint(48)
+       got := f1(48)
+       if got != want {
+               fmt.Println("got", got, ", wanted", want)
+               panic("bad")
+       }
+}
+func f1(v1 uint) uint {
+       switch {
+       } // prevent inlining
+       return v1 >> ((1 >> v1) + (1 >> v1))
+}