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 : }