summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2011-01-31 00:09:45 -0800
committerTom Stellard <tstellar@gmail.com>2011-01-31 00:09:45 -0800
commitd5566682bafcb42c81d192e4a6958d0e9849fafc (patch)
treecf6860d24d759c9de3987f4bda82c57b3f482125
parenta82cfb6229ca5d63c0eb9469157eeb13e2c24e53 (diff)
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_compiler_util.c2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c52
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h10
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_list.c65
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_list.h44
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c19
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_variable.c167
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_variable.h59
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 */