mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-30 22:20:27 +01:00
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:
parent
b86bf31b05
commit
06fa5d81da
3 changed files with 34 additions and 23 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue