LCOV - code coverage report
Current view: top level - src/optimizer - optimizer.cpp (source / functions) Hit Total Coverage
Test: flower-f.info Lines: 57 83 68.7 %
Date: 2022-06-10 00:44:15 Functions: 3 4 75.0 %

          Line data    Source code
       1             : #include "optimizer/optimizer.hpp"
       2             : #include "common/exprtype.hpp"
       3             : #include "optimizer/util.hpp"
       4             : #include <iostream>
       5             : #include <algorithm>
       6             : #include <vector>
       7             : #include <map>
       8             : 
       9          29 : Optimizer::Optimizer(IdentTable * IT, POLIZ * p, bool verb) {
      10          29 :     IdTable = IT;
      11          29 :     poliz = p;
      12          29 :     verbose = verb;
      13          29 : }
      14             : 
      15          29 : void Optimizer::reduceConstants(void) {
      16          29 :     IdentTable * ait = IdTable, *bit = IdTable, *temp;
      17             : 
      18         412 :     while (ait->next != nullptr) {
      19         383 :         bit = ait;
      20        4487 :         while (bit->next != nullptr) {
      21        4104 :             if ((*ait == *bit->next) && (bit->next->isDef())) {
      22        7077 :                 for (int i = 0; i < poliz->getSize(); i++) {
      23        6979 :                     if ((!poliz->getEB()[i]) && (poliz->getProg()[i] == (op_t)bit->next))
      24         101 :                         poliz->getProg()[i] = (op_t) ait;
      25             :                 }
      26          98 :                 if (verbose) {
      27           0 :                     std::cout << "УДАЛЁН ";
      28           0 :                     bit->next->whoami();
      29           0 :                     std::cout << "\n";
      30             :                 }
      31             :                 
      32          98 :                 temp = bit->next;
      33          98 :                 bit->next = bit->next->next;
      34          98 :                 temp->next = nullptr;
      35          98 :                 delete temp;
      36        4006 :             } else bit = bit->next;
      37             :         }
      38         383 :         ait = ait->next;
      39             :     }
      40          29 : }
      41             : 
      42          29 : IdentTable * Optimizer::optimize() {
      43          29 :     reduceConstants();
      44             :     
      45          29 :     CFG.make(poliz);
      46             :     #ifdef DRAW_GRAPH
      47             :     CFG.draw("compiled");
      48             :     #endif
      49          29 :     if (verbose) CFG.info();
      50             : 
      51          58 :     std::vector<flowTree *> optimized = {CFG.head()};
      52          58 :     std::vector<flowTree *> queue = {CFG.head()};
      53          58 :     std::vector<bool> afterCall = {false}; // Нужно собирать возврат
      54             : 
      55          58 :     std::map<int, std::vector<type_t>> funcRets;
      56          58 :     std::vector<type_t> typeOnStack;
      57         116 :     std::vector<std::vector<type_t>> oldStack = {{}};
      58          58 :     std::vector<int> conn; // ID вызванной функции
      59          29 :     std::vector<int> funcHead = {};
      60             : 
      61          87 :     while (queue.size() != 0) {
      62          58 :         DirectedAcyclicGraph DAG(verbose);
      63          58 :         DAG.make(queue.back()->block);
      64             : 
      65          58 :         DAG.commonSubExpr(IdTable);
      66             : 
      67          58 :         typeOnStack = oldStack.front();
      68          58 :         if (afterCall.front()) {
      69           0 :             std::vector<type_t> tail = funcRets[conn.front()];
      70           0 :             typeOnStack.insert(typeOnStack.end(), tail.begin(), tail.begin());
      71           0 :             conn.erase(conn.begin());
      72             :         }
      73          58 :         POLIZ src = DAG.decompose(&typeOnStack);
      74          58 :         src.repr();
      75          58 :         queue.back()->block.clear();
      76          58 :         copyPOLIZ(src, queue.back()->block, 0, src.getSize());
      77             : 
      78          58 :         if (queue.back()->block.endsWithRet()) {
      79           0 :             funcRets[funcHead.back()] = typeOnStack;
      80           0 :             funcHead.pop_back();
      81             :         }
      82             : 
      83          58 :         if (queue.back()->block.endsWithCall()) {
      84           0 :             auto nextB = queue.back()->next;
      85           0 :             auto isTrueB = [](std::pair<flowTree *, char> pair){return pair.second == 1;};
      86           0 :             auto nodeTrueB = std::find_if(nextB.begin(), nextB.end(), isTrueB);
      87           0 :             int connID = nodeTrueB->first->ID;
      88             : 
      89           0 :             for (auto node: queue.back()->next) {
      90           0 :                 if ((node.second == 2) && (find(optimized, node.first) == -1)) {
      91           0 :                     conn.push_back(connID);
      92           0 :                     queue.push_back(node.first);
      93           0 :                     optimized.push_back(node.first);
      94           0 :                     afterCall.push_back(true);
      95           0 :                     oldStack.push_back(typeOnStack);
      96             :                 }
      97             :             }
      98           0 :             for (auto node: queue.back()->next) {
      99           0 :                 if ((node.second == 1) && (find(optimized, node.first) == -1)) {
     100           0 :                         queue.push_back(node.first);
     101           0 :                         optimized.push_back(node.first);
     102           0 :                         afterCall.push_back(false);
     103           0 :                         oldStack.push_back({});
     104           0 :                         funcHead.push_back(connID);
     105             :                 }
     106             :             }
     107             :         } else {
     108         116 :             for (auto node: queue.back()->next) {
     109          58 :                 if (find(optimized, node.first) == -1) {
     110          29 :                     queue.push_back(node.first);
     111          29 :                     optimized.push_back(node.first);
     112          29 :                     afterCall.push_back(false);
     113          29 :                     oldStack.push_back(typeOnStack);
     114             :                 }
     115             :             }
     116             :         }
     117             :         
     118          58 :         queue.pop_back();
     119          58 :         afterCall.erase(afterCall.begin());
     120          58 :         oldStack.erase(oldStack.begin());
     121             :     }
     122             : 
     123          29 :     IdTable = CFG.decompose(IdTable, poliz);
     124             : 
     125             :     #ifdef DRAW_GRAPH
     126             :     CFG.clear();
     127             :     CFG.make(poliz);
     128             :     CFG.draw("optimized");
     129             :     #endif   
     130             : 
     131          58 :     return IdTable; 
     132             : }

Generated by: LCOV version 1.14