Ignore:
Timestamp:
Oct 31, 2015, 12:20:31 PM (3 years ago)
Author:
nmedfort
Message:

Bug fix for use-def correctness regarding escaping values of If and While nodes.

File:
1 edited

Legend:

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

    r4829 r4856  
    99#include <llvm/Support/Compiler.h>
    1010#include <pablo/printer_pablos.h>
    11 #ifndef NDEBUG
    12 #include <queue>
    13 #include <unordered_set>
    14 #endif
     11#include <iostream>
    1512
    1613namespace pablo {
     
    2724*/
    2825
     26/** ------------------------------------------------------------------------------------------------------------- *
     27 * @brief equals
     28 ** ------------------------------------------------------------------------------------------------------------- */
    2929bool equals(const PabloAST * expr1, const PabloAST * expr2) {
    3030    assert (expr1 && expr2);
     
    8484}
    8585
     86/** ------------------------------------------------------------------------------------------------------------- *
     87 * @brief replaceAllUsesWith
     88 ** ------------------------------------------------------------------------------------------------------------- */
    8689void PabloAST::replaceAllUsesWith(PabloAST * expr) {   
    8790    Statement * user[mUsers.size()];
     
    99102}
    100103
     104/** ------------------------------------------------------------------------------------------------------------- *
     105 * @brief checkForReplacementInEscapedValueList
     106 ** ------------------------------------------------------------------------------------------------------------- */
     107template <class ValueType, class ValueList>
     108inline void Statement::checkForReplacementInEscapedValueList(Statement * branch, PabloAST * const from, PabloAST * const to, ValueList & list) {
     109    if (LLVM_LIKELY(isa<ValueType>(from))) {
     110        auto f = std::find(list.begin(), list.end(), cast<ValueType>(from));
     111        if (LLVM_LIKELY(f != list.end())) {
     112            if (LLVM_LIKELY(isa<ValueType>(to))) {
     113                if (std::find(list.begin(), list.end(), cast<ValueType>(to)) == list.end()) {
     114                    *f = cast<ValueType>(to);
     115                    branch->addUser(to);
     116                } else {
     117                    list.erase(f);
     118                }
     119                branch->removeUser(from);
     120                assert (std::find(list.begin(), list.end(), cast<ValueType>(to)) != list.end());
     121                assert (std::find(branch->user_begin(), branch->user_end(), cast<ValueType>(to)) != branch->user_end());
     122            } else { // replacement error occured
     123                std::string tmp;
     124                raw_string_ostream str(tmp);
     125                str << "cannot replace escaped value ";
     126                PabloPrinter::print(from, str);
     127                str << " with ";
     128                PabloPrinter::print(to, str);
     129                str << " in ";
     130                PabloPrinter::print(branch, str);
     131                throw std::runtime_error(str.str());
     132            }
     133        }               
     134        assert (std::find(list.begin(), list.end(), cast<ValueType>(from)) == list.end());
     135        assert (std::find(branch->user_begin(), branch->user_end(), cast<ValueType>(from)) == branch->user_end());
     136    }
     137}
     138
     139/** ------------------------------------------------------------------------------------------------------------- *
     140 * @brief replaceUsesOfWith
     141 ** ------------------------------------------------------------------------------------------------------------- */
     142void Statement::replaceUsesOfWith(PabloAST * const from, PabloAST * const to) {
     143    for (unsigned i = 0; i != getNumOperands(); ++i) {
     144       if (getOperand(i) == from) {
     145           setOperand(i, to);
     146       }
     147    }
     148    if (LLVM_UNLIKELY(isa<If>(this))) {
     149        checkForReplacementInEscapedValueList<Assign>(this, from, to, cast<If>(this)->getDefined());
     150    } else if (LLVM_UNLIKELY(isa<While>(this))) {
     151        checkForReplacementInEscapedValueList<Next>(this, from, to, cast<While>(this)->getVariants());
     152    }
     153}
     154
     155/** ------------------------------------------------------------------------------------------------------------- *
     156 * @brief setOperand
     157 ** ------------------------------------------------------------------------------------------------------------- */
    101158void Statement::setOperand(const unsigned index, PabloAST * const value) {
    102159    assert (value);
    103160    assert (index < getNumOperands());
    104     assert (noRecursiveOperand(value));
    105161    PabloAST * const priorValue = getOperand(index);
    106162    if (LLVM_UNLIKELY(priorValue == value)) {
     
    124180}
    125181
     182/** ------------------------------------------------------------------------------------------------------------- *
     183 * @brief insertBefore
     184 ** ------------------------------------------------------------------------------------------------------------- */
    126185void Statement::insertBefore(Statement * const statement) {
    127186    if (LLVM_UNLIKELY(statement == this)) {
     
    151210}
    152211
     212/** ------------------------------------------------------------------------------------------------------------- *
     213 * @brief insertAfter
     214 ** ------------------------------------------------------------------------------------------------------------- */
    153215void Statement::insertAfter(Statement * const statement) {
    154216    if (LLVM_UNLIKELY(statement == this)) {
     
    178240}
    179241
     242/** ------------------------------------------------------------------------------------------------------------- *
     243 * @brief removeFromParent
     244 ** ------------------------------------------------------------------------------------------------------------- */
    180245Statement * Statement::removeFromParent() {
    181246    Statement * next = mNext;
     
    207272}
    208273
     274/** ------------------------------------------------------------------------------------------------------------- *
     275 * @brief eraseFromParent
     276 ** ------------------------------------------------------------------------------------------------------------- */
    209277Statement * Statement::eraseFromParent(const bool recursively) {
    210278    // remove this statement from its operands' users list
     
    281349}
    282350
     351/** ------------------------------------------------------------------------------------------------------------- *
     352 * @brief replaceWith
     353 ** ------------------------------------------------------------------------------------------------------------- */
    283354Statement * Statement::replaceWith(PabloAST * const expr, const bool rename, const bool recursively) {
    284355    assert (expr);
     
    296367}
    297368
    298 #ifndef NDEBUG
    299 bool Statement::noRecursiveOperand(const PabloAST * const operand) {
    300     if (const Statement * stmt = dyn_cast<Statement>(operand)) {
    301         std::queue<const Statement *> Q;
    302         std::unordered_set<const PabloAST *> V;
    303         V.insert(stmt);
    304         for (;;) {
    305             if (stmt == this) {
    306                 return false;
    307             }
    308             for (unsigned i = 0; i != stmt->getNumOperands(); ++i) {
    309                 const PabloAST * op = stmt->getOperand(i);               
    310                 if (isa<Statement>(op) && V.count(op) == 0) {
    311                     Q.push(cast<Statement>(op));
    312                     V.insert(op);
    313                 }
    314             }
    315             if (LLVM_UNLIKELY(Q.empty())) {
    316                 break;
    317             }
    318             stmt = Q.front();
    319             Q.pop();
    320         }
    321     }
    322     return true;
    323 }
    324 #endif
    325 
     369/** ------------------------------------------------------------------------------------------------------------- *
     370 * @brief contains
     371 ** ------------------------------------------------------------------------------------------------------------- */
    326372bool StatementList::contains(Statement * const statement) {
    327373    for (Statement * stmt : *this) {
Note: See TracChangeset for help on using the changeset viewer.