#include "main/glheader.h"
#include "main/context.h"
#include "main/macros.h"
#include "program.h"
#include "prog_instruction.h"
#include "prog_optimize.h"
#include "prog_print.h"
Data Structures | |
struct | interval |
A live register interval. More... | |
struct | interval_list |
A list of register intervals. More... | |
Defines | |
#define | MAX_LOOP_NESTING 50 |
Enumerations | |
enum | temp_use { READ, WRITE, FLOW, END } |
Functions | |
static GLuint | remove_instructions (struct gl_program *prog, const GLboolean *removeFlags) |
In 'prog' remove instruction[i] if removeFlags[i] == TRUE. | |
static void | replace_regs (struct gl_program *prog, gl_register_file file, const GLint map[]) |
Remap register indexes according to map. | |
static void | _mesa_consolidate_registers (struct gl_program *prog) |
Consolidate temporary registers to use low numbers. | |
static void | _mesa_remove_dead_code (struct gl_program *prog) |
Remove dead instructions from the given program. | |
static enum temp_use | find_next_temp_use (const struct gl_program *prog, GLuint start, GLuint index) |
Scan forward in program from 'start' for the next occurance of TEMP[index]. | |
static void | _mesa_remove_extra_moves (struct gl_program *prog) |
Try to remove extraneous MOV instructions from the given program. | |
static void | append_interval (struct interval_list *list, const struct interval *inv) |
static void | insert_interval_by_end (struct interval_list *list, const struct interval *inv) |
Insert interval inv into list, sorted by interval end. | |
static void | remove_interval (struct interval_list *list, const struct interval *inv) |
Remove the given interval from the interval list. | |
static int | compare_start (const void *a, const void *b) |
called by qsort() | |
static void | sort_interval_list_by_start (struct interval_list *list) |
sort the interval list according to interval starts | |
static void | update_interval (GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic) |
Update the intermediate interval info for register 'index' and instruction 'ic'. | |
GLboolean | _mesa_find_temp_intervals (const struct prog_instruction *instructions, GLuint numInstructions, GLint intBegin[MAX_PROGRAM_TEMPS], GLint intEnd[MAX_PROGRAM_TEMPS]) |
Find first/last instruction that references each temporary register. | |
static GLboolean | find_live_intervals (struct gl_program *prog, struct interval_list *liveIntervals) |
Find the live intervals for each temporary register in the program. | |
static GLint | alloc_register (GLboolean usedRegs[MAX_PROGRAM_TEMPS]) |
Scan the array of used register flags to find free entry. | |
static void | _mesa_reallocate_registers (struct gl_program *prog) |
This function implements "Linear Scan Register Allocation" to reduce the number of temporary registers used by the program. | |
void | _mesa_optimize_program (GLcontext *ctx, struct gl_program *program) |
Apply optimizations to the given program to eliminate unnecessary instructions, temp regs, etc. | |
Variables | |
static GLboolean | dbg = GL_FALSE |
#define MAX_LOOP_NESTING 50 |
enum temp_use |
static void _mesa_consolidate_registers | ( | struct gl_program * | prog | ) | [static] |
Consolidate temporary registers to use low numbers.
For example, if the shader only uses temps 4, 5, 8, replace them with 0, 1, 2.
GLboolean _mesa_find_temp_intervals | ( | const struct prog_instruction * | instructions, | |
GLuint | numInstructions, | |||
GLint | intBegin[MAX_PROGRAM_TEMPS], | |||
GLint | intEnd[MAX_PROGRAM_TEMPS] | |||
) |
Find first/last instruction that references each temporary register.
< Start, end instructions of loop
void _mesa_optimize_program | ( | GLcontext * | ctx, | |
struct gl_program * | program | |||
) |
Apply optimizations to the given program to eliminate unnecessary instructions, temp regs, etc.
static void _mesa_reallocate_registers | ( | struct gl_program * | prog | ) | [static] |
This function implements "Linear Scan Register Allocation" to reduce the number of temporary registers used by the program.
We compute the "live interval" for all temporary registers then examine the overlap of the intervals to allocate new registers. Basically, if two intervals do not overlap, they can use the same register.
static void _mesa_remove_dead_code | ( | struct gl_program * | prog | ) | [static] |
Remove dead instructions from the given program.
This is very primitive for now. Basically look for temp registers that are written to but never read. Remove any instructions that write to such registers. Be careful with condition code setters.
static void _mesa_remove_extra_moves | ( | struct gl_program * | prog | ) | [static] |
Try to remove extraneous MOV instructions from the given program.
static GLint alloc_register | ( | GLboolean | usedRegs[MAX_PROGRAM_TEMPS] | ) | [static] |
Scan the array of used register flags to find free entry.
static void append_interval | ( | struct interval_list * | list, | |
const struct interval * | inv | |||
) | [static] |
static int compare_start | ( | const void * | a, | |
const void * | b | |||
) | [static] |
called by qsort()
static GLboolean find_live_intervals | ( | struct gl_program * | prog, | |
struct interval_list * | liveIntervals | |||
) | [static] |
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.
static enum temp_use find_next_temp_use | ( | const struct gl_program * | prog, | |
GLuint | start, | |||
GLuint | index | |||
) | [static] |
Scan forward in program from 'start' for the next occurance of TEMP[index].
Return READ, WRITE, FLOW or END to indicate the next usage or an indicator that we can't look further.
static void insert_interval_by_end | ( | struct interval_list * | list, | |
const struct interval * | inv | |||
) | [static] |
static GLuint remove_instructions | ( | struct gl_program * | prog, | |
const GLboolean * | removeFlags | |||
) | [static] |
In 'prog' remove instruction[i] if removeFlags[i] == TRUE.
static void remove_interval | ( | struct interval_list * | list, | |
const struct interval * | inv | |||
) | [static] |
static void replace_regs | ( | struct gl_program * | prog, | |
gl_register_file | file, | |||
const GLint | map[] | |||
) | [static] |
Remap register indexes according to map.
prog | the program to search/replace | |
file | the type of register file to search/replace | |
map | maps old register indexes to new indexes |
static void sort_interval_list_by_start | ( | struct interval_list * | list | ) | [static] |
static void update_interval | ( | GLint | intBegin[], | |
GLint | intEnd[], | |||
GLuint | index, | |||
GLuint | ic | |||
) | [static] |
Update the intermediate interval info for register 'index' and instruction 'ic'.
GLboolean dbg = GL_FALSE [static] |