Mesa (7.9): r300/compiler: Fix register allocator's handling of loops

Tom Stellard tstellar at kemper.freedesktop.org
Mon Nov 22 20:08:31 UTC 2010


Module: Mesa
Branch: 7.9
Commit: 06fa5d81da6d58fbd7cfa3c74da4e37f8e48e845
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=06fa5d81da6d58fbd7cfa3c74da4e37f8e48e845

Author: Tom Stellard <tstellar at gmail.com>
Date:   Sat Nov 13 16:57:06 2010 -0800

r300/compiler: Fix register allocator's handling of loops

NOTE: This is a candidate for the 7.9 branch.
(cherry picked from commit e2301b45c288cdbd4e763dfbc698d709045f2df5)

---

 src/glsl/glsl_parser.cpp                           |   20 ++++++------
 src/glsl/glsl_parser.h                             |    6 ++--
 .../dri/r300/compiler/radeon_pair_regalloc.c       |   31 +++++++++++++------
 3 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/src/glsl/glsl_parser.cpp b/src/glsl/glsl_parser.cpp
index 301c221..ad99eee 100644
--- a/src/glsl/glsl_parser.cpp
+++ b/src/glsl/glsl_parser.cpp
@@ -1,9 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.4.3.  */
+/* A Bison parser, made by GNU Bison 2.4.2.  */
 
 /* Skeleton implementation for Bison's Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2009, 2010 Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
+   Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -45,7 +45,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.3"
+#define YYBISON_VERSION "2.4.2"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -2621,7 +2621,7 @@ YYLTYPE yylloc;
     YYLTYPE *yylsp;
 
     /* The locations where the error started and ended.  */
-    YYLTYPE yyerror_range[3];
+    YYLTYPE yyerror_range[2];
 
     YYSIZE_T yystacksize;
 
@@ -5084,7 +5084,7 @@ yyerrlab:
 #endif
     }
 
-  yyerror_range[1] = yylloc;
+  yyerror_range[0] = yylloc;
 
   if (yyerrstatus == 3)
     {
@@ -5121,7 +5121,7 @@ yyerrorlab:
   if (/*CONSTCOND*/ 0)
      goto yyerrorlab;
 
-  yyerror_range[1] = yylsp[1-yylen];
+  yyerror_range[0] = yylsp[1-yylen];
   /* Do not reclaim the symbols of the rule which action triggered
      this YYERROR.  */
   YYPOPSTACK (yylen);
@@ -5155,7 +5155,7 @@ yyerrlab1:
       if (yyssp == yyss)
 	YYABORT;
 
-      yyerror_range[1] = *yylsp;
+      yyerror_range[0] = *yylsp;
       yydestruct ("Error: popping",
 		  yystos[yystate], yyvsp, yylsp, state);
       YYPOPSTACK (1);
@@ -5165,10 +5165,10 @@ yyerrlab1:
 
   *++yyvsp = yylval;
 
-  yyerror_range[2] = yylloc;
+  yyerror_range[1] = yylloc;
   /* Using YYLLOC is tempting, but would change the location of
      the lookahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
   *++yylsp = yyloc;
 
   /* Shift the error token.  */
diff --git a/src/glsl/glsl_parser.h b/src/glsl/glsl_parser.h
index 4a78037..266a4a2 100644
--- a/src/glsl/glsl_parser.h
+++ b/src/glsl/glsl_parser.h
@@ -1,9 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.4.3.  */
+/* A Bison parser, made by GNU Bison 2.4.2.  */
 
 /* Skeleton interface for Bison's Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2009, 2010 Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
+   Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
index c738455..126b50b 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
@@ -66,10 +66,13 @@ struct regalloc_state {
 	struct hardware_register * HwTemporary;
 	unsigned int NumHwTemporaries;
 	/**
-	 * If an instruction is inside of a loop, end_loop will be the
-	 * IP of the ENDLOOP instruction, otherwise end_loop will be 0
+	 * If an instruction is inside of a loop, EndLoop will be the
+	 * IP of the ENDLOOP instruction, and BeginLoop will be the IP
+	 * of the BGNLOOP instruction.  Otherwise, EndLoop and BeginLoop
+	 * will be -1.
 	 */
-	int end_loop;
+	int EndLoop;
+	int BeginLoop;
 };
 
 static void print_live_intervals(struct live_intervals * src)
@@ -180,11 +183,13 @@ static void scan_callback(void * data, struct rc_instruction * inst,
 		reg->Used = 1;
 		if (file == RC_FILE_INPUT)
 			reg->Live.Start = -1;
+		else if (s->BeginLoop >= 0)
+			reg->Live.Start = s->BeginLoop;
 		else
 			reg->Live.Start = inst->IP;
 		reg->Live.End = inst->IP;
-	} else if (s->end_loop)
-		reg->Live.End = s->end_loop;
+	} else if (s->EndLoop >= 0)
+		reg->Live.End = s->EndLoop;
 	else if (inst->IP > reg->Live.End)
 		reg->Live.End = inst->IP;
 }
@@ -195,6 +200,8 @@ static void compute_live_intervals(struct radeon_compiler *c,
 	memset(s, 0, sizeof(*s));
 	s->C = c;
 	s->NumHwTemporaries = c->max_temp_regs;
+	s->BeginLoop = -1;
+	s->EndLoop = -1;
 	s->HwTemporary =
 		memory_pool_malloc(&c->Pool,
 				   s->NumHwTemporaries * sizeof(struct hardware_register));
@@ -207,8 +214,10 @@ static void compute_live_intervals(struct radeon_compiler *c,
 	    inst = inst->Next) {
 
 		/* For all instructions inside of a loop, the ENDLOOP
-		 * instruction is used as the end of the live interval. */
-		if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && !s->end_loop) {
+		 * instruction is used as the end of the live interval and
+		 * the BGNLOOP instruction is used as the beginning. */
+		if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && s->EndLoop < 0) {
+			s->BeginLoop = inst->IP;
 			int loops = 1;
 			struct rc_instruction * tmp;
 			for(tmp = inst->Next;
@@ -219,15 +228,17 @@ static void compute_live_intervals(struct radeon_compiler *c,
 				} else if (tmp->U.I.Opcode
 							== RC_OPCODE_ENDLOOP) {
 					if(!--loops) {
-						s->end_loop = tmp->IP;
+						s->EndLoop = tmp->IP;
 						break;
 					}
 				}
 			}
 		}
 
-		if (inst->IP == s->end_loop)
-			s->end_loop = 0;
+		if (inst->IP == s->EndLoop) {
+			s->EndLoop = -1;
+			s->BeginLoop = -1;
+		}
 
 		rc_for_all_reads_mask(inst, scan_callback, s);
 		rc_for_all_writes_mask(inst, scan_callback, s);




More information about the mesa-commit mailing list