]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/5g: fix out of registers in nested calls, add compiler torture test.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Fri, 5 Oct 2012 21:30:49 +0000 (23:30 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Fri, 5 Oct 2012 21:30:49 +0000 (23:30 +0200)
R=golang-dev, dave, daniel.morsing, rsc
CC=golang-dev, remy
https://golang.org/cl/6586072

src/cmd/5g/cgen.c
test/torture.go [new file with mode: 0644]

index 79efab4947948f62f5093a31947e339ebeaa1c6c..eaa813fcf7fc1a17c2a6938deaff541a45707d0a 100644 (file)
@@ -16,7 +16,7 @@ cgen(Node *n, Node *res)
 {
        Node *nl, *nr, *r;
        Node n1, n2, n3, f0, f1;
-       int a, w;
+       int a, w, rg;
        Prog *p1, *p2, *p3;
        Addr addr;
 
@@ -406,7 +406,22 @@ cgen(Node *n, Node *res)
                break;
 
        case OCALLMETH:
-               cgen_callmeth(n, 0);
+       case OCALLFUNC:
+               // Release res so that it is available for cgen_call.
+               // Pick it up again after the call.
+               rg = -1;
+               if(n->ullman >= UINF) {
+                       if(res->op == OREGISTER || res->op == OINDREG) {
+                               rg = res->val.u.reg;
+                               reg[rg]--;
+                       }
+               }
+               if(n->op == OCALLMETH)
+                       cgen_callmeth(n, 0);
+               else
+                       cgen_call(n, 0);
+               if(rg >= 0)
+                       reg[rg]++;
                cgen_callret(n, res);
                break;
 
@@ -415,11 +430,6 @@ cgen(Node *n, Node *res)
                cgen_callret(n, res);
                break;
 
-       case OCALLFUNC:
-               cgen_call(n, 0);
-               cgen_callret(n, res);
-               break;
-
        case OMOD:
        case ODIV:
                a = optoas(n->op, nl->type);
diff --git a/test/torture.go b/test/torture.go
new file mode 100644 (file)
index 0000000..fdc5dda
--- /dev/null
@@ -0,0 +1,171 @@
+// compile
+
+// Copyright 2012 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.
+
+// Various tests for expressions with high complexity.
+
+package main
+
+// Concatenate 16 4-bit integers into a 64-bit number.
+func concat(s *[16]byte) uint64 {
+       r := (((((((((((((((uint64(s[0])<<4|
+               uint64(s[1]))<<4|
+               uint64(s[2]))<<4|
+               uint64(s[3]))<<4|
+               uint64(s[4]))<<4|
+               uint64(s[5]))<<4|
+               uint64(s[6]))<<4|
+               uint64(s[7]))<<4|
+               uint64(s[8]))<<4|
+               uint64(s[9]))<<4|
+               uint64(s[10]))<<4|
+               uint64(s[11]))<<4|
+               uint64(s[12]))<<4|
+               uint64(s[13]))<<4|
+               uint64(s[14]))<<4 |
+               uint64(s[15]))
+       return r
+}
+
+// Compute the determinant of a 4x4-matrix by the sum
+// over all index permutations.
+func determinant(m [4][4]float64) float64 {
+       return m[0][0]*m[1][1]*m[2][2]*m[3][3] -
+               m[0][0]*m[1][1]*m[2][3]*m[3][2] -
+               m[0][0]*m[1][2]*m[2][1]*m[3][3] +
+               m[0][0]*m[1][2]*m[2][3]*m[3][1] +
+               m[0][0]*m[1][3]*m[2][1]*m[3][2] -
+               m[0][0]*m[1][3]*m[2][2]*m[3][1] -
+               m[0][1]*m[1][0]*m[2][2]*m[3][3] +
+               m[0][1]*m[1][0]*m[2][3]*m[3][2] +
+               m[0][1]*m[1][2]*m[2][0]*m[3][3] -
+               m[0][1]*m[1][2]*m[2][3]*m[3][0] -
+               m[0][1]*m[1][3]*m[2][0]*m[3][2] +
+               m[0][1]*m[1][3]*m[2][2]*m[3][0] +
+               m[0][2]*m[1][0]*m[2][1]*m[3][3] -
+               m[0][2]*m[1][0]*m[2][3]*m[3][1] -
+               m[0][2]*m[1][1]*m[2][0]*m[3][3] +
+               m[0][2]*m[1][1]*m[2][3]*m[3][0] +
+               m[0][2]*m[1][3]*m[2][0]*m[3][1] -
+               m[0][2]*m[1][3]*m[2][1]*m[3][0] -
+               m[0][3]*m[1][0]*m[2][1]*m[3][2] +
+               m[0][3]*m[1][0]*m[2][2]*m[3][1] +
+               m[0][3]*m[1][1]*m[2][0]*m[3][2] -
+               m[0][3]*m[1][1]*m[2][2]*m[3][0] -
+               m[0][3]*m[1][2]*m[2][0]*m[3][1] +
+               m[0][3]*m[1][2]*m[2][1]*m[3][0]
+}
+
+// A right-leaning tree of byte multiplications.
+func righttree(a, b, c, d uint8) uint8 {
+       return a * (b * (c * (d *
+               (a * (b * (c * (d *
+                       (a * (b * (c * (d *
+                               (a * (b * (c * (d *
+                                       (a * (b * (c * (d *
+                                               a * (b * (c * d)))))))))))))))))))))
+
+}
+
+// A left-leaning tree of byte multiplications.
+func lefttree(a, b, c, d uint8) uint8 {
+       return ((((((((((((((((((a * b) * c) * d *
+               a) * b) * c) * d *
+               a) * b) * c) * d *
+               a) * b) * c) * d *
+               a) * b) * c) * d *
+               a) * b) * c) * d)
+}
+
+type T struct {
+       Next I
+}
+
+type I interface{}
+
+// A chains of type assertions.
+func ChainT(t *T) *T {
+       return t.
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T).
+               Next.(*T)
+}
+
+type U struct {
+       Children []J
+}
+
+func (u *U) Child(n int) J { return u.Children[n] }
+
+type J interface {
+       Child(n int) J
+}
+
+func ChainUAssert(u *U) *U {
+       return u.Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U).
+               Child(0).(*U)
+}
+
+func ChainUNoAssert(u *U) *U {
+       return u.Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).
+               Child(0).(*U)
+}