mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 15:48:36 +02:00
mesa: refactor code and make _mesa_find_temp_intervals() public
This commit is contained in:
parent
027ed1b505
commit
7da3f9403b
2 changed files with 144 additions and 22 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue