Ignore:
Timestamp:
Nov 24, 2015, 4:27:35 PM (4 years ago)
Author:
nmedfort
Message:

More work on n-ary operations.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/passes/flattenassociativedfg.cpp

    r4878 r4880  
    66#include <boost/graph/adjacency_list.hpp>
    77#include <pablo/analysis/pabloverifier.hpp>
    8 
    9 #include <boost/graph/strong_components.hpp>
     8#include <pablo/optimizers/distributivepass.h>
     9
     10
    1011#include <pablo/printer_pablos.h>
    1112#include <iostream>
     
    109110        std::sort(extractedVar->begin(), extractedVar->end());
    110111        var->addOperand(block->createNot(extractedVar));
    111         std::sort(var->begin(), var->end());
    112     }
    113 }
    114 
    115 /** ------------------------------------------------------------------------------------------------------------- *
    116  * @brief removeCommonCalculation
    117  ** ------------------------------------------------------------------------------------------------------------- */
    118 inline void FlattenAssociativeDFG::removeCommonCalculation(Assign * const def) {
     112    }
     113}
     114
     115/** ------------------------------------------------------------------------------------------------------------- *
     116 * @brief removeCommonLiterals
     117 ** ------------------------------------------------------------------------------------------------------------- */
     118inline void FlattenAssociativeDFG::removeCommonLiterals(Assign * const def) {
    119119    PabloAST * op = def->getOperand(0);
    120120    if (isa<And>(op) || isa<Or>(op) || isa<Xor>(op)) {
    121         Variadic * const var = cast<Variadic>(op);
    122         std::vector<PabloAST *> common(var->begin(), var->end());
    123         std::vector<PabloAST *> temp;
    124         temp.reserve(common.size());
    125         for (PabloAST * user : def->users()) {
    126             if (user->getClassTypeId() != var->getClassTypeId()) {
    127                 if (isa<If>(user)) {
    128                     continue;
    129                 }
    130                 return;
     121        removeCommonLiterals(def, cast<Variadic>(op));
     122    }
     123}
     124
     125/** ------------------------------------------------------------------------------------------------------------- *
     126 * @brief removeCommonLiterals
     127 ** ------------------------------------------------------------------------------------------------------------- */
     128void FlattenAssociativeDFG::removeCommonLiterals(Statement * input, Variadic * var) {
     129    std::vector<PabloAST *> common(var->begin(), var->end());
     130    std::vector<PabloAST *> temp;
     131    temp.reserve(common.size());
     132    for (PabloAST * user : input->users()) {
     133        if (user->getClassTypeId() != var->getClassTypeId()) {
     134            if (isa<If>(user) && (input != cast<If>(user)->getCondition())) {
     135                continue;
    131136            }
    132             std::set_intersection(common.begin(), common.end(), cast<Variadic>(user)->begin(), cast<Variadic>(user)->end(), std::back_inserter(temp));
    133             common.swap(temp);
    134             temp.clear();
    135         }
    136         for (PabloAST * op : common) {
    137             for (unsigned i = 0; i != var->getNumOperands(); ++i) {
    138                 if (var->getOperand(i) == op) {
    139                     var->removeOperand(i);
    140                     break;
    141                 }
    142             }
     137            return;
     138        }
     139        std::set_intersection(common.begin(), common.end(), cast<Variadic>(user)->begin(), cast<Variadic>(user)->end(), std::back_inserter(temp));
     140        common.swap(temp);
     141        temp.clear();
     142    }
     143    for (PabloAST * op : common) {
     144        var->removeOperand(op);
     145    }
     146}
     147
     148/** ------------------------------------------------------------------------------------------------------------- *
     149 * @brief removeCommonLiterals
     150 ** ------------------------------------------------------------------------------------------------------------- */
     151inline void FlattenAssociativeDFG::removeCommonLiterals(PabloBlock * const block) {
     152    for (Statement * stmt : *block) {
     153        if (isa<If>(stmt) || isa<While>(stmt)) {
     154            removeCommonLiterals(isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody());
     155        } else if (isa<And>(stmt) || isa<Or>(stmt)) {
     156            removeCommonLiterals(cast<Variadic>(stmt), cast<Variadic>(stmt));
     157        } else if (isa<Assign>(stmt)) {
     158            removeCommonLiterals(cast<Assign>(stmt));
    143159        }
    144160    }
     
    148164 * @brief extract
    149165 ** ------------------------------------------------------------------------------------------------------------- */
    150 void FlattenAssociativeDFG::extract(PabloBlock * const block) {
    151     Statement * stmt = block->front();
    152     while (stmt) {
     166inline void FlattenAssociativeDFG::extract(PabloBlock * const block) {
     167    for (Statement * stmt : *block) {
    153168        if (isa<If>(stmt) || isa<While>(stmt)) {
    154169            extract(isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody());
    155170        } else if (isa<And>(stmt) || isa<Or>(stmt)) {
    156171            extractNegationsOutwards(cast<Variadic>(stmt), block);
    157         } else if (isa<Assign>(stmt)) {
    158             removeCommonCalculation(cast<Assign>(stmt));
    159         }
    160         stmt = stmt->getNextNode();
     172        }
    161173    }
    162174}
     
    167179void FlattenAssociativeDFG::transform(PabloFunction & function) {
    168180
    169     FlattenAssociativeDFG::flatten(function.getEntryBlock());
    170     #ifndef NDEBUG
    171     PabloVerifier::verify(function, "post-flatten");
    172     #endif
    173     Simplifier::optimize(function);
    174 
    175     FlattenAssociativeDFG::extract(function.getEntryBlock());
    176     #ifndef NDEBUG
    177     PabloVerifier::verify(function, "post-extract");
    178     #endif
    179     Simplifier::optimize(function);
    180 
    181 }
    182 
    183 }
     181    for (;;) {
     182
     183        FlattenAssociativeDFG::flatten(function.getEntryBlock());
     184        #ifndef NDEBUG
     185        PabloVerifier::verify(function, "post-flatten");
     186        #endif
     187        FlattenAssociativeDFG::removeCommonLiterals(function.getEntryBlock());
     188        #ifndef NDEBUG
     189        PabloVerifier::verify(function, "post-remove-common-literals");
     190        #endif
     191
     192        Simplifier::optimize(function);
     193
     194        const bool distributed = DistributivePass::optimize(function);
     195
     196        FlattenAssociativeDFG::extract(function.getEntryBlock());
     197        #ifndef NDEBUG
     198        PabloVerifier::verify(function, "post-extract");
     199        #endif
     200        Simplifier::optimize(function);
     201
     202        if (distributed == 0) {
     203            break;
     204        }
     205    }
     206
     207    if (DistributivePass::optimize(function)) {
     208        throw std::runtime_error("Some distributions remained!");
     209    }
     210
     211}
     212
     213}
Note: See TracChangeset for help on using the changeset viewer.