LCOV - code coverage report
Current view: top level - src/optimizer - acyclicgraph.cpp (source / functions) Hit Total Coverage
Test: flower-f.info Lines: 27 205 13.2 %
Date: 2022-06-10 00:44:15 Functions: 5 10 50.0 %

          Line data    Source code
       1             : #include "optimizer/acyclicgraph.hpp"
       2             : #include "common/exprtype.hpp"
       3             : #include "optimizer/util.hpp"
       4             : #include <iostream>
       5             : 
       6             : std::vector<DAGRow *> DAGRow::created;
       7             : 
       8           0 : bool DAGRow::isLast(void) const {
       9           0 :     return (lvar == nullptr) && (rvar == nullptr);
      10             : }
      11             : 
      12             : /*
      13             : DAGRow & DAGRow::operator=(const DAGRow & dr) {
      14             :     if (this == &dr) return *this;
      15             : 
      16             :     ident = dr.ident;
      17             :     opcode = dr.opcode;
      18             :     prev = dr.prev;
      19             :     
      20             :     if (dr.lvar != nullptr) {
      21             :         lvar = new DAGRow;
      22             :         *lvar = *dr.lvar;
      23             :     } else lvar = nullptr;
      24             : 
      25             :     if (dr.rvar != nullptr) {
      26             :         rvar = new DAGRow;
      27             :         *rvar = *dr.rvar;
      28             :     } else rvar = nullptr;
      29             : 
      30             :     assigned = dr.assigned;
      31             : 
      32             :     return *this;
      33             : }
      34             : 
      35             : DAGRow::DAGRow(const DAGRow & dr) {
      36             :     ident = dr.ident;
      37             :     opcode = dr.opcode;
      38             :     prev = dr.prev;
      39             :     
      40             :     if (dr.lvar != nullptr) {
      41             :         lvar = new DAGRow;
      42             :         *lvar = *dr.lvar;
      43             :     } else lvar = nullptr;
      44             : 
      45             :     if (dr.rvar != nullptr) {
      46             :         rvar = new DAGRow;
      47             :         *rvar = *dr.rvar;
      48             :     } else rvar = nullptr;
      49             : 
      50             :     assigned = dr.assigned;
      51             : }
      52             : */
      53             : 
      54           0 : bool operator==(DAGRow & a, DAGRow & b) {
      55           0 :     if (&a == &b) return false;
      56             : 
      57           0 :     bool ret = (a.opcode == b.opcode);
      58             : 
      59           0 :     if (a.lvar != b.lvar) {
      60           0 :         if ((a.lvar == nullptr) || (b.lvar == nullptr))
      61           0 :             return false;
      62           0 :         ret = ret && (*a.lvar == *b.lvar);
      63             :     }
      64             : 
      65           0 :     if (a.rvar != b.rvar) {
      66           0 :         if ((a.rvar == nullptr) || (b.rvar == nullptr))
      67           0 :             return false;
      68           0 :         ret = ret && (*a.rvar == *b.rvar);
      69             :     }
      70             : 
      71           0 :     if (a.isLast() && b.isLast())
      72           0 :         return ret && (*a.ident == *b.ident);
      73             : 
      74           0 :     if ((!a.isLast()) && (!b.isLast()))
      75           0 :         return ret;
      76             : 
      77           0 :     return false;
      78             : }
      79             : 
      80          58 : void DirectedAcyclicGraph::stash(POLIZ & p) {
      81          58 :     int s = p.getSize();
      82             : 
      83          58 :     if (s == 0) return;
      84           0 :     if (!p.getEB()[s - 1])
      85           0 :         return;
      86           0 :     if ((operation_t)(p.getProg()[s - 1] & 0xFF) != CALL)
      87           0 :         return;
      88             :     
      89           0 :     IdentTable * paramit = IT_FROM_POLIZ(p, s - 2);
      90           0 :     int paramNum = * static_cast<int *>(paramit->getVal());
      91           0 :     stashed.clear();
      92           0 :     copyPOLIZ(p, stashed, s - paramNum - 2, s);
      93           0 :     for (int i = 0; i < paramNum + 2; i++)
      94           0 :         p.pop();
      95             : }
      96             : 
      97          58 : void DirectedAcyclicGraph::make(POLIZ p) {
      98         116 :     std::vector<std::pair<IdentTable *, DAGRow *>> changed;
      99          58 :     std::pair<IdentTable *, DAGRow *> rep;
     100         116 :     std::vector<DAGRow *> queue;
     101          58 :     stash(p);
     102          58 :     for (int i = 0; i < p.getSize(); i++) {
     103             :         DAGRow * qrow;
     104           0 :         if (p.getEB()[i]) {
     105           0 :             qrow = new DAGRow;
     106           0 :             operation_t op = (operation_t)(p.getProg()[i] & 0xFF);
     107           0 :             type_t rettype = (type_t) ((p.getProg()[i] >> 24) & 0xFF);
     108           0 :             qrow->type = rettype;
     109           0 :             int opnum = operands(op);
     110           0 :             if ((opnum != 0) && (queue.size() != 0)) {
     111           0 :                 qrow->rvar = queue.back();
     112           0 :                 queue.pop_back();
     113           0 :                 if (qrow->rvar->prev == nullptr)
     114           0 :                     qrow->rvar->prev = qrow;
     115           0 :                 opnum--;
     116             :             }
     117           0 :             if ((opnum != 0) && (queue.size() != 0)) {
     118           0 :                 qrow->lvar = queue.back();
     119           0 :                 queue.pop_back();
     120           0 :                 if (qrow->lvar->prev == nullptr)
     121           0 :                     qrow->lvar->prev = qrow;
     122             :                 //opnum--;
     123             :             }
     124           0 :             qrow->opcode = p.getProg()[i];
     125           0 :             queue.push_back(qrow);
     126             : 
     127           0 :             if ((op == ASSIGN) && (qrow->lvar != nullptr) && (qrow->rvar != nullptr)) {
     128           0 :                 if (qrow->rvar->ident == nullptr)
     129           0 :                     qrow->rvar->ident = qrow->lvar->ident;
     130           0 :                 rep = std::make_pair(qrow->lvar->ident, qrow->rvar);
     131           0 :                 changed.emplace(changed.begin(), rep); 
     132             :             }
     133             :             
     134             :         } else {
     135           0 :             int idx = find(changed, IT_FROM_POLIZ(p, i));
     136           0 :             if (idx != -1) {
     137           0 :                 qrow = changed[idx].second;
     138             :             } else {
     139           0 :                 qrow = new DAGRow;
     140           0 :                 qrow->ident = IT_FROM_POLIZ(p, i);
     141             :             }
     142           0 :             queue.push_back(qrow);
     143             :         }
     144             :     }
     145             : 
     146          58 :     for (auto it = queue.begin(); it != queue.end(); it++)
     147           0 :         rows.push_back(*it);
     148          58 : }
     149             : 
     150           0 : void DAGRow::decompose(POLIZ & p, std::vector<DAGRow *> * asd) {
     151           0 :     if ((ident == nullptr) || (!assigned)) {
     152           0 :         if (lvar != nullptr)
     153           0 :             lvar->decompose(p, asd);
     154           0 :         if (rvar != nullptr)
     155           0 :             rvar->decompose(p, asd);
     156           0 :         if (ident != nullptr) {
     157           0 :             asd->push_back(this);
     158           0 :             assigned = true;
     159             :         }
     160             : 
     161           0 :         bool execBit = (opcode != (op_t) NONE);
     162           0 :         type_t ltype = (lvar == NULL)
     163           0 :                                     ? _NONE_
     164           0 :                                     : lvar->type;
     165           0 :         type_t rtype = (rvar == NULL)
     166           0 :                                     ? _NONE_
     167           0 :                                     : rvar->type;
     168             : 
     169           0 :         op_t newOp = (char) type << 24 | (char) ltype << 16;
     170           0 :         newOp |= (char) rtype << 8 | (char) (opcode & 0xFF);
     171           0 :         op_t op = (execBit)
     172           0 :                         ? newOp
     173           0 :                         : (op_t) ident;
     174           0 :         p.push(op, execBit);
     175           0 :     } else p.push((op_t)ident, false);
     176           0 : }
     177             : 
     178           0 : type_t DAGRow::updateType(std::vector<type_t> * typeOnStack) {
     179             :     type_t ltype, rtype;
     180             :     
     181           0 :     switch ((operation_t) (opcode & 0xFF)) {
     182           0 :         case LOAD:
     183           0 :             if ((!typeOnStack->empty()))
     184           0 :                 typeOnStack->pop_back();
     185           0 :             return type;
     186           0 :         default:
     187           0 :             break;
     188             :     }
     189             : 
     190           0 :     if ((lvar != nullptr)) {
     191           0 :         ltype = lvar->updateType(typeOnStack);
     192           0 :     } else ltype = _NONE_;
     193             :     
     194           0 :     if ((rvar != nullptr)) {
     195           0 :         rtype = rvar->updateType(typeOnStack);
     196           0 :     } else rtype = _NONE_;
     197             : 
     198           0 :     if (opcode != (op_t) NONE) {
     199           0 :         operation_t oper = (operation_t) (opcode & 0xFF);
     200             :         try {
     201           0 :             type = expressionType(ltype, rtype, oper);
     202           0 :         } catch (...) {
     203           0 :             if ((ltype == _NONE_) && (!typeOnStack->empty())) {
     204           0 :                 ltype = typeOnStack->back();
     205           0 :                 typeOnStack->pop_back();
     206             :             }
     207           0 :             if ((rtype == _NONE_) && (!typeOnStack->empty())) {
     208           0 :                 rtype = typeOnStack->back();
     209           0 :                 typeOnStack->pop_back();
     210             :             }
     211           0 :             type = expressionType(ltype, rtype, oper);
     212             :         }
     213             :         
     214             :     } else {
     215           0 :         if (ident != nullptr){
     216           0 :             type = ident->getType();
     217             :         } else
     218           0 :             type = _NONE_;
     219             :     }
     220           0 :     return type;
     221             : }
     222             : 
     223          58 : POLIZ DirectedAcyclicGraph::decompose(std::vector<type_t> * typeOnStack) {
     224          58 :     POLIZ ret;
     225         116 :     std::vector<DAGRow *> asd;
     226             :     type_t t;
     227             : 
     228          58 :     for (auto head: rows) {
     229           0 :         t = head->updateType(typeOnStack);
     230           0 :         if (t != _NONE_) typeOnStack->push_back(t);
     231           0 :         head->decompose(ret, &asd);
     232             :         #ifdef DEBUG
     233             :         //ret.repr();
     234             :         //ret.clear();
     235             :         //std::cout << "\n";
     236             :         #endif
     237             :     }
     238             : 
     239          58 :     for (auto x: asd) {
     240           0 :         x->assigned = false;
     241             :     }
     242             : 
     243          58 :     copyPOLIZ(stashed, ret, 0, stashed.getSize());
     244             :     
     245         116 :     return ret;
     246             : }
     247             : 
     248          58 : void DirectedAcyclicGraph::commonSubExpr(IdentTable * IT) {
     249          58 :     std::pair<std::pair<DAGRow *, DAGRow *>, int> fcret;
     250          58 :     std::pair<DAGRow *, DAGRow *> rowc;
     251             : 
     252          58 :     for (int i = 0; i < (signed int)rows.size(); i++) {
     253           0 :         for (int j = i; j < (signed int)rows.size(); j++) {
     254           0 :             fcret = findCopies(rows[i], rows[j], i, j);
     255           0 :             rowc = fcret.first;
     256           0 :             int left = fcret.second;
     257             :             
     258           0 :             if (rowc.first == nullptr)
     259           0 :                 continue;
     260             : 
     261           0 :             if ((!isExpr((operation_t)(rowc.first->opcode & 0xFF))) ||
     262           0 :                 (!isExpr((operation_t)(rowc.first->prev->opcode & 0xFF))))
     263           0 :                 continue;
     264             :             
     265           0 :             rowc.second->assigned = true;
     266             :                 
     267           0 :             if ((operation_t)(rowc.first->prev->opcode & 0xFF) == ASSIGN) {
     268           0 :                 if (rowc.second->prev->lvar == rowc.second)
     269           0 :                     rowc.second->prev->lvar = rowc.first;
     270             :                 else
     271           0 :                     rowc.second->prev->rvar = rowc.first;
     272             :                 
     273           0 :                 if (verbose) {
     274           0 :                     std::cout << "Исключено подвыражение, значение было вычислено в ";
     275           0 :                     rowc.first->prev->lvar->ident->whoami();
     276           0 :                     std::cout << std::endl;
     277             :                 }
     278           0 :                 continue;
     279             :             }
     280             :             
     281           0 :             type_t tt = (type_t) ((rowc.first->opcode >> 24) & 0xFF);
     282           0 :             DAGRow * temprow = new DAGRow;
     283           0 :             temprow->opcode = (char) tt << 16 | (char) tt << 8 | (char) tt;
     284           0 :             temprow->opcode = temprow->opcode << 8  | (char) ASSIGN;
     285           0 :             temprow->rvar = rowc.first;
     286           0 :             temprow->lvar = new DAGRow;
     287             : 
     288           0 :             temprow->lvar->ident = IT->last();
     289           0 :             temprow->rvar->ident = IT->last();
     290           0 :             temprow->lvar->ident->setType(tt);
     291           0 :             temprow->lvar->ident->setOrd(IT->last()->getOrd() + 1);
     292           0 :             IT->last()->next = new IdentTable;
     293             : 
     294           0 :             rows.insert(rows.begin() + left, temprow);
     295           0 :             if (left == i) i++;
     296           0 :             j++;
     297             : 
     298           0 :             if (rowc.first->prev->lvar == rowc.first)
     299           0 :                 rowc.first->prev->lvar = temprow->rvar;
     300             :             else
     301           0 :                 rowc.first->prev->rvar = temprow->rvar;
     302             : 
     303           0 :             if (rowc.second->prev->lvar == rowc.second)
     304           0 :                 rowc.second->prev->lvar = temprow->rvar;
     305             :             else
     306           0 :                 rowc.second->prev->rvar = temprow->rvar;
     307             : 
     308           0 :             if (verbose) {
     309           0 :                 std::cout << "Исключено подвыражение для двух выражений.\n";
     310             :             }
     311             : 
     312             :             #ifdef DEBUG
     313             :             std::cout << "Итерация i = " << i << " j = " << j << ":\n";
     314             :             std::vector<type_t> typeOnStack;
     315             :             decompose(&typeOnStack).repr(false);
     316             :             #endif
     317             :         }
     318             :     }
     319          58 : }
     320             : 
     321             : // Это очень нагруженная функция! Как сделать лучше?
     322             : std::pair<std::pair<DAGRow *, DAGRow *>, int> 
     323           0 : DirectedAcyclicGraph::findCopies(DAGRow * left, DAGRow * right, int a, int b) {
     324             : 
     325           0 :     if ((left == nullptr) && (right != nullptr))
     326           0 :         return findCopies(right->lvar, right->rvar, b, b);
     327             :     
     328           0 :     if ((left != nullptr) && (right == nullptr))
     329           0 :         return findCopies(left->lvar, left->rvar, a, a);
     330             :     
     331           0 :     if ((left == nullptr) || (right == nullptr))
     332           0 :         return std::make_pair(std::make_pair(nullptr, nullptr), 0);
     333             : 
     334           0 :     if ((*left == *right) && (left->prev != nullptr) &&
     335           0 :         (!left->isLast()) && (!right->isLast())) {
     336             :         #ifdef DEBUG
     337             :         POLIZ temp;
     338             :         std::vector<DAGRow *> asd;
     339             :         left->decompose(temp, &asd);
     340             :         for (auto x: asd) x->assigned = false;
     341             :         std::cout << "Новая копия:\n";
     342             :         temp.repr(false);
     343             :         std::cout << "\n";
     344             :         #endif
     345           0 :         return std::make_pair(std::make_pair(left, right), a);
     346             :     }
     347             :         
     348           0 :     std::pair<std::pair<DAGRow *, DAGRow *>, int> ret;
     349           0 :     ret = findCopies(left->lvar, right, a, b);
     350           0 :     if (ret.first.first != nullptr) return ret;
     351           0 :     ret = findCopies(left->rvar, right, a, b);
     352           0 :     if (ret.first.first != nullptr) return ret;
     353           0 :     ret = findCopies(left, right->lvar, a, b);
     354           0 :     if (ret.first.first != nullptr) return ret;
     355           0 :     ret = findCopies(left, right->rvar, a, b);
     356           0 :     if (ret.first.first != nullptr) return ret;
     357             : 
     358           0 :     return std::make_pair(std::make_pair(nullptr, nullptr), 0);
     359             : }
     360             : 
     361          58 : DirectedAcyclicGraph::~DirectedAcyclicGraph() {
     362          58 :     for (DAGRow * node: DAGRow::created)
     363           0 :         delete node;
     364          58 :     DAGRow::created.clear();
     365          58 : }

Generated by: LCOV version 1.14