From ca5da31f83517780893423e46665d48149e545ee Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 10 Feb 2012 22:19:34 -0500 Subject: [PATCH] 6g: fix out of registers bug Fix it twice: reuse registers more aggressively in cgen abop, and also release R14 and R15, which are no longer m and g. Fixes #2669. R=ken2 CC=golang-dev https://golang.org/cl/5655056 --- src/cmd/6g/cgen.c | 4 ++-- src/cmd/6g/gsubr.c | 24 +++++++++++++----------- test/fixedbugs/bug410.go | 24 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 13 deletions(-) create mode 100644 test/fixedbugs/bug410.go diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c index fd84932314..2521b02d23 100644 --- a/src/cmd/6g/cgen.c +++ b/src/cmd/6g/cgen.c @@ -387,9 +387,9 @@ abop: // asymmetric binary regalloc(&n2, nr->type, N); cgen(nr, &n2); } else { - regalloc(&n2, nr->type, N); + regalloc(&n2, nr->type, res); cgen(nr, &n2); - regalloc(&n1, nl->type, res); + regalloc(&n1, nl->type, N); cgen(nl, &n1); } gins(a, &n2, &n1); diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index cf00c3c494..22fea9b166 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -287,8 +287,6 @@ static int resvd[] = D_CX, // for shift D_DX, // for divide D_SP, // for stack - D_R14, // reserved for m - D_R15, // reserved for u }; void @@ -340,6 +338,8 @@ anyregalloc(void) return 0; } +static uintptr regpc[D_R15+1 - D_AX]; + /* * allocate register of type t, leave in n. * if o != N, o is desired fixed register. @@ -372,11 +372,15 @@ regalloc(Node *n, Type *t, Node *o) goto out; } for(i=D_AX; i<=D_R15; i++) - if(reg[i] == 0) + if(reg[i] == 0) { + regpc[i-D_AX] = (uintptr)getcallerpc(&n); goto out; + } - yyerror("out of fixed registers"); - goto err; + flusherrors(); + for(i=0; i+D_AX<=D_R15; i++) + print("%d %p\n", i, regpc[i]); + fatal("out of fixed registers"); case TFLOAT32: case TFLOAT64: @@ -388,18 +392,14 @@ regalloc(Node *n, Type *t, Node *o) for(i=D_X0; i<=D_X7; i++) if(reg[i] == 0) goto out; - yyerror("out of floating registers"); - goto err; + fatal("out of floating registers"); case TCOMPLEX64: case TCOMPLEX128: tempname(n, t); return; } - yyerror("regalloc: unknown type %T", t); - -err: - nodreg(n, t, 0); + fatal("regalloc: unknown type %T", t); return; out: @@ -424,6 +424,8 @@ regfree(Node *n) if(reg[i] <= 0) fatal("regfree: reg not allocated"); reg[i]--; + if(reg[i] == 0 && D_AX <= i && i <= D_R15) + regpc[i - D_AX] = 0; } /* diff --git a/test/fixedbugs/bug410.go b/test/fixedbugs/bug410.go new file mode 100644 index 0000000000..6eee6cfd48 --- /dev/null +++ b/test/fixedbugs/bug410.go @@ -0,0 +1,24 @@ +// $G $D/$F.go + +// 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. + +// Used to run 6g out of registers. Issue 2669. + +package p + +type y struct { + num int +} + +func zzz () { + k := make([]byte, 10) + arr := make ([]*y, 0) + for s := range arr { + x := make([]byte, 10) + for i := 0; i < 100 ; i++ { + x[i] ^= k[i-arr[s].num%0] + } + } +} -- 2.50.0