Ignore:
Timestamp:
Nov 6, 2016, 8:37:11 PM (3 years ago)
Author:
nmedfort
Message:

Initial work on adding types to PabloAST and mutable Var objects.

File:
1 edited

Legend:

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

    r5160 r5202  
    66
    77#include <pablo/codegenstate.h>
    8 #include <iostream>
    98#include <pablo/printer_pablos.h>
    109
    1110namespace pablo {
    1211
    13 inline PabloAST * PabloBlock::renameNonNamedNode(PabloAST * expr, const std::string && prefix) {
    14     if (Statement * stmt = dyn_cast<Statement>(expr)) {
    15         if (stmt->getName()->isGenerated()) {
    16             stmt->setName(makeName(prefix, false));
    17         }
    18     }
    19     return expr;
    20 }
    21 
     12/// UNARY CREATE FUNCTIONS
     13///
     14
     15Call * PabloBlock::createCall(PabloAST * prototype, const std::vector<PabloAST *> &) {
     16    assert (prototype);
     17    return insertAtInsertionPoint(new Call(prototype));
     18}
     19
     20Count * PabloBlock::createCount(PabloAST * expr) {
     21    return insertAtInsertionPoint(new Count(expr, makeName("count")));
     22}
     23
     24Count * PabloBlock::createCount(PabloAST * const expr, const std::string & prefix)  {
     25    return insertAtInsertionPoint(new Count(expr, makeName(prefix)));
     26}
     27
     28Not * PabloBlock::createNot(PabloAST * expr, String * name) {
     29    assert (expr);
     30    if (name == nullptr) {
     31        name = makeName("not");
     32    }
     33    return insertAtInsertionPoint(new Not(expr, name));
     34}
     35
     36Var * PabloBlock::createVar(PabloAST * name, Type * type) {
     37    if (type == nullptr) {
     38        type = getStreamTy();
     39    }
     40    if (LLVM_UNLIKELY(name == nullptr || !isa<String>(name))) {
     41        throw std::runtime_error("Var objects must have a String name");
     42    }
     43    return mParent->makeVariable(name, type);
     44}
     45
     46InFile * PabloBlock::createInFile(PabloAST * expr, String * name) {
     47    assert (expr);
     48    if (name == nullptr) {
     49        name = makeName("inFile");
     50    }
     51    return insertAtInsertionPoint(new InFile(expr, name));
     52}
     53
     54AtEOF * PabloBlock::createAtEOF(PabloAST * expr, String * name) {
     55    assert (expr);
     56    if (name == nullptr) {
     57        name = makeName("atEOF");
     58    }
     59    return insertAtInsertionPoint(new AtEOF(expr, name));
     60}
     61   
     62   
     63/// BINARY CREATE FUNCTIONS
     64
     65Advance * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount, String * name) {
     66    if (name == nullptr) {
     67        name = makeName("advance");
     68    }
     69    return insertAtInsertionPoint(new Advance(expr, shiftAmount, name));
     70}
     71
     72Lookahead * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount, String * name) {
     73    if (name == nullptr) {
     74        name = makeName("lookahead");
     75    }
     76    return insertAtInsertionPoint(new Lookahead(expr, shiftAmount, name));
     77}
     78
     79Extract * PabloBlock::createExtract(PabloAST * array, PabloAST * index, String * name) {
     80    assert (array && index);
     81    if (LLVM_LIKELY(isa<ArrayType>(array->getType()))) {
     82        if (name == nullptr) {
     83            std::string tmp;
     84            raw_string_ostream out(tmp);
     85            PabloPrinter::print(array, out);
     86            PabloPrinter::print(index, out);
     87            name = makeName(out.str());
     88        }
     89        return insertAtInsertionPoint(new Extract(array, index, name));
     90    }
     91    std::string tmp;
     92    raw_string_ostream out(tmp);
     93    out << "cannot extract element from ";
     94    array->print(out);
     95    out << ": type is not a valid ArrayType";
     96    throw std::runtime_error(out.str());
     97}
     98
     99And * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, String * name) {
     100    if (name == nullptr) {
     101        name = makeName("and");
     102    }
     103    return insertAtInsertionPoint(new And(expr1->getType(), expr1, expr2, name));
     104}
     105
     106And * PabloBlock::createAnd(Type * const type, const unsigned reserved, String * name) {
     107    if (name == nullptr) {
     108        name = makeName("and");
     109    }
     110    return insertAtInsertionPoint(new And(type, reserved, name));
     111}
     112
     113Or * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, String * name) {
     114    if (name == nullptr) {
     115        name = makeName("or");
     116    }
     117    return insertAtInsertionPoint(new Or(expr1->getType(), expr1, expr2, name));
     118}
     119
     120Or * PabloBlock::createOr(Type * const type, const unsigned reserved, String * name) {
     121    if (name == nullptr) {
     122        name = makeName("or");
     123    }
     124    return insertAtInsertionPoint(new Or(type, reserved, name));
     125}
     126
     127Xor * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, String * name) {
     128    if (name == nullptr) {
     129        name = makeName("xor");
     130    }
     131    return insertAtInsertionPoint(new Xor(expr1->getType(), expr1, expr2, name));
     132}
     133
     134Xor * PabloBlock::createXor(Type * const type, const unsigned reserved, String * name) {
     135    if (name == nullptr) {
     136        name = makeName("xor");
     137    }
     138    return insertAtInsertionPoint(new Xor(type, reserved, name));
     139}
     140
     141Assign * PabloBlock::createAssign(PabloAST * const var, PabloAST * const value) {
     142    return insertAtInsertionPoint(new Assign(var, value));
     143}
     144
     145MatchStar * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, String * name) {
     146    if (name == nullptr) {
     147        name = makeName("matchstar");
     148    }
     149    return insertAtInsertionPoint(new MatchStar(marker, charclass, name));
     150}
     151
     152ScanThru * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, String * name) {
     153    if (name == nullptr) {
     154        name = makeName("scanthru");
     155    }
     156    return insertAtInsertionPoint(new ScanThru(from, thru, name));
     157}
     158
     159If * PabloBlock::createIf(PabloAST * condition, PabloBlock * body) {
     160    assert (condition);
     161    If * const node = insertAtInsertionPoint(new If(condition, body));
     162    body->setBranch(node);
     163    return node;
     164}
     165
     166While * PabloBlock::createWhile(PabloAST * condition, PabloBlock * body) {
     167    assert (condition);
     168    While * const node = insertAtInsertionPoint(new While(condition, body));
     169    body->setBranch(node);
     170    return node;
     171}
     172
     173/// TERNARY CREATE FUNCTION
     174
     175Sel * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, String * name) {
     176    if (name == nullptr) {
     177        name = makeName("sel");
     178    }
     179    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, name));
     180}
     181
     182/** ------------------------------------------------------------------------------------------------------------- *
     183 * @brief insert
     184 ** ------------------------------------------------------------------------------------------------------------- */
    22185void PabloBlock::insert(Statement * const statement) {
    23186    assert (statement);
     
    38201}
    39202
    40 /// UNARY CREATE FUNCTIONS
    41 
    42 Assign * PabloBlock::createAssign(const std::string && prefix, PabloAST * const expr)  {
    43     assert ("Assign expression cannot be null!" && expr);
    44     return insertAtInsertionPoint(new Assign(expr, makeName(prefix, false)));
    45 }
    46 
    47 PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
    48     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    49     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
    50         return expr;
    51     }
    52     return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName("advance")));
    53 }
    54 
    55 PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
    56     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    57     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
    58         return expr;
    59     }
    60     return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName(prefix, false)));
    61 }
    62 
    63 PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount) {
    64     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    65     if (isa<Zeroes>(expr) || shiftAmount == 0) {
    66         return expr;
    67     }
    68     return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName("advance")));
    69 }
    70 
    71 PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
    72     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    73     if (isa<Zeroes>(expr) || shiftAmount == 0) {
    74         return renameNonNamedNode(expr, std::move(prefix));
    75     }
    76     return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName(prefix, false)));
    77 }
    78 
    79 Count * PabloBlock::createCount(const std::string counterName, PabloAST * const expr)  {
    80     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    81     return insertAtInsertionPoint(new Count(expr, makeName(counterName, false)));
    82 }
    83    
    84 
    85 PabloAST * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount) {
    86     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
    87         return expr;
    88     }
    89     return insertAtInsertionPoint(new Lookahead(expr, shiftAmount, makeName("lookahead")));
    90 }
    91 
    92 PabloAST * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
    93     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    94     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
    95         return expr;
    96     }
    97     return insertAtInsertionPoint(new Lookahead(expr, shiftAmount, makeName(prefix, false)));
    98 }
    99 
    100 PabloAST * PabloBlock::createLookahead(PabloAST * expr, const Integer::Type shiftAmount) {
    101     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    102     if (isa<Zeroes>(expr) || shiftAmount == 0) {
    103         return expr;
    104     }
    105     return insertAtInsertionPoint(new Lookahead(expr, getInteger(shiftAmount), makeName("lookahead")));
    106 }
    107 
    108 PabloAST * PabloBlock::createLookahead(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
    109     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    110     if (isa<Zeroes>(expr) || shiftAmount == 0) {
    111         return renameNonNamedNode(expr, std::move(prefix));
    112     }
    113     return insertAtInsertionPoint(new Lookahead(expr, getInteger(shiftAmount), makeName(prefix, false)));
    114 }
    115 
    116 Call * PabloBlock::createCall(PabloAST * prototype, const std::vector<PabloAST *> &) {
    117     assert (prototype);
    118     return insertAtInsertionPoint(new Call(prototype));
    119 }
    120 
    121 
    122 PabloAST * PabloBlock::createNot(PabloAST * expr) {
    123     assert (expr);
    124     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    125     if (isa<Ones>(expr)) {
    126         return createZeroes(expr->getType());
    127     }
    128     else if (isa<Zeroes>(expr)){
    129         return createOnes(expr->getType());
    130     }
    131     else if (Not * not1 = dyn_cast<Not>(expr)) {
    132         return not1->getOperand(0);
    133     }
    134     return insertAtInsertionPoint(new Not(expr, makeName("not_")));
    135 }
    136 
    137 PabloAST * PabloBlock::createNot(PabloAST * expr, const std::string prefix) {
    138     assert (expr);
    139     PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    140     if (isa<Ones>(expr)) {
    141         return createZeroes(expr->getType());
    142     }
    143     else if (isa<Zeroes>(expr)){
    144         return createOnes(expr->getType());
    145     }
    146     else if (Not * not1 = dyn_cast<Not>(expr)) {       
    147         return renameNonNamedNode(not1->getOperand(0), std::move(prefix));
    148     }
    149     return insertAtInsertionPoint(new Not(expr, makeName(prefix, false)));
    150 }
    151 
    152 Var * PabloBlock::createVar(PabloAST * name, const PabloType * const type) {
    153     assert (name);
    154     return new Var(name, type);
    155 }
    156 
    157 PabloAST * PabloBlock::createInFile(PabloAST * expr) {
    158     assert (expr);
    159     return insertAtInsertionPoint(new InFile(expr, makeName("inFile_")));
    160 }
    161 
    162 PabloAST * PabloBlock::createInFile(PabloAST * expr, const std::string prefix) {
    163     assert (expr);
    164     return insertAtInsertionPoint(new InFile(expr, makeName(prefix, false)));
    165 }
    166 
    167 
    168 PabloAST * PabloBlock::createAtEOF(PabloAST * expr) {
    169     assert (expr);
    170     return insertAtInsertionPoint(new AtEOF(expr, makeName("atEOF_")));
    171 }
    172 
    173 PabloAST * PabloBlock::createAtEOF(PabloAST * expr, const std::string prefix) {
    174     assert (expr);
    175     return insertAtInsertionPoint(new AtEOF(expr, makeName(prefix, false)));
    176 }
    177    
    178    
    179     /// BINARY CREATE FUNCTIONS
    180 
    181 Next * PabloBlock::createNext(Assign * assign, PabloAST * expr) {
    182     assert (assign && expr);
    183     return insertAtInsertionPoint(new Next(assign, expr));
    184 }
    185 
    186 PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass) {
    187     throwIfNonMatchingTypes(marker, charclass);
    188     if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
    189         return marker;
    190     }
    191     return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName("matchstar")));
    192 }
    193 
    194 PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const std::string prefix) {   
    195     throwIfNonMatchingTypes(marker, charclass);
    196     throwIfNonMatchingType(marker, PabloType::Stream);
    197     if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
    198         return renameNonNamedNode(marker, std::move(prefix));
    199     }
    200     return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName(prefix, false)));
    201 }
    202 
    203 PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {   
    204     throwIfNonMatchingTypes(from, thru);
    205     throwIfNonMatchingType(from, PabloType::Stream);
    206     if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
    207         return from;
    208     }
    209     return insertAtInsertionPoint(new ScanThru(from, thru, makeName("scanthru")));
    210 }
    211 
    212 PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, const std::string prefix) {
    213     throwIfNonMatchingTypes(from, thru);
    214     throwIfNonMatchingType(from, PabloType::Stream);
    215     if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {       
    216         return renameNonNamedNode(from, std::move(prefix));
    217     }
    218     return insertAtInsertionPoint(new ScanThru(from, thru, makeName(prefix, false)));
    219 }
    220 
    221 template<typename Type>
    222 static inline Type * isBinary(PabloAST * expr) {
    223     if (isa<Type>(expr) && cast<Type>(expr)->getNumOperands() == 2) {
    224         return cast<Type>(expr);
    225     }
    226     return nullptr;
    227 }
    228 
    229 PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
    230     throwIfNonMatchingTypes(expr1, expr2);
    231     if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
    232         return expr2;
    233     } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
    234         return expr1;
    235     } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    236         if (Not * not2 = dyn_cast<Not>(expr2)) {
    237             return createNot(createOr(not1->getOperand(0), not2->getOperand(0)));
    238         } else if (equals(not1->getOperand(0), expr2)) {
    239             return createZeroes(expr1->getType());
    240         }
    241     } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    242         if (equals(expr1, not2->getOperand(0))) {
    243             return createZeroes(expr1->getType());
    244         }
    245     } else if (Or * or1 = isBinary<Or>(expr1)) {
    246         if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
    247             return expr2;
    248         }
    249     } else if (Or * or2 = isBinary<Or>(expr2)) {
    250         if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
    251             return expr1;
    252         }
    253     }
    254     return insertAtInsertionPoint(new And(expr1->getType(), expr1, expr2, makeName("and_")));
    255 }
    256 
    257 PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    258     throwIfNonMatchingTypes(expr1, expr2);
    259     if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
    260         return renameNonNamedNode(expr2, std::move(prefix));
    261     }
    262     else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
    263         return renameNonNamedNode(expr1, std::move(prefix));
    264     } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    265         if (Not * not2 = dyn_cast<Not>(expr2)) {
    266             return createNot(createOr(not1->getOperand(0), not2->getOperand(0)), prefix);
    267         }
    268         else if (equals(not1->getOperand(0), expr2)) {
    269             return createZeroes(expr1->getType());
    270         }
    271     } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    272         if (equals(expr1, not2->getOperand(0))) {
    273             return createZeroes(expr1->getType());
    274         }
    275     } else if (Or * or1 = isBinary<Or>(expr1)) {
    276         if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
    277             return expr2;
    278         }
    279     } else if (Or * or2 = isBinary<Or>(expr2)) {
    280         if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
    281             return expr1;
    282         }
    283     }
    284     return insertAtInsertionPoint(new And(expr1->getType(), expr1, expr2, makeName(prefix, false)));
    285 }
    286 
    287 And * PabloBlock::createAnd(const PabloType * const type, const unsigned reserved) {
    288     return insertAtInsertionPoint(new And(type, reserved, makeName("and_")));
    289 }
    290 
    291 And * PabloBlock::createAnd(const PabloType * const type, const unsigned reserved, const std::string prefix) {
    292     return insertAtInsertionPoint(new And(type, reserved, makeName(prefix, false)));
    293 }
    294 
    295 And * PabloBlock::createAnd(const PabloType * const type, std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end) {
    296     return insertAtInsertionPoint(new And(type, begin, end, makeName("and_")));
    297 }
    298 
    299 And * PabloBlock::createAnd(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end) {
    300     return insertAtInsertionPoint(new And(type, begin, end, makeName("and_")));
    301 }
    302 
    303 PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
    304     throwIfNonMatchingTypes(expr1, expr2);
    305     if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    306         return expr2;
    307     }
    308     if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
    309         return expr1;
    310     } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    311         // ¬a√b = ¬¬(¬a √ b) = ¬(a ∧ ¬b)
    312         return createNot(createAnd(not1->getOperand(0), createNot(expr2)));
    313     } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    314         // a√¬b = ¬¬(¬b √ a) = ¬(b ∧ ¬a)
    315         return createNot(createAnd(not2->getOperand(0), createNot(expr1)));
    316     } else if (equals(expr1, expr2)) {
    317         return expr1;
    318     } else if (And * and1 = isBinary<And>(expr1)) {
    319         if (And * and2 = isBinary<And>(expr2)) {
    320             PabloAST * const expr1a = and1->getOperand(0);
    321             PabloAST * const expr1b = and1->getOperand(1);
    322             PabloAST * const expr2a = and2->getOperand(0);
    323             PabloAST * const expr2b = and2->getOperand(1);
    324             //These optimizations factor out common components that can occur when sets are formed by union
    325             //(e.g., union of [a-z] and [A-Z].
    326             if (equals(expr1a, expr2a)) {
    327                 return createAnd(expr1a, createOr(expr1b, expr2b));
    328             } else if (equals(expr1b, expr2b)) {
    329                 return createAnd(expr1b, createOr(expr1a, expr2a));
    330             } else if (equals(expr1a, expr2b)) {
    331                 return createAnd(expr1a, createOr(expr1b, expr2a));
    332             } else if (equals(expr1b, expr2a)) {
    333                 return createAnd(expr1b, createOr(expr1a, expr2b));
    334             }
    335         } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
    336             // (a ∧ b) √ a = a
    337             return expr2;
    338         }
    339     } else if (And * and2 = isBinary<And>(expr2)) {
    340         if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
    341             return expr1;
    342         }
    343     }
    344     return insertAtInsertionPoint(new Or(expr1->getType(), expr1, expr2, makeName("or_")));
    345 }
    346 
    347 PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    348     throwIfNonMatchingTypes(expr1, expr2);
    349     if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    350         return renameNonNamedNode(expr2, std::move(prefix));
    351     }
    352     else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
    353         return renameNonNamedNode(expr1, std::move(prefix));
    354     } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    355         // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
    356         return createNot(createAnd(not1->getOperand(0), createNot(expr2)), prefix);
    357     } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    358         // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
    359         return createNot(createAnd(not2->getOperand(0), createNot(expr1)), prefix);
    360     } else if (And * and1 = isBinary<And>(expr1)) {
    361         if (And * and2 = isBinary<And>(expr2)) {
    362             PabloAST * const expr1a = and1->getOperand(0);
    363             PabloAST * const expr1b = and1->getOperand(1);
    364             PabloAST * const expr2a = and2->getOperand(0);
    365             PabloAST * const expr2b = and2->getOperand(1);
    366             //These optimizations factor out common components that can occur when sets are formed by union
    367             //(e.g., union of [a-z] and [A-Z].
    368             if (equals(expr1a, expr2a)) {
    369                 return createAnd(expr1a, createOr(expr1b, expr2b), prefix);
    370             } else if (equals(expr1b, expr2b)) {
    371                 return createAnd(expr1b, createOr(expr1a, expr2a), prefix);
    372             } else if (equals(expr1a, expr2b)) {
    373                 return createAnd(expr1a, createOr(expr1b, expr2a), prefix);
    374             } else if (equals(expr1b, expr2a)) {
    375                 return createAnd(expr1b, createOr(expr1a, expr2b), prefix);
    376             }
    377         } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
    378             // (a∧b) √ a = a
    379             return expr2;
    380         }
    381     } else if (And * and2 = isBinary<And>(expr2)) {
    382         if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
    383             return expr1;
    384         }
    385     }
    386     return insertAtInsertionPoint(new Or(expr1->getType(), expr1, expr2, makeName(prefix, false)));
    387 }
    388 
    389 Or * PabloBlock::createOr(const PabloType * const type, const unsigned reserved) {
    390     return insertAtInsertionPoint(new Or(type, reserved, makeName("or_")));
    391 }
    392 
    393 Or * PabloBlock::createOr(const PabloType * const type, const unsigned reserved, const std::string prefix) {
    394     return insertAtInsertionPoint(new Or(type, reserved, makeName(prefix, false)));
    395 }
    396 
    397 Or * PabloBlock::createOr(const PabloType * const type, std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end) {
    398     return insertAtInsertionPoint(new Or(type, begin, end, makeName("or_")));
    399 }
    400 
    401 Or * PabloBlock::createOr(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end) {
    402     return insertAtInsertionPoint(new Or(type, begin, end, makeName("or_")));
    403 }
    404 
    405 PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
    406     throwIfNonMatchingTypes(expr1, expr2);
    407     if (expr1 == expr2) {
    408         return PabloBlock::createZeroes(expr1->getType());
    409     } else if (isa<Ones>(expr1)) {
    410         return createNot(expr2);
    411     } else if (isa<Zeroes>(expr1)){
    412         return expr2;
    413     } else if (isa<Ones>(expr2)) {
    414         return createNot(expr1);
    415     } else if (isa<Zeroes>(expr2)){
    416         return expr1;
    417     } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    418         if (Not * not2 = dyn_cast<Not>(expr2)) {
    419             return createXor(not1->getOperand(0), not2->getOperand(0));
    420         }
    421     }
    422     return insertAtInsertionPoint(new Xor(expr1->getType(), expr1, expr2, makeName("xor_")));
    423 }
    424 
    425 PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    426     throwIfNonMatchingTypes(expr1, expr2);
    427     if (expr1 == expr2) {
    428         return PabloBlock::createZeroes(expr1->getType());
    429     } else if (isa<Ones>(expr1)) {
    430         return createNot(expr2, prefix);
    431     } else if (isa<Zeroes>(expr1)){
    432         return expr2;
    433     } else if (isa<Ones>(expr2)) {
    434         return createNot(expr1, prefix);
    435     } else if (isa<Zeroes>(expr2)){
    436         return expr1;
    437     } else if (Not * not1 = dyn_cast<Not>(expr1)) {
    438         if (Not * not2 = dyn_cast<Not>(expr2)) {
    439             return createXor(not1->getOperand(0), not2->getOperand(0), prefix);
    440         }
    441     }
    442     return insertAtInsertionPoint(new Xor(expr1->getType(), expr1, expr2, makeName(prefix, false)));
    443 }
    444 
    445 Xor * PabloBlock::createXor(const PabloType * const type, const unsigned reserved) {
    446     return insertAtInsertionPoint(new Xor(type, reserved, makeName("xor_")));
    447 }
    448 
    449 Xor * PabloBlock::createXor(const PabloType * const type, const unsigned reserved, const std::string prefix) {
    450     return insertAtInsertionPoint(new Xor(type, reserved, makeName(prefix, false)));
    451 }
    452 
    453 Xor * PabloBlock::createXor(const PabloType * const type, std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end) {
    454     return insertAtInsertionPoint(new Xor(type, begin, end, makeName("xor_")));
    455 }
    456 
    457 Xor * PabloBlock::createXor(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end) {
    458     return insertAtInsertionPoint(new Xor(type, begin, end, makeName("xor_")));
    459 }
    460 
    461 /// TERNARY CREATE FUNCTION
    462 
    463 PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
    464     throwIfNonMatchingTypes(trueExpr, falseExpr);
    465     if (isa<Ones>(condition)) {
    466         return trueExpr;
    467     } else if (isa<Zeroes>(condition)){
    468         return falseExpr;
    469     } else if (isa<Ones>(trueExpr)) {
    470         return createOr(condition, falseExpr);
    471     } else if (isa<Zeroes>(trueExpr)){
    472         return createAnd(createNot(condition), falseExpr);
    473     } else if (isa<Ones>(falseExpr)) {
    474         return createOr(createNot(condition), trueExpr);
    475     } else if (isa<Zeroes>(falseExpr)){
    476         return createAnd(condition, trueExpr);
    477     } else if (equals(trueExpr, falseExpr)) {
    478         return trueExpr;
    479     } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
    480         return createXor(condition, falseExpr);
    481     } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
    482         return createXor(condition, trueExpr);
    483     }
    484     return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName("sel")));
    485 }
    486 
    487 PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const std::string prefix) {
    488     throwIfNonMatchingTypes(trueExpr, falseExpr);
    489     if (isa<Zeroes>(condition)){
    490         return renameNonNamedNode(falseExpr, std::move(prefix));
    491     } else if (isa<Ones>(condition) || equals(trueExpr, falseExpr)) {
    492         return renameNonNamedNode(trueExpr, std::move(prefix));
    493     } else if (isa<Ones>(trueExpr)) {
    494         return createOr(condition, falseExpr, prefix);
    495     } else if (isa<Zeroes>(trueExpr)){
    496         return createAnd(createNot(condition), falseExpr, prefix);
    497     } else if (isa<Ones>(falseExpr)) {
    498         return createOr(createNot(condition), trueExpr, prefix);
    499     } else if (isa<Zeroes>(falseExpr)){
    500         return createAnd(condition, trueExpr, prefix);
    501     } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
    502         return createXor(condition, falseExpr, prefix);
    503     } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
    504         return createXor(condition, trueExpr, prefix);
    505     }
    506     return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName(prefix, false)));
    507 }
    508 
    509 If * PabloBlock::createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock * body) {
    510     assert (condition);
    511     return insertAtInsertionPoint(new If(condition, definedVars, body));
    512 }
    513 
    514 If * PabloBlock::createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock * body) {
    515     assert (condition);
    516     return insertAtInsertionPoint(new If(condition, definedVars, body));
    517 }
    518 
    519 If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock * body) {
    520     assert (condition);
    521     return insertAtInsertionPoint(new If(condition, definedVars, body));
    522 }
    523 
    524 While * PabloBlock::createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock * body) {
    525     assert (condition);
    526     return insertAtInsertionPoint(new While(condition, nextVars, body));
    527 }
    528 
    529 While * PabloBlock::createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock * body) {
    530     assert (condition);
    531     return insertAtInsertionPoint(new While(condition, nextVars, body));
    532 }
    533 
    534 While * PabloBlock::createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock * body) {
    535     assert (condition);
    536     return insertAtInsertionPoint(new While(condition, nextVars, body));
    537 }
    538 
    539203/** ------------------------------------------------------------------------------------------------------------- *
    540204 * @brief eraseFromParent
     
    542206void PabloBlock::eraseFromParent(const bool recursively) {
    543207    Statement * stmt = front();
    544     // Note: by erasing the scope block, any Assign/Next nodes will be replaced with Zero and removed from
    545     // the If/While node
    546208    while (stmt) {
    547209        stmt = stmt->eraseFromParent(recursively);
     
    550212}
    551213
    552 
    553 // Assign sequential scope indexes, returning the next unassigned index   
    554 
     214/** ------------------------------------------------------------------------------------------------------------- *
     215 * @brief enumerateScopes
     216 *
     217 * Assign sequential scope indexes, returning the next unassigned index
     218 ** ------------------------------------------------------------------------------------------------------------- */
    555219unsigned PabloBlock::enumerateScopes(unsigned baseScopeIndex) {
    556220    mScopeIndex = baseScopeIndex;
     
    569233/// CONSTRUCTOR
    570234
    571 PabloBlock::PabloBlock(PabloFunction * parent, PabloBlock *predecessor) noexcept
    572 : PabloAST(PabloAST::ClassTypeId::Block, nullptr)
     235PabloBlock::PabloBlock(PabloFunction * const parent) noexcept
     236: PabloAST(PabloAST::ClassTypeId::Block, nullptr, nullptr)
    573237, mParent(parent)
    574 , mPredecessor(predecessor)
    575238, mBranch(nullptr)
    576239, mScopeIndex(0)
Note: See TracChangeset for help on using the changeset viewer.