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

NOTE: This is a candidate for the 7.9 branch.
(cherry picked from commit e2301b45c2)
This commit is contained in:
Tom Stellard 2010-11-13 16:57:06 -08:00
parent b86bf31b05
commit 06fa5d81da
3 changed files with 34 additions and 23 deletions

View file

@ -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. */

View file

@ -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

View file

@ -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);