#include "sb_bc.h"
#include "sb_shader.h"
-
#include "sb_pass.h"
namespace r600_sb {
-using std::cerr;
-
-shader::shader(sb_context &sctx, shader_target t, unsigned id, bool dump)
+shader::shader(sb_context &sctx, shader_target t, unsigned id)
: ctx(sctx), next_temp_value_index(temp_regid_offset),
prep_regs_count(), pred_sels(),
regions(), inputs(), undef(), val_pool(sizeof(value)),
- pool(), all_nodes(), errors(), enable_dump(dump),
+ pool(), all_nodes(), src_stats(), opt_stats(), errors(),
optimized(), id(id),
coal(*this), bbs(),
target(t), vt(ex), ex(*this), root(),
compute_interferences(),
- has_alu_predication(), uses_gradients(), ngpr(), nstack() {}
+ has_alu_predication(), uses_gradients(), safe_math(), ngpr(), nstack() {}
bool shader::assign_slot(alu_node* n, alu_node *slots[5]) {
return true;
}
-void shader::add_gpr_values(vvec& vec, unsigned gpr, unsigned comp_mask,
+void shader::add_pinned_gpr_values(vvec& vec, unsigned gpr, unsigned comp_mask,
bool src) {
unsigned chan = 0;
while (comp_mask) {
v->gpr = v->pin_gpr = v->select;
v->fix();
}
+ if (v->array && !v->array->gpr) {
+ // if pinned value can be accessed with indirect addressing
+ // pin the entire array to its original location
+ v->array->gpr = v->array->base_gpr;
+ }
vec.push_back(v);
}
comp_mask >>= 1;
i.comp_mask = comp_mask;
if (preloaded) {
- add_gpr_values(root->dst, gpr, comp_mask, true);
+ add_pinned_gpr_values(root->dst, gpr, comp_mask, true);
}
}
for(inputs_vec::const_iterator I = inputs.begin(),
E = inputs.end(); I != E; ++I, ++gpr) {
if (!I->preloaded)
- add_gpr_values(cf->dst, gpr, I->comp_mask, false);
+ add_pinned_gpr_values(cf->dst, gpr, I->comp_mask, false);
else
- add_gpr_values(cf->src, gpr, I->comp_mask, true);
+ add_pinned_gpr_values(cf->src, gpr, I->comp_mask, true);
}
}
v->gvn_source = undefined->gvn_source;
}
}
-/*
-void shader::transfer_pins(vvec& vv, vvec &sv) {
- vvec::iterator SI = sv.begin();
- for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I, ++SI) {
- value *v = *I;
- value *sv = *SI;
- v->pin_gpr = sv->pin_gpr;
-
- if (sv->is_chan_pinned()) {
- v->flags |= VLF_PIN_CHAN;
- sv->flags &= ~VLF_PIN_CHAN;
- }
- if (sv->is_reg_pinned()) {
- v->flags |= VLF_PIN_REG;
- sv->flags &= ~VLF_PIN_REG;
- }
- }
-}
-*/
value* shader::create_value(value_kind k, sel_chan regid, unsigned ver) {
value *v = val_pool.create(k, regid, ver);
return v;
all_nodes.push_back(n);
return n;
}
-/*
-void shader::prepare_regs(unsigned cnt) {
- assert(!prep_regs_count);
-
- for (unsigned i = 0; i < cnt*4; ++i) {
- value *v = create_value(VLK_REG, i + 1, 0);
- assert (v->uid == i + 1);
- }
- prep_regs_count = cnt;
-}
-*/
value* shader::get_special_ro_value(unsigned sel) {
return get_ro_value(special_ro_values, VLK_PARAM, sel);
}
for (node_vec::iterator I = all_nodes.begin(), E = all_nodes.end();
I != E; ++I)
(*I)->~node();
+
+ for (gpr_array_vec::iterator I = gpr_arrays.begin(), E = gpr_arrays.end();
+ I != E; ++I) {
+ delete *I;
+ }
}
void shader::dump_ir() {
gpr_array *a = new gpr_array(
sel_chan(gpr_start, chan), gpr_count);
- SB_DUMP_PASS( cerr << "add_gpr_array: @" << a->base_gpr
+ SB_DUMP_PASS( sblog << "add_gpr_array: @" << a->base_gpr
<< " [" << a->array_size << "]\n";
);
std::string shader::get_full_target_name() {
std::string s = get_shader_target_name();
s += "/";
- s += get_hw_chip_name();
+ s += ctx.get_hw_chip_name();
s += "/";
- s += get_hw_class_name();
+ s += ctx.get_hw_class_name();
return s;
}
-const char* shader::get_hw_class_name() {
- switch (ctx.hw_class) {
-#define TRANSLATE_HW_CLASS(c) case HW_CLASS_##c: return #c
- TRANSLATE_HW_CLASS(R600);
- TRANSLATE_HW_CLASS(R700);
- TRANSLATE_HW_CLASS(EVERGREEN);
- TRANSLATE_HW_CLASS(CAYMAN);
-#undef TRANSLATE_HW_CLASS
- default:
- return "INVALID_CHIP_CLASS";
- }
-}
-
-const char* shader::get_hw_chip_name() {
- switch (ctx.hw_chip) {
-#define TRANSLATE_CHIP(c) case HW_CHIP_##c: return #c
- TRANSLATE_CHIP(R600);
- TRANSLATE_CHIP(RV610);
- TRANSLATE_CHIP(RV630);
- TRANSLATE_CHIP(RV670);
- TRANSLATE_CHIP(RV620);
- TRANSLATE_CHIP(RV635);
- TRANSLATE_CHIP(RS780);
- TRANSLATE_CHIP(RS880);
- TRANSLATE_CHIP(RV770);
- TRANSLATE_CHIP(RV730);
- TRANSLATE_CHIP(RV710);
- TRANSLATE_CHIP(RV740);
- TRANSLATE_CHIP(CEDAR);
- TRANSLATE_CHIP(REDWOOD);
- TRANSLATE_CHIP(JUNIPER);
- TRANSLATE_CHIP(CYPRESS);
- TRANSLATE_CHIP(HEMLOCK);
- TRANSLATE_CHIP(PALM);
- TRANSLATE_CHIP(SUMO);
- TRANSLATE_CHIP(SUMO2);
- TRANSLATE_CHIP(BARTS);
- TRANSLATE_CHIP(TURKS);
- TRANSLATE_CHIP(CAICOS);
- TRANSLATE_CHIP(CAYMAN);
-#undef TRANSLATE_CHIP
-
- default:
- assert(!"unknown chip");
- return "INVALID_CHIP";
- }
-}
-
const char* shader::get_shader_target_name() {
switch (target) {
case TARGET_VS: return "VS";
return c;
}
+void shader::collect_stats(bool opt) {
+ if (!sb_context::dump_stat)
+ return;
+
+ shader_stats &s = opt ? opt_stats : src_stats;
+
+ s.shaders = 1;
+ s.ngpr = ngpr;
+ s.nstack = nstack;
+ s.collect(root);
+
+ if (opt)
+ ctx.opt_stats.accumulate(s);
+ else
+ ctx.src_stats.accumulate(s);
+}
+
value* shader::get_ro_value(value_map& vm, value_kind vk, unsigned key) {
value_map::iterator I = vm.find(key);
if (I != vm.end())
}
}
+void shader_stats::collect(node *n) {
+ if (n->is_alu_inst())
+ ++alu;
+ else if (n->is_fetch_inst())
+ ++fetch;
+ else if (n->is_container()) {
+ container_node *c = static_cast<container_node*>(n);
+
+ if (n->is_alu_group())
+ ++alu_groups;
+ else if (n->is_alu_clause())
+ ++alu_clauses;
+ else if (n->is_fetch_clause())
+ ++fetch_clauses;
+ else if (n->is_cf_inst())
+ ++cf;
+
+ if (!c->empty()) {
+ for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) {
+ collect(*I);
+ }
+ }
+ }
+}
+
+void shader_stats::accumulate(shader_stats& s) {
+ ++shaders;
+ ndw += s.ndw;
+ ngpr += s.ngpr;
+ nstack += s.nstack;
+
+ alu += s.alu;
+ alu_groups += s.alu_groups;
+ alu_clauses += s.alu_clauses;
+ fetch += s.fetch;
+ fetch_clauses += s.fetch_clauses;
+ cf += s.cf;
+}
+
+void shader_stats::dump() {
+ sblog << "dw:" << ndw << ", gpr:" << ngpr << ", stk:" << nstack
+ << ", alu groups:" << alu_groups << ", alu clauses: " << alu_clauses
+ << ", alu:" << alu << ", fetch:" << fetch
+ << ", fetch clauses:" << fetch_clauses
+ << ", cf:" << cf;
+
+ if (shaders > 1)
+ sblog << ", shaders:" << shaders;
+
+ sblog << "\n";
+}
+
+static void print_diff(unsigned d1, unsigned d2) {
+ if (d1)
+ sblog << ((int)d2 - (int)d1) * 100 / (int)d1 << "%";
+ else if (d2)
+ sblog << "N/A";
+ else
+ sblog << "0%";
+}
+
+void shader_stats::dump_diff(shader_stats& s) {
+ sblog << "dw:"; print_diff(ndw, s.ndw);
+ sblog << ", gpr:" ; print_diff(ngpr, s.ngpr);
+ sblog << ", stk:" ; print_diff(nstack, s.nstack);
+ sblog << ", alu groups:" ; print_diff(alu_groups, s.alu_groups);
+ sblog << ", alu clauses: " ; print_diff(alu_clauses, s.alu_clauses);
+ sblog << ", alu:" ; print_diff(alu, s.alu);
+ sblog << ", fetch:" ; print_diff(fetch, s.fetch);
+ sblog << ", fetch clauses:" ; print_diff(fetch_clauses, s.fetch_clauses);
+ sblog << ", cf:" ; print_diff(cf, s.cf);
+ sblog << "\n";
+}
+
} // namespace r600_sb