int o = 0;
unsigned sel = alu->dst.sel;
char reg_char = 'R';
- if (sel > 128 - 4) { /* clause temporary gpr */
+ if (sel >= 128 - 4) { /* clause temporary gpr */
sel -= 128 - 4;
reg_char = 'T';
}
if (alu_writes(alu)) {
o += fprintf(stderr, "%c", reg_char);
- o += print_sel(alu->dst.sel, alu->dst.rel, alu->index_mode, 0);
+ o += print_sel(sel, alu->dst.rel, alu->index_mode, 0);
} else {
o += fprintf(stderr, "__");
}
}
}
+ if (alu.dst.sel >= g_clause_local_start && alu.dst.sel < g_clause_local_end) {
+ int clidx = 4 * (alu.dst.sel - g_clause_local_start) + alu.dst.chan;
+ m_bc->cf_last->clause_local_written |= 1 << clidx;
+ }
+
if (ai.opcode() == op1_set_cf_idx0) {
m_bc->index_loaded[0] = 1;
m_bc->index_reg[0] = -1;
bool
AssamblerVisitor::copy_dst(r600_bytecode_alu_dst& dst, const Register& d, bool write)
{
- if (write && d.sel() > 124) {
- R600_ERR("shader_from_nir: Don't support more then 124 GPRs, but try "
- "using %d\n",
+ if (write && d.sel() > g_clause_local_end) {
+ R600_ERR("shader_from_nir: Don't support more then 124 GPRs + 2 claus "
+ "local, but try using %d\n",
d.sel());
m_result = false;
return false;
src.sel = s.sel();
src.chan = s.chan();
+ if (s.sel() >= g_clause_local_start && s.sel() < g_clause_local_end ) {
+ assert(m_bc->cf_last);
+ int clidx = 4 * (s.sel() - g_clause_local_start) + s.chan();
+ /* Ensure that the clause local register was already written */
+ assert(m_bc->cf_last->clause_local_written & (1 << clidx));
+ }
+
s.accept(visitor);
return visitor.m_buffer_offset;
}
void
EncodeSourceVisitor::visit(const Register& value)
{
- assert(value.sel() <= 124 && "Only have 124 registers");
+ assert(value.sel() < g_clause_local_end && "Only have 124 reisters + 4 clause local");
}
void
#include "sfn_ra.h"
+#include "sfn_alu_defines.h"
#include "sfn_debug.h"
#include <cassert>
return true;
}
+struct AluRegister {
+ int lifetime;
+ LiveRangeEntry *lre;
+};
+
+static inline bool operator < (const AluRegister& lhs, const AluRegister& rhs)
+{
+ return lhs.lifetime > rhs.lifetime;
+}
+
+using AluClauseRegisters = std::priority_queue<AluRegister>;
+
+
+static void
+scalar_clause_local_allocation (LiveRangeMap& lrm, const Interference& interference)
+{
+ for (int comp = 0; comp < 4; ++comp) {
+ AluClauseRegisters clause_reg;
+ auto& live_ranges = lrm.component(comp);
+ for (auto& r : live_ranges) {
+
+ sfn_log << SfnLog::merge << "LR: " << *r.m_register
+ << "[ " << r.m_start << ", " << r.m_end
+ << " ], AC: " << r.m_alu_clause_local
+ << " Color; " << r.m_color << "\n";
+
+ if (r.m_color != -1)
+ continue;
+
+ if (r.m_start == -1 &&
+ r.m_end == -1)
+ continue;
+
+ if (!r.m_alu_clause_local)
+ continue;
+
+ int len = r.m_end - r.m_start;
+ if (len > 1) {
+ clause_reg.push({len, &r});
+ sfn_log << SfnLog::merge << "Consider " << *r.m_register
+ << " for clause local\n";
+ }
+ }
+
+ while (!clause_reg.empty()) {
+ auto& r = clause_reg.top().lre;
+ clause_reg.pop();
+
+ sfn_log << SfnLog::merge << "Color " << *r->m_register << "\n";
+
+ auto& adjecency = interference.row(comp, r->m_register->index());
+
+ int color = g_clause_local_start;
+
+ while (color < g_clause_local_end) {
+ bool color_in_use = false;
+ for (auto adj : adjecency) {
+ if (live_ranges[adj].m_color == color) {
+ color_in_use = true;
+ break;
+ }
+ }
+
+ if (color_in_use) {
+ ++color;
+ continue;
+ }
+
+ r->m_color = color;
+ break;
+ }
+ if (color == g_clause_local_end)
+ break;
+ }
+ }
+}
+
bool
register_allocation(LiveRangeMap& lrm)
{
if (!group_allocation(lrm, interference, groups_sorted))
return false;
+ scalar_clause_local_allocation(lrm, interference);
+
if (!scalar_allocation(lrm, interference))
return false;