Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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.                         default: o << "???specialreg"; break;
  59.                 }
  60.                 break;
  61.         }
  62.  
  63.         case VLK_REG:
  64.                 o << "R" << v.select.sel() << "."
  65.                         << chans[v.select.chan()];
  66.  
  67.                 break;
  68.         case VLK_KCACHE: {
  69.                 o << "C" << v.select.sel() << "." << chans[v.select.chan()];
  70.         }
  71.                 break;
  72.         case VLK_CONST:
  73.                 o << v.literal_value.f << "|";
  74.                 o.print_zw_hex(v.literal_value.u, 8);
  75.                 break;
  76.         case VLK_PARAM:
  77.                 o << "Param" << (v.select.sel() - ALU_SRC_PARAM_OFFSET)
  78.                         << chans[v.select.chan()];
  79.                 break;
  80.         case VLK_TEMP:
  81.                 o << "t" << v.select.sel() - shader::temp_regid_offset;
  82.                 break;
  83.         case VLK_REL_REG:
  84.  
  85.                 o << "A" << v.select;
  86.                 o << "[";
  87.                 o << *v.rel;
  88.                 o << "]";
  89.  
  90.                 o << "_" << v.uid;
  91.  
  92.                 break;
  93.         case VLK_UNDEF:
  94.                 o << "undef";
  95.                 break;
  96.         default:
  97.                 o << v.kind << "?????";
  98.                 break;
  99.         }
  100.  
  101.         if (v.version)
  102.                 o << "." << v.version;
  103.  
  104.         if (dead)
  105.                 o << "}";
  106.  
  107.         if (v.is_global())
  108.                 o << "||";
  109.         if (v.is_fixed())
  110.                 o << "F";
  111.         if (v.is_prealloc())
  112.                 o << "P";
  113.  
  114.         sel_chan g;
  115.  
  116.         if (v.is_rel()) {
  117.                 g = v.array->gpr;
  118.         } else {
  119.                 g = v.gpr;
  120.         }
  121.  
  122.         if (g) {
  123.                 o << "@R" << g.sel() << "." << chans[g.chan()];
  124.         }
  125.  
  126.         return o;
  127. }
  128.  
  129. void value_table::add_value(value* v) {
  130.  
  131.         if (v->gvn_source) {
  132.                 return;
  133.         }
  134.  
  135.         VT_DUMP(
  136.                 sblog << "gvn add_value ";
  137.                 dump::dump_val(v);
  138.         );
  139.  
  140.         value_hash hash = v->hash();
  141.         vt_item & vti = hashtable[hash & size_mask];
  142.         vti.push_back(v);
  143.         ++cnt;
  144.  
  145.         if (v->def && ex.try_fold(v)) {
  146.                 VT_DUMP(
  147.                         sblog << " folded: ";
  148.                         dump::dump_val(v->gvn_source);
  149.                         sblog << "\n";
  150.                 );
  151.                 return;
  152.         }
  153.  
  154.         int n = 0;
  155.         for (vt_item::iterator I = vti.begin(), E = vti.end(); I != E; ++I, ++n) {
  156.                 value *c = *I;
  157.  
  158.                 if (c == v)
  159.                         break;
  160.  
  161.                 if (expr_equal(c, v)) {
  162.                         v->gvn_source = c->gvn_source;
  163.  
  164.                         VT_DUMP(
  165.                                 sblog << " found : equal to ";
  166.                                 dump::dump_val(v->gvn_source);
  167.                                 sblog << "\n";
  168.                         );
  169.                         return;
  170.                 }
  171.         }
  172.  
  173.         v->gvn_source = v;
  174.         VT_DUMP(
  175.                 sblog << " added new\n";
  176.         );
  177. }
  178.  
  179. value_hash value::hash() {
  180.         if (ghash)
  181.                 return ghash;
  182.         if (is_rel())
  183.                 ghash = rel_hash();
  184.         else if (def)
  185.                 ghash = def->hash();
  186.         else
  187.                 ghash = ((uintptr_t)this) | 1;
  188.  
  189.         return ghash;
  190. }
  191.  
  192. value_hash value::rel_hash() {
  193.         value_hash h = rel ? rel->hash() : 0;
  194.         h |= select << 10;
  195.         h |= array->hash();
  196.         return h;
  197. }
  198.  
  199. bool value_table::expr_equal(value* l, value* r) {
  200.         return ex.equal(l, r);
  201. }
  202.  
  203. void value_table::get_values(vvec& v) {
  204.         v.resize(cnt);
  205.  
  206.         vvec::iterator T = v.begin();
  207.  
  208.         for(vt_table::iterator I = hashtable.begin(), E = hashtable.end();
  209.                         I != E; ++I) {
  210.                 T = std::copy(I->begin(), I->end(), T);
  211.         }
  212. }
  213.  
  214. void value::add_use(node* n, use_kind kind, int arg) {
  215.         if (0) {
  216.         sblog << "add_use ";
  217.         dump::dump_val(this);
  218.         sblog << "   =>  ";
  219.         dump::dump_op(n);
  220.         sblog << "     kind " << kind << "    arg " << arg << "\n";
  221.         }
  222.         uses = new use_info(n, kind, arg, uses);
  223. }
  224.  
  225. unsigned value::use_count() {
  226.         use_info *u = uses;
  227.         unsigned c = 0;
  228.         while (u) {
  229.                 ++c;
  230.                 u = u->next;
  231.         }
  232.         return c;
  233. }
  234.  
  235. bool value::is_global() {
  236.         if (chunk)
  237.                 return chunk->is_global();
  238.         return flags & VLF_GLOBAL;
  239. }
  240.  
  241. void value::set_global() {
  242.         assert(is_sgpr());
  243.         flags |= VLF_GLOBAL;
  244.         if (chunk)
  245.                 chunk->set_global();
  246. }
  247.  
  248. void value::set_prealloc() {
  249.         assert(is_sgpr());
  250.         flags |= VLF_PREALLOC;
  251.         if (chunk)
  252.                 chunk->set_prealloc();
  253. }
  254.  
  255. bool value::is_fixed() {
  256.         if (array && array->gpr)
  257.                 return true;
  258.         if (chunk)
  259.                 return chunk->is_fixed();
  260.         return flags & VLF_FIXED;
  261. }
  262.  
  263. void value::fix() {
  264.         if (chunk)
  265.                 chunk->fix();
  266.         flags |= VLF_FIXED;
  267. }
  268.  
  269. bool value::is_prealloc() {
  270.         if (chunk)
  271.                 return chunk->is_prealloc();
  272.         return flags & VLF_PREALLOC;
  273. }
  274.  
  275. void value::delete_uses() {
  276.         use_info *u, *c = uses;
  277.         while (c) {
  278.                 u = c->next;
  279.                 delete c;
  280.                 c = u;
  281.         }
  282.         uses = NULL;
  283. }
  284.  
  285. void ra_constraint::update_values() {
  286.         for (vvec::iterator I = values.begin(), E = values.end(); I != E; ++I) {
  287.                 assert(!(*I)->constraint);
  288.                 (*I)->constraint = this;
  289.         }
  290. }
  291.  
  292. void* sb_pool::allocate(unsigned sz) {
  293.         sz = (sz + SB_POOL_ALIGN - 1) & ~(SB_POOL_ALIGN - 1);
  294.         assert (sz < (block_size >> 6) && "too big allocation size for sb_pool");
  295.  
  296.         unsigned offset = total_size % block_size;
  297.         unsigned capacity = block_size * blocks.size();
  298.  
  299.         if (total_size + sz > capacity) {
  300.                 total_size = capacity;
  301.                 void * nb = malloc(block_size);
  302.                 blocks.push_back(nb);
  303.                 offset = 0;
  304.         }
  305.  
  306.         total_size += sz;
  307.         return ((char*)blocks.back() + offset);
  308. }
  309.  
  310. void sb_pool::free_all() {
  311.         for (block_vector::iterator I = blocks.begin(), E = blocks.end(); I != E;
  312.                         ++I) {
  313.                 free(*I);
  314.         }
  315. }
  316.  
  317. value* sb_value_pool::create(value_kind k, sel_chan regid,
  318.                              unsigned ver) {
  319.         void* np = allocate(aligned_elt_size);
  320.         value *v = new (np) value(size(), k, regid, ver);
  321.         return v;
  322. }
  323.  
  324. void sb_value_pool::delete_all() {
  325.         unsigned bcnt = blocks.size();
  326.         unsigned toffset = 0;
  327.         for (unsigned b = 0; b < bcnt; ++b) {
  328.                 char *bstart = (char*)blocks[b];
  329.                 for (unsigned offset = 0; offset < block_size;
  330.                                 offset += aligned_elt_size) {
  331.                         ((value*)(bstart + offset))->~value();
  332.                         toffset += aligned_elt_size;
  333.                         if (toffset >= total_size)
  334.                                 return;
  335.                 }
  336.         }
  337. }
  338.  
  339. bool sb_bitset::get(unsigned id) {
  340.         assert(id < bit_size);
  341.         unsigned w = id / bt_bits;
  342.         unsigned b = id % bt_bits;
  343.         return (data[w] >> b) & 1;
  344. }
  345.  
  346. void sb_bitset::set(unsigned id, bool bit) {
  347.         assert(id < bit_size);
  348.         unsigned w = id / bt_bits;
  349.         unsigned b = id % bt_bits;
  350.         if (w >= data.size())
  351.                 data.resize(w + 1);
  352.  
  353.         if (bit)
  354.                 data[w] |= (1 << b);
  355.         else
  356.                 data[w] &= ~(1 << b);
  357. }
  358.  
  359. inline bool sb_bitset::set_chk(unsigned id, bool bit) {
  360.         assert(id < bit_size);
  361.         unsigned w = id / bt_bits;
  362.         unsigned b = id % bt_bits;
  363.         basetype d = data[w];
  364.         basetype dn = (d & ~(1 << b)) | (bit << b);
  365.         bool r = (d != dn);
  366.         data[w] = r ? dn : data[w];
  367.         return r;
  368. }
  369.  
  370. void sb_bitset::clear() {
  371.         std::fill(data.begin(), data.end(), 0);
  372. }
  373.  
  374. void sb_bitset::resize(unsigned size) {
  375.         unsigned cur_data_size = data.size();
  376.         unsigned new_data_size = (size + bt_bits - 1) / bt_bits;
  377.  
  378.  
  379.         if (new_data_size != cur_data_size)
  380.                 data.resize(new_data_size);
  381.  
  382.         // make sure that new bits in the existing word are cleared
  383.         if (cur_data_size && size > bit_size && bit_size % bt_bits) {
  384.                 basetype clear_mask = (~(basetype)0u) << (bit_size % bt_bits);
  385.                 data[cur_data_size - 1] &= ~clear_mask;
  386.         }
  387.  
  388.         bit_size = size;
  389. }
  390.  
  391. unsigned sb_bitset::find_bit(unsigned start) {
  392.         assert(start < bit_size);
  393.         unsigned w = start / bt_bits;
  394.         unsigned b = start % bt_bits;
  395.         unsigned sz = data.size();
  396.  
  397.         while (w < sz) {
  398.                 basetype d = data[w] >> b;
  399.                 if (d != 0) {
  400.                         unsigned pos = __builtin_ctz(d) + b + w * bt_bits;
  401.                         return pos;
  402.                 }
  403.  
  404.                 b = 0;
  405.                 ++w;
  406.         }
  407.  
  408.         return bit_size;
  409. }
  410.  
  411. sb_value_set::iterator::iterator(shader& sh, sb_value_set* s, unsigned nb)
  412.         : vp(sh.get_value_pool()), s(s), nb(nb) {}
  413.  
  414. bool sb_value_set::add_set_checked(sb_value_set& s2) {
  415.         if (bs.size() < s2.bs.size())
  416.                 bs.resize(s2.bs.size());
  417.         sb_bitset nbs = bs | s2.bs;
  418.         if (bs != nbs) {
  419.                 bs.swap(nbs);
  420.                 return true;
  421.         }
  422.         return false;
  423. }
  424.  
  425. void r600_sb::sb_value_set::remove_set(sb_value_set& s2) {
  426.         bs.mask(s2.bs);
  427. }
  428.  
  429. bool sb_value_set::add_val(value* v) {
  430.         assert(v);
  431.         if (bs.size() < v->uid)
  432.                 bs.resize(v->uid + 32);
  433.  
  434.         return bs.set_chk(v->uid - 1, 1);
  435. }
  436.  
  437. bool sb_value_set::remove_vec(vvec& vv) {
  438.         bool modified = false;
  439.         for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
  440.                 if (*I)
  441.                         modified |= remove_val(*I);
  442.         }
  443.         return modified;
  444. }
  445.  
  446. void sb_value_set::clear() {
  447.         bs.clear();
  448. }
  449.  
  450. bool sb_value_set::remove_val(value* v) {
  451.         assert(v);
  452.         if (bs.size() < v->uid)
  453.                 return false;
  454.         return bs.set_chk(v->uid - 1, 0);
  455. }
  456.  
  457. bool r600_sb::sb_value_set::add_vec(vvec& vv) {
  458.         bool modified = false;
  459.         for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
  460.                 value *v = *I;
  461.                 if (v)
  462.                         modified |= add_val(v);
  463.         }
  464.         return modified;
  465. }
  466.  
  467. bool r600_sb::sb_value_set::contains(value* v) {
  468.         unsigned b = v->uid - 1;
  469.         if (b < bs.size())
  470.                 return bs.get(v->uid - 1);
  471.         else
  472.                 return false;
  473. }
  474.  
  475. bool sb_value_set::empty() {
  476.         return bs.size() == 0 || bs.find_bit(0) == bs.size();
  477. }
  478.  
  479. void sb_bitset::swap(sb_bitset& bs2) {
  480.         std::swap(data, bs2.data);
  481.         std::swap(bit_size, bs2.bit_size);
  482. }
  483.  
  484. bool sb_bitset::operator ==(const sb_bitset& bs2) {
  485.         if (bit_size != bs2.bit_size)
  486.                 return false;
  487.  
  488.         for (unsigned i = 0, c = data.size(); i < c; ++i) {
  489.                 if (data[i] != bs2.data[i])
  490.                         return false;
  491.         }
  492.         return true;
  493. }
  494.  
  495. sb_bitset& sb_bitset::operator &=(const sb_bitset& bs2) {
  496.         if (bit_size > bs2.bit_size) {
  497.                 resize(bs2.bit_size);
  498.         }
  499.  
  500.         for (unsigned i = 0, c = std::min(data.size(), bs2.data.size()); i < c;
  501.                         ++i) {
  502.                 data[i] &= bs2.data[i];
  503.         }
  504.         return *this;
  505. }
  506.  
  507. sb_bitset& sb_bitset::mask(const sb_bitset& bs2) {
  508.         if (bit_size < bs2.bit_size) {
  509.                 resize(bs2.bit_size);
  510.         }
  511.  
  512.         for (unsigned i = 0, c = data.size(); i < c;
  513.                         ++i) {
  514.                 data[i] &= ~bs2.data[i];
  515.         }
  516.         return *this;
  517. }
  518.  
  519. bool ra_constraint::check() {
  520.         assert(kind == CK_SAME_REG);
  521.  
  522.         unsigned reg = 0;
  523.  
  524.         for (vvec::iterator I = values.begin(), E = values.end(); I != E; ++I) {
  525.                 value *v = *I;
  526.                 if (!v)
  527.                         continue;
  528.  
  529.                 if (!v->gpr)
  530.                         return false;
  531.  
  532.                 if (reg == 0)
  533.                         reg = v->gpr.sel() + 1;
  534.                 else if (reg != v->gpr.sel() + 1)
  535.                         return false;
  536.  
  537.                 if (v->is_chan_pinned()) {
  538.                         if (v->pin_gpr.chan() != v->gpr.chan())
  539.                                 return false;
  540.                 }
  541.         }
  542.         return true;
  543. }
  544.  
  545. bool gpr_array::is_dead() {
  546.         return false;
  547. }
  548.  
  549. } // namespace r600_sb
  550.