diff options
author | Tom Stellard <tstellar@gmail.com> | 2011-01-31 00:09:45 -0800 |
---|---|---|
committer | Tom Stellard <tstellar@gmail.com> | 2011-01-31 00:09:45 -0800 |
commit | d5566682bafcb42c81d192e4a6958d0e9849fafc (patch) | |
tree | cf6860d24d759c9de3987f4bda82c57b3f482125 | |
parent | a82cfb6229ca5d63c0eb9469157eeb13e2c24e53 (diff) |
Tempregalloc-wip
8 files changed, 403 insertions, 15 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c index 619862b375c..177b764989d 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c @@ -131,7 +131,7 @@ unsigned int rc_replace_swizzle( rc_swizzle new_swz) { unsigned int i; - for (i = 0; i < 3; i++) { + for (i = 0; i < 4; i++) { if (get_swz(src_swizzle, i) == old_swz) { SET_SWZ(src_swizzle, i, new_swz); } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c index a7eae077ada..12772288a97 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c @@ -789,6 +789,26 @@ static void get_readers_for_single_write( } } +static void init_get_readers_callback_data( + struct get_readers_callback_data * d, + struct rc_reader_data * reader_data, + struct radeon_compiler * c, + rc_read_src_fn read_normal_cb, + rc_pair_read_arg_fn read_pair_cb, + rc_read_write_mask_fn write_cb) +{ + reader_data->Abort = 0; + reader_data->ReaderCount = 0; + reader_data->ReadersReserved = 0; + reader_data->Readers = NULL; + + d->C = c; + d->ReaderData = reader_data; + d->ReadNormalCB = read_normal_cb; + d->ReadPairCB = read_pair_cb; + d->WriteCB = write_cb; +} + /** * This function will create a list of readers via the rc_reader_data struct. * This function will abort (set the flag data->Abort) and return if it @@ -837,16 +857,28 @@ void rc_get_readers( { struct get_readers_callback_data d; - data->Abort = 0; - data->ReaderCount = 0; - data->ReadersReserved = 0; - data->Readers = NULL; - - d.C = c; - d.ReaderData = data; - d.ReadNormalCB = read_normal_cb; - d.ReadPairCB = read_pair_cb; - d.WriteCB = write_cb; + init_get_readers_callback_data(&d, data, c, read_normal_cb, + read_pair_cb, write_cb); rc_for_all_writes_mask(writer, get_readers_for_single_write, &d); } + +void rc_get_readers_sub( + struct radeon_compiler * c, + struct rc_instruction * writer, + struct rc_pair_sub_instruction * sub_writer, + struct rc_reader_data * data, + rc_read_src_fn read_normal_cb, + rc_pair_read_arg_fn read_pair_cb, + rc_read_write_mask_fn write_cb) +{ + struct get_readers_callback_data d; + + init_get_readers_callback_data(&d, data, c, read_normal_cb, + read_pair_cb, write_cb); + + if (sub_writer->WriteMask) { + get_readers_for_single_write(&d, writer, RC_FILE_TEMPORARY, + sub_writer->DestIndex, sub_writer->WriteMask); + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h index 2b5d3dda733..ed7c9e4d073 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h @@ -37,6 +37,7 @@ struct rc_swizzle_caps; struct rc_src_register; struct rc_pair_instruction_arg; struct rc_pair_instruction_source; +struct rc_pair_sub_instruction; struct rc_compiler; @@ -102,6 +103,15 @@ void rc_get_readers( rc_read_src_fn read_normal_cb, rc_pair_read_arg_fn read_pair_cb, rc_read_write_mask_fn write_cb); + +void rc_get_readers_sub( + struct radeon_compiler * c, + struct rc_instruction * writer, + struct rc_pair_sub_instruction * sub_writer, + struct rc_reader_data * data, + rc_read_src_fn read_normal_cb, + rc_pair_read_arg_fn read_pair_cb, + rc_read_write_mask_fn write_cb); /** * Compiler passes based on dataflow analysis. */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_list.c b/src/mesa/drivers/dri/r300/compiler/radeon_list.c new file mode 100644 index 00000000000..6f6eae2664c --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_list.c @@ -0,0 +1,65 @@ +/* + * Copyright 2011 Tom Stellard <tstellar@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + + + +struct rc_list * rc_list(struct memory_pool * pool, void * item) +{ + struct rc_list * new = memory_pool_malloc(pool, sizeof(struct rc_list)); + new->Item = item; + new->Next = NULL; + new->Prev = NULL; +} + +static void rc_list_add(struct rc_list ** list, rc_list * new_value) +{ + struct rc_list * temp; + + if (*list == NULL) { + *list = new_value; + return; + } + + for (temp = *list; temp->Next; temp = temp->Next); + + list->Next = new_value; + new_value->Prev = list; +} + +static void rc_list_remove(struct rc_list ** list, rc_list * rm_value) +{ + if (*list == rm_value) { + *list = rm_value->Next; + return; + } + + rm_value->Prev->Next = rm_value->Next; + if (rm_value->Next) { + rm_value->Next->Prev = rm_value->Prev; + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_list.h b/src/mesa/drivers/dri/r300/compiler/radeon_list.h new file mode 100644 index 00000000000..f0d6ebd221b --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_list.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011 Tom Stellard <tstellar@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RADEON_LIST_H +#define RADEON_LIST_H + +struct memory_pool; + +struct rc_list { + void * Item; + struct rc_list * Prev; + struct rc_list * Next; +}; + +struct rc_list * rc_list(struct memory_pool * pool, void * item); +void rc_list_add(struct rc_list ** list, struct rc_list * new_value); +void rc_list_remove(struct rc_list ** list, struct rc_list * rm_value); + +#endif /* RADEON_LIST_H */ + diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c index 8d93d049232..ca6a09cb053 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c @@ -30,10 +30,12 @@ #include <stdio.h> #include "radeon_compiler.h" +#include "radeon_compiler_util.h" #include "radeon_dataflow.h" +#include "radeon_list.h" +#include "radeon_variable.h" - -#define VERBOSE 1 +#define VERBOSE 0 #define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0) @@ -597,13 +599,22 @@ static void pack_registers(struct regalloc_state * s) } } +static void do_advanced_regalloc(struct regalloc_state * s) +{ + +// assert(!aborted_list); + +// rc_variable_calculate_live_intervals(); + /* With the list of variables begin packing. */ +} + /** * @param user This parameter should be a pointer to an integer value. If this * integer value is zero, then a simple register allocator will be used that * only allocates space for input registers (\sa do_regalloc_inputs_only). If * user is non-zero, then the regular register allocator will be used * (\sa do_regalloc). - */ + */ void rc_pair_regalloc(struct radeon_compiler *cc, void *user) { struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc; @@ -617,7 +628,7 @@ void rc_pair_regalloc(struct radeon_compiler *cc, void *user) do_regalloc_inputs_only(&s); } else { pack_registers(&s); - rc_print_program(&cc->Program); +// rc_print_program(&cc->Program); c->AllocateHwInputs(c, &alloc_input, &s); do_regalloc(&s); } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_variable.c b/src/mesa/drivers/dri/r300/compiler/radeon_variable.c new file mode 100644 index 00000000000..015120863fc --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_variable.c @@ -0,0 +1,167 @@ +/* + * Copyright 2011 Tom Stellard <tstellar@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "rc_list.h" + +static unsigned int readers_instersect( + struct rc_variable * a, + struct rc_variable * b) +{ + unsigned int a_index, b_index; + for (a_index = 0; a_index < a->ReaderCount; a_index++) { + struct rc_reader * reader_a = a->Readers[a_index]; + for (b_index = 0; b_index < b->ReaderCount b_index++) { + struct rc_reader * reader_b = b->readers[b_index]; + if (reader_a->Inst->Type == RC_INSTRUCTION_NORMAL + && reader_b->Inst->Type = RC_INSTRUCTION_NORMAL + && reader_a.U.Src == reader_b.U.Src) { + + return 1; + } + + if (reader_a->Inst->Type == RC_INSTRUCTION_PAIR + && reader_b->Inst->Type == RC_INSTRUCTION_PAIR + && reader_a.U.Arg == reader_b.U.Arg) { + + return 1; + } + } + } + return 0; +} + +void rc_variable_add_friend( + struct rc_variable * var, + struct rc_variable * friend) +{ + while(var->Friend) { + var = var->Friend; + } + var->Friend = friend; +} + +struct rc_variable * rc_variable( + memory_pool * pool, + unsigned int DstFile, + unsigned int DstIndex, + unsigned int DstWriteMask, + struct rc_reader_data * reader_data) +{ + struct rc_variable * new = + memory_pool_malloc(pool, sizeof(struct rc_variable)); + memset(new, 0, sizeof(struct variable)); + new->ReaderDataList = rc_list(reader_data); + return new; +} + +static void get_variable_helper( + struct rc_list ** aborted_list, + struct rc_list ** variable_list, + unsigned int aborted, + struct rc_variable * variable) +{ + if (reader_data->Abort) { + rc_list_add(aborted_list, rc_list(variable)); + } else { + rc_list_add(variable_list, rc_list(variable)); + } +} + +static void get_variable_pair_helper( + struct rc_list ** aborted_list, + struct rc_list ** variable_list, + struct rc_compiler * c, + struct rc_pair_sub_instruction * sub_inst) +{ + struct reader_data reader_data; + struct rc_variable * new_var; + rc_register_file file; + unsigned int writemask; + + if (sub->Opcode == RC_OPCODE_NOP) { + return; + } + rc_get_readers_sub(c, inst, sub_inst, &reader_data, NULL, NULL, NULL); + + if (sub_inst->WriteMask) { + file = RC_FILE_TEMPORARY; + writemask = sub_inst->WriteMask; + } else if (sub_isnt->OutputWriteMask) { + file = RC_FILE_OUTPUT; + writemask = sub_inst->OutputWriteMask; + } else { + writemask = 0; + file = RC_FILE_NONE; + } + new_var = rc_variable(c->Pool, file, sub_inst->DstIndex, writemask, + &reader_data); + get_variable_helper(aborted_list, variable_list, reader_data->Aborted, + new_var); +} + + +struct rc_list * rc_get_variables(radeon_compiler * c) +{ + struct rc_instruction * inst; + struct rc_list * aborted_list = NULL; + struct rc_list * variable_list = NULL; + struct rc_list * var_ptr; + struct rc_list * search_ptr; + + for (inst = c->Program.Instructions.Next; + inst != &c->Program.Instructions; + inst = inst->Next) { + struct rc_reader reader_data; + struct rc_variable * new_var; + + if (inst->Type == RC_NORMAL_INSTRUCTION) { + rc_get_readers(c, inst, reader_data, NULL, NULL, NULL); + new_var = rc_variable(c->Pool, inst->U.I.DstReg.File, + inst->U.I.DstReg.Index, + inst->U.I.DstReg.WriteMask, &reader_data); + get_variable_helper(&aborted_list, &variable_list, + reader_data->Abort, new_var); + } else { + get_variable_pair_helper(aborted_list, variable_list, + c, inst->U.P.RGB); + get_variable_pair_helper(aborted_list, variable_list, + c, inst->U.P.Alpha); + } + } + + for (var_ptr = aborted_list; var_ptr; var_ptr = var_ptr->Next) { + rc_list_remove(&aborted_list, var_ptr); + for (search_ptr = var_ptr->Next; search_ptr; + search_ptr = search_ptr->Next) { + if (readers_intersect(var_ptr->Item, search_ptr->Item)){ + rc_list_remove(&aborted_list, search_ptr); + rc_variable_add_friend(var_ptr->Item, + search_ptr->Item); + } + } + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_variable.h b/src/mesa/drivers/dri/r300/compiler/radeon_variable.h new file mode 100644 index 00000000000..689a7e2de84 --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_variable.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011 Tom Stellard <tstellar@gmail.com> + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RADEON_VARIABLE_H +#define RADEON_VARIABLE_H + +struct live_intervals; +struct memory_pool; +struct rc_list; + +struct rc_variable { + struct rc_dst_register Dst; + + struct rc_instruction * Inst; + unsigned int ReaderCount; + struct rc_readers * Readers; + struct live_intervals * Live[4]; + + struct rc_variable * Friend; +}; + +void rc_variable_add_friend( + struct rc_variable * var, + struct rc_variable * friend); + +struct rc_variable * rc_variable( + struct memory_pool * pool, + unsigned int DstFile, + unsigned int DstIndex, + unsigned int DstWriteMask, + struct rc_reader_data * reader_data); + +struct rc_list * rc_get_variables(struct radeon_compiler * c); + +#endif /* RADEON_VARIABLE_H */ |