Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2013 Vadim Girlin <vadimgirlin@gmail.com>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Vadim Girlin
  25.  */
  26.  
  27. #define VT_DEBUG 0
  28.  
  29. #if VT_DEBUG
  30. #define VT_DUMP(q) do { q } while (0)
  31. #else
  32. #define VT_DUMP(q)
  33. #endif
  34.  
  35. #include <cstring>
  36.  
  37. #include "sb_shader.h"
  38. #include "sb_pass.h"
  39.  
  40. namespace r600_sb {
  41.  
  42. static const char * chans = "xyzw01?_";
  43.  
  44. sb_ostream& operator << (sb_ostream &o, value &v) {
  45.  
  46.         bool dead = v.flags & VLF_DEAD;
  47.  
  48.         if (dead)
  49.                 o << "{";
  50.  
  51.         switch (v.kind) {
  52.         case VLK_SPECIAL_REG: {
  53.                 switch (v.select.sel()) {
  54.                         case SV_AR_INDEX: o << "AR"; break;
  55.                         case SV_ALU_PRED: o << "PR"; break;
  56.                         case SV_EXEC_MASK: o << "EM"; break;
  57.                         case SV_VALID_MASK: o << "VM"; break;
  58.                         case SV_GEOMETRY_EMIT: o << "GEOMETRY_EMIT"; break;
  59.                         default: o << "???specialreg"; break;
  60.                 }
  61.                 break;
  62.         }
  63.  
  64.         case VLK_REG:
  65.                 o << "R" << v.select.sel() << "."
  66.                         << chans[v.select.chan()];
  67.  
  68.                 break;
  69.         case VLK_KCACHE: {
  70.                 o << "C" << v.select.sel() << "." << chans[v.select.chan()];
  71.         }
  72.                 break;
  73.         case VLK_CONST:
  74.                 o << v.literal_value.f << "|";
  75.                 o.print_zw_hex(v.literal_value.u, 8);
  76.                 break;
  77.         case VLK_PARAM:
  78.                 o << "Param" << (v.select.sel() - ALU_SRC_PARAM_OFFSET)
  79.                         << chans[v.select.chan()];
  80.                 break;
  81.         case VLK_TEMP:
  82.                 o << "t" << v.select.sel() - shader::temp_regid_offset;
  83.                 break;
  84.         case VLK_REL_REG:
  85.  
  86.                 o << "A" << v.select;
  87.                 o << "[";
  88.                 o << *v.rel;
  89.                 o << "]";
  90.  
  91.                 o << "_" << v.uid;
  92.  
  93.                 break;
  94.         case VLK_UNDEF:
  95.                 o << "undef";
  96.                 break;
  97.         default:
  98.                 o << v.kind << "?????";
  99.                 break;
  100.         }
  101.  
  102.         if (v.version)
  103.                 o << "." << v.version;
  104.  
  105.         if (dead)
  106.                 o << "}";
  107.  
  108.         if (v.is_global())
  109.                 o << "||";
  110.         if (v.is_fixed())
  111.                 o << "F";
  112.         if (v.is_prealloc())
  113.                 o << "P";
  114.  
  115.         sel_chan g;
  116.  
  117.         if (v.is_rel()) {
  118.                 g = v.array->gpr;
  119.         } else {
  120.                 g = v.gpr;
  121.         }
  122.  
  123.         if (g) {
  124.                 o << "@R" << g.sel() << "." << chans[g.chan()];
  125.         }
  126.  
  127.         return o;
  128. }
  129.  
  130. void value_table::add_value(value* v) {
  131.  
  132.         if (v->gvn_source) {
  133.                 return;
  134.         }
  135.  
  136.         VT_DUMP(
  137.                 sblog << "gvn add_value ";
  138.                 dump::dump_val(v);
  139.         );
  140.  
  141.         value_hash hash = v->hash();
  142.         vt_item & vti = hashtable[hash & size_mask];
  143.         vti.push_back(v);
  144.         ++cnt;
  145.  
  146.         if (v->def && ex.try_fold(v)) {
  147.                 VT_DUMP(
  148.                         sblog << " folded: ";
  149.                         dump::dump_val(v->gvn_source);
  150.                         sblog << "\n";
  151.                 );
  152.                 return;
  153.         }
  154.  
  155.         int n = 0;
  156.         for (vt_item::iterator I = vti.begin(), E = vti.end(); I != E; ++I, ++n) {
  157.                 value *c = *I;
  158.  
  159.                 if (c == v)
  160.                         break;
  161.  
  162.                 if (expr_equal(c, v)) {
  163.                         v->gvn_source = c->gvn_source;
  164.  
  165.                         VT_DUMP(
  166.                                 sblog << " found : equal to ";
  167.                                 dump::dump_val(v->gvn_source);
  168.                                 sblog << "\n";
  169.                         );
  170.                         return;
  171.                 }
  172.         }
  173.  
  174.         v->gvn_source = v;
  175.         VT_DUMP(
  176.                 sblog << " added new\n";
  177.         );
  178. }
  179.  
  180. value_hash value::hash() {
  181.         if (ghash)
  182.                 return ghash;
  183.         if (is_rel())
  184.                 ghash = rel_hash();
  185.         else if (def)
  186.                 ghash = def->hash();
  187.         else
  188.                 ghash = ((uintptr_t)this) | 1;
  189.  
  190.         return ghash;
  191. }
  192.  
  193. value_hash value::rel_hash() {
  194.         value_hash h = rel ? rel->hash() : 0;
  195.         h |= select << 10;
  196.         h |= array->hash();
  197.         return h;
  198. }
  199.  
  200. bool value_table::expr_equal(value* l, value* r) {
  201.         return ex.equal(l, r);
  202. }
  203.  
  204. void value_table::get_values(vvec& v) {
  205.         v.resize(cnt);
  206.  
  207.         vvec::iterator T = v.begin();
  208.  
  209.         for(vt_table::iterator I = hashtable.begin(), E = hashtable.end();
  210.                         I != E; ++I) {
  211.                 T = std::copy(I->begin(), I->end(), T);
  212.         }
  213. }
  214.  
  215. void value::add_use(node* n, use_kind kind, int arg) {
  216.         if (0) {
  217.         sblog << "add_use ";
  218.         dump::dump_val(this);
  219.         sblog << "   =>  ";
  220.         dump::dump_op(n);
  221.         sblog << "     kind " << kind << "    arg " << arg << "\n";
  222.         }
  223.         uses = new use_info(n, kind, arg, uses);
  224. }
  225.  
  226. unsigned value::use_count() {
  227.         use_info *u = uses;
  228.         unsigned c = 0;
  229.         while (u) {
  230.                 ++c;
  231.                 u = u->next;
  232.         }
  233.         return c;
  234. }
  235.  
  236. bool value::is_global() {
  237.         if (chunk)
  238.                 return chunk->is_global();
  239.         return flags & VLF_GLOBAL;
  240. }
  241.  
  242. void value::set_global() {
  243.         assert(is_sgpr());
  244.         flags |= VLF_GLOBAL;
  245.         if (chunk)
  246.                 chunk->set_global();
  247. }
  248.  
  249. void value::set_prealloc() {
  250.         assert(is_sgpr());
  251.         flags |= VLF_PREALLOC;
  252.         if (chunk)
  253.                 chunk->set_prealloc();
  254. }
  255.  
  256. bool value::is_fixed() {
  257.         if (array && array->gpr)
  258.                 return true;
  259.         if (chunk && chunk->is_fixed())
  260.                 return true;
  261.         return flags & VLF_FIXED;
  262. }
  263.  
  264. void value::fix() {
  265.         if (chunk)
  266.                 chunk->fix();
  267.         flags |= VLF_FIXED;
  268. }
  269.  
  270. bool value::is_prealloc() {
  271.         if (chunk)
  272.                 return chunk->is_prealloc();
  273.         return flags & VLF_PREALLOC;
  274. }
  275.  
  276. void value::delete_uses() {
  277.         use_info *u, *c = uses;
  278.         while (c) {
  279.                 u = c->next;
  280.                 delete c;
  281.                 c = u;
  282.         }
  283.         uses = NULL;
  284. }
  285.  
  286. void ra_constraint::update_values() {
  287.         for (vvec::iterator I = values.begin(), E = values.end(); I != E; ++I) {
  288.                 assert(!(*I)->constraint);
  289.                 (*I)->constraint = this;
  290.         }
  291. }
  292.  
  293. void* sb_pool::allocate(unsigned sz) {
  294.         sz = (sz + SB_POOL_ALIGN - 1) & ~(SB_POOL_ALIGN - 1);
  295.         assert (sz < (block_size >> 6) && "too big allocation size for sb_pool");
  296.  
  297.         unsigned offset = total_size % block_size;
  298.         unsigned capacity = block_size * blocks.size();
  299.  
  300.         if (total_size + sz > capacity) {
  301.                 total_size = capacity;
  302.                 void * nb = malloc(block_size);
  303.                 blocks.push_back(nb);
  304.                 offset = 0;
  305.         }
  306.  
  307.         total_size += sz;
  308.         return ((char*)blocks.back() + offset);
  309. }
  310.  
  311. void sb_pool::free_all() {
  312.         for (block_vector::iterator I = blocks.begin(), E = blocks.end(); I != E;
  313.                         ++I) {
  314.                 free(*I);
  315.         }
  316. }
  317.  
  318. value* sb_value_pool::create(value_kind k, sel_chan regid,
  319.                              unsigned ver) {
  320.         void* np = allocate(aligned_elt_size);
  321.         value *v = new (np) value(size(), k, regid, ver);
  322.         return v;
  323. }
  324.  
  325. void sb_value_pool::delete_all() {
  326.         unsigned bcnt = blocks.size();
  327.         unsigned toffset = 0;
  328.         for (unsigned b = 0; b < bcnt; ++b) {
  329.                 char *bstart = (char*)blocks[b];
  330.                 for (unsigned offset = 0; offset < block_size;
  331.                                 offset += aligned_elt_size) {
  332.                         ((value*)(bstart + offset))->~value();
  333.                         toffset += aligned_elt_size;
  334.                         if (toffset >= total_size)
  335.                                 return;
  336.                 }
  337.         }
  338. }
  339.  
  340. bool sb_bitset::get(unsigned id) {
  341.         assert(id < bit_size);
  342.         unsigned w = id / bt_bits;
  343.         unsigned b = id % bt_bits;
  344.         return (data[w] >> b) & 1;
  345. }
  346.  
  347. void sb_bitset::set(unsigned id, bool bit) {
  348.         assert(id < bit_size);
  349.         unsigned w = id / bt_bits;
  350.         unsigned b = id % bt_bits;
  351.         if (w >= data.size())
  352.                 data.resize(w + 1);
  353.  
  354.         if (bit)
  355.                 data[w] |= (1 << b);
  356.         else
  357.                 data[w] &= ~(1 << b);
  358. }
  359.  
  360. inline bool sb_bitset::set_chk(unsigned id, bool bit) {
  361.         assert(id < bit_size);
  362.         unsigned w = id / bt_bits;
  363.         unsigned b = id % bt_bits;
  364.         basetype d = data[w];
  365.         basetype dn = (d & ~(1 << b)) | (bit << b);
  366.         bool r = (d != dn);
  367.         data[w] = r ? dn : data[w];
  368.         return r;
  369. }
  370.  
  371. void sb_bitset::clear() {
  372.         std::fill(data.begin(), data.end(), 0);
  373. }
  374.  
  375. void sb_bitset::resize(unsigned size) {
  376.         unsigned cur_data_size = data.size();
  377.         unsigned new_data_size = (size + bt_bits - 1) / bt_bits;
  378.  
  379.  
  380.         if (new_data_size != cur_data_size)
  381.                 data.resize(new_data_size);
  382.  
  383.         // make sure that new bits in the existing word are cleared
  384.         if (cur_data_size && size > bit_size && bit_size % bt_bits) {
  385.                 basetype clear_mask = (~(basetype)0u) << (bit_size % bt_bits);
  386.                 data[cur_data_size - 1] &= ~clear_mask;
  387.         }
  388.  
  389.         bit_size = size;
  390. }
  391.  
  392. unsigned sb_bitset::find_bit(unsigned start) {
  393.         assert(start < bit_size);
  394.         unsigned w = start / bt_bits;
  395.         unsigned b = start % bt_bits;
  396.         unsigned sz = data.size();
  397.  
  398.         while (w < sz) {
  399.                 basetype d = data[w] >> b;
  400.                 if (d != 0) {
  401.                         unsigned pos = __builtin_ctz(d) + b + w * bt_bits;
  402.                         return pos;
  403.                 }
  404.  
  405.                 b = 0;
  406.                 ++w;
  407.         }
  408.  
  409.         return bit_size;
  410. }
  411.  
  412. sb_value_set::iterator::iterator(shader& sh, sb_value_set* s, unsigned nb)
  413.         : vp(sh.get_value_pool()), s(s), nb(nb) {}
  414.  
  415. bool sb_value_set::add_set_checked(sb_value_set& s2) {
  416.         if (bs.size() < s2.bs.size())
  417.                 bs.resize(s2.bs.size());
  418.         sb_bitset nbs = bs | s2.bs;
  419.         if (bs != nbs) {
  420.                 bs.swap(nbs);
  421.                 return true;
  422.         }
  423.         return false;
  424. }
  425.  
  426. void r600_sb::sb_value_set::remove_set(sb_value_set& s2) {
  427.         bs.mask(s2.bs);
  428. }
  429.  
  430. bool sb_value_set::add_val(value* v) {
  431.         assert(v);
  432.         if (bs.size() < v->uid)
  433.                 bs.resize(v->uid + 32);
  434.  
  435.         return bs.set_chk(v->uid - 1, 1);
  436. }
  437.  
  438. bool sb_value_set::remove_vec(vvec& vv) {
  439.         bool modified = false;
  440.         for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
  441.                 if (*I)
  442.                         modified |= remove_val(*I);
  443.         }
  444.         return modified;
  445. }
  446.  
  447. void sb_value_set::clear() {
  448.         bs.clear();
  449. }
  450.  
  451. bool sb_value_set::remove_val(value* v) {
  452.         assert(v);
  453.         if (bs.size() < v->uid)
  454.                 return false;
  455.         return bs.set_chk(v->uid - 1, 0);
  456. }
  457.  
  458. bool r600_sb::sb_value_set::add_vec(vvec& vv) {
  459.         bool modified = false;
  460.         for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
  461.                 value *v = *I;
  462.                 if (v)
  463.                         modified |= add_val(v);
  464.         }
  465.         return modified;
  466. }
  467.  
  468. bool r600_sb::sb_value_set::contains(value* v) {
  469.         unsigned b = v->uid - 1;
  470.         if (b < bs.size())
  471.                 return bs.get(v->uid - 1);
  472.         else
  473.                 return false;
  474. }
  475.  
  476. bool sb_value_set::empty() {
  477.         return bs.size() == 0 || bs.find_bit(0) == bs.size();
  478. }
  479.  
  480. void sb_bitset::swap(sb_bitset& bs2) {
  481.         std::swap(data, bs2.data);
  482.         std::swap(bit_size, bs2.bit_size);
  483. }
  484.  
  485. bool sb_bitset::operator ==(const sb_bitset& bs2) {
  486.         if (bit_size != bs2.bit_size)
  487.                 return false;
  488.  
  489.         for (unsigned i = 0, c = data.size(); i < c; ++i) {
  490.                 if (data[i] != bs2.data[i])
  491.                         return false;
  492.         }
  493.         return true;
  494. }
  495.  
  496. sb_bitset& sb_bitset::operator &=(const sb_bitset& bs2) {
  497.         if (bit_size > bs2.bit_size) {
  498.                 resize(bs2.bit_size);
  499.         }
  500.  
  501.         for (unsigned i = 0, c = std::min(data.size(), bs2.data.size()); i < c;
  502.                         ++i) {
  503.                 data[i] &= bs2.data[i];
  504.         }
  505.         return *this;
  506. }
  507.  
  508. sb_bitset& sb_bitset::mask(const sb_bitset& bs2) {
  509.         if (bit_size < bs2.bit_size) {
  510.                 resize(bs2.bit_size);
  511.         }
  512.  
  513.         for (unsigned i = 0, c = data.size(); i < c;
  514.                         ++i) {
  515.                 data[i] &= ~bs2.data[i];
  516.         }
  517.         return *this;
  518. }
  519.  
  520. bool ra_constraint::check() {
  521.         assert(kind == CK_SAME_REG);
  522.  
  523.         unsigned reg = 0;
  524.  
  525.         for (vvec::iterator I = values.begin(), E = values.end(); I != E; ++I) {
  526.                 value *v = *I;
  527.                 if (!v)
  528.                         continue;
  529.  
  530.                 if (!v->gpr)
  531.                         return false;
  532.  
  533.                 if (reg == 0)
  534.                         reg = v->gpr.sel() + 1;
  535.                 else if (reg != v->gpr.sel() + 1)
  536.                         return false;
  537.  
  538.                 if (v->is_chan_pinned()) {
  539.                         if (v->pin_gpr.chan() != v->gpr.chan())
  540.                                 return false;
  541.                 }
  542.         }
  543.         return true;
  544. }
  545.  
  546. bool gpr_array::is_dead() {
  547.         return false;
  548. }
  549.  
  550. } // namespace r600_sb
  551.