source: icGREP/icgrep-devel/icgrep/pablo/passes/flattenassociativedfg.cpp @ 4876

Last change on this file since 4876 was 4876, checked in by nmedfort, 4 years ago

More work towards n-ary And/Or/Xor? functions.

File size: 4.2 KB
Line 
1#include "flattenassociativedfg.h"
2
3#include <pablo/codegenstate.h>
4#include <pablo/optimizers/pablo_simplifier.hpp>
5#include <pablo/analysis/pabloverifier.hpp>
6
7namespace pablo {
8
9/** ------------------------------------------------------------------------------------------------------------- *
10 * @brief flatten
11 ** ------------------------------------------------------------------------------------------------------------- */
12inline bool FlattenAssociativeDFG::flatten(Variadic * const var, PabloBlock * const block) {
13    bool modified = false;
14    for (;;) {
15        bool unmodified = true;
16        for (unsigned i = 0; i < var->getNumOperands(); ) {
17            PabloAST * const op = var->getOperand(i);
18            if ((op->getNumUses() == 1) && (op->getClassTypeId() == var->getClassTypeId()) && (cast<Variadic>(op)->getParent() == block)) {
19                var->removeOperand(i);
20                for (unsigned j = 0; j != cast<Variadic>(op)->getNumOperands(); ++j) {
21                    var->addOperand(cast<Variadic>(op)->getOperand(j));
22                }
23                assert (op->getNumUses() == 0);
24                cast<Variadic>(op)->eraseFromParent(true);
25                unmodified = false;
26                modified = true;
27                continue;
28            }
29            ++i;
30        }
31        if (unmodified) {
32            break;
33        }
34    }
35    return modified;
36}
37
38/** ------------------------------------------------------------------------------------------------------------- *
39 * @brief flatten
40 ** ------------------------------------------------------------------------------------------------------------- */
41inline bool FlattenAssociativeDFG::flatten(PabloBlock * const block) {
42    bool modified = false;
43    Statement * stmt = block->front();
44    while (stmt) {
45        if (isa<And>(stmt) || isa<Or>(stmt) || isa<Xor>(stmt)) {
46            Variadic * var = cast<Variadic>(stmt);
47            if (flatten(var, block)) {
48                modified = true;
49                if (PabloAST * replacement = Simplifier::foldReassociativeFunction(var, block)) {
50                    stmt = stmt->replaceWith(replacement);
51                    continue;
52                }
53            }
54        }
55        stmt = stmt->getNextNode();
56    }
57    return modified;
58}
59
60/** ------------------------------------------------------------------------------------------------------------- *
61 * @brief factorize
62 ** ------------------------------------------------------------------------------------------------------------- */
63inline bool FlattenAssociativeDFG::factorize(PabloBlock * const block) {
64    bool modified = false;
65    Statement * stmt = block->front();
66    while (stmt) {
67        if (isa<And>(stmt) || isa<Or>(stmt) || isa<Xor>(stmt)) {
68            // Does this function share two operands with another function of the same type?
69            // If so, pull them out of both functions.
70            Variadic * var = cast<Variadic>(stmt);
71            for (unsigned i = 1; i < var->getNumOperands(); ++i) {
72                for (unsigned j = 0; j != i; ++j) {
73
74                }
75            }
76        }
77        stmt = stmt->getNextNode();
78    }
79    return modified;
80}
81
82
83/** ------------------------------------------------------------------------------------------------------------- *
84 * @brief traverse
85 ** ------------------------------------------------------------------------------------------------------------- */
86void FlattenAssociativeDFG::traverse(PabloBlock * const block) {
87    for (Statement * stmt : *block) {
88        if (isa<If>(stmt) || isa<While>(stmt)) {
89            traverse(isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody());
90        }
91    }
92    flatten(block);
93}
94
95/** ------------------------------------------------------------------------------------------------------------- *
96 * @brief process
97 ** ------------------------------------------------------------------------------------------------------------- */
98void FlattenAssociativeDFG::process(PabloFunction & function) {
99    FlattenAssociativeDFG::traverse(function.getEntryBlock());
100//    #ifndef NDEBUG
101    PabloVerifier::verify(function, "post-flatten-associative-dfg");
102//    #endif
103    Simplifier::optimize(function);
104}
105
106}
Note: See TracBrowser for help on using the repository browser.