mesa: refactor code and make _mesa_find_temp_intervals() public

This commit is contained in:
Brian Paul 2009-04-24 16:28:36 -06:00
parent 027ed1b505
commit 7da3f9403b
2 changed files with 144 additions and 22 deletions

View file

@ -547,15 +547,13 @@ update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic)
/**
* Find the live intervals for each temporary register in the program.
* For register R, the interval [A,B] indicates that R is referenced
* from instruction A through instruction B.
* Special consideration is needed for loops and subroutines.
* \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason
* Find first/last instruction that references each temporary register.
*/
static GLboolean
find_live_intervals(struct gl_program *prog,
struct interval_list *liveIntervals)
GLboolean
_mesa_find_temp_intervals(const struct prog_instruction *instructions,
GLuint numInstructions,
GLint intBegin[MAX_PROGRAM_TEMPS],
GLint intEnd[MAX_PROGRAM_TEMPS])
{
struct loop_info
{
@ -563,26 +561,15 @@ find_live_intervals(struct gl_program *prog,
};
struct loop_info loopStack[MAX_LOOP_NESTING];
GLuint loopStackDepth = 0;
GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
GLuint i;
/*
* Note: we'll return GL_FALSE below if we find relative indexing
* into the TEMP register file. We can't handle that yet.
* We also give up on subroutines for now.
*/
if (dbg) {
_mesa_printf("Optimize: Begin find intervals\n");
}
for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
intBegin[i] = intEnd[i] = -1;
}
/* Scan instructions looking for temporary registers */
for (i = 0; i < prog->NumInstructions; i++) {
const struct prog_instruction *inst = prog->Instructions + i;
for (i = 0; i < numInstructions; i++) {
const struct prog_instruction *inst = instructions + i;
if (inst->Opcode == OPCODE_BGNLOOP) {
loopStack[loopStackDepth].Start = i;
loopStack[loopStackDepth].End = inst->BranchTarget;
@ -595,7 +582,7 @@ find_live_intervals(struct gl_program *prog,
return GL_FALSE;
}
else {
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/
GLuint j;
for (j = 0; j < numSrc; j++) {
if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
@ -624,6 +611,39 @@ find_live_intervals(struct gl_program *prog,
}
}
return GL_TRUE;
}
/**
* Find the live intervals for each temporary register in the program.
* For register R, the interval [A,B] indicates that R is referenced
* from instruction A through instruction B.
* Special consideration is needed for loops and subroutines.
* \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason
*/
static GLboolean
find_live_intervals(struct gl_program *prog,
struct interval_list *liveIntervals)
{
GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
GLuint i;
/*
* Note: we'll return GL_FALSE below if we find relative indexing
* into the TEMP register file. We can't handle that yet.
* We also give up on subroutines for now.
*/
if (dbg) {
_mesa_printf("Optimize: Begin find intervals\n");
}
/* build intermediate arrays */
if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions,
intBegin, intEnd))
return GL_FALSE;
/* Build live intervals list from intermediate arrays */
liveIntervals->Num = 0;
for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
@ -794,6 +814,96 @@ _mesa_reallocate_registers(struct gl_program *prog)
#if 0
static void
_mesa_find_temporary_live_intervals(struct gl_program *prog,
GLint firstInst[MAX_PROGRAM_TEMPS],
GLint lastInst[MAX_PROGRAM_TEMPS])
{
GLuint i;
for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
firstInst[i] = lastInst[i] = -1;
}
struct loop_info loopStack[MAX_LOOP_NESTING];
GLuint loopStackDepth = 0;
GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
GLuint i;
/*
* Note: we'll return GL_FALSE below if we find relative indexing
* into the TEMP register file. We can't handle that yet.
* We also give up on subroutines for now.
*/
if (dbg) {
_mesa_printf("Optimize: Begin find intervals\n");
}
for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
intBegin[i] = intEnd[i] = -1;
}
/* Scan instructions looking for temporary registers */
for (i = 0; i < prog->NumInstructions; i++) {
const struct prog_instruction *inst = prog->Instructions + i;
if (inst->Opcode == OPCODE_BGNLOOP) {
loopStack[loopStackDepth].Start = i;
loopStack[loopStackDepth].End = inst->BranchTarget;
loopStackDepth++;
}
else if (inst->Opcode == OPCODE_ENDLOOP) {
loopStackDepth--;
}
else if (inst->Opcode == OPCODE_CAL) {
return GL_FALSE;
}
else {
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
GLuint j;
for (j = 0; j < numSrc; j++) {
if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
const GLuint index = inst->SrcReg[j].Index;
if (inst->SrcReg[j].RelAddr)
return GL_FALSE;
update_interval(intBegin, intEnd, index, i);
if (loopStackDepth > 0) {
/* extend temp register's interval to end of loop */
GLuint loopEnd = loopStack[loopStackDepth - 1].End;
update_interval(intBegin, intEnd, index, loopEnd);
}
}
}
if (inst->DstReg.File == PROGRAM_TEMPORARY) {
const GLuint index = inst->DstReg.Index;
if (inst->DstReg.RelAddr)
return GL_FALSE;
update_interval(intBegin, intEnd, index, i);
if (loopStackDepth > 0) {
/* extend temp register's interval to end of loop */
GLuint loopEnd = loopStack[loopStackDepth - 1].End;
update_interval(intBegin, intEnd, index, loopEnd);
}
}
}
}
#endif
/**
* Apply optimizations to the given program to eliminate unnecessary
* instructions, temp regs, etc.

View file

@ -25,7 +25,19 @@
#ifndef PROG_OPT_H
#define PROG_OPT_H
#include "main/config.h"
struct gl_program;
struct prog_instruction;
extern GLboolean
_mesa_find_temp_intervals(const struct prog_instruction *instructions,
GLuint numInstructions,
GLint intBegin[MAX_PROGRAM_TEMPS],
GLint intEnd[MAX_PROGRAM_TEMPS]);
extern void
_mesa_optimize_program(GLcontext *ctx, struct gl_program *program);