Changeset 5160 for icGREP/icgrep-devel


Ignore:
Timestamp:
Sep 23, 2016, 4:12:41 PM (3 years ago)
Author:
nmedfort
Message:

Initial work for incorporating Types into Pablo AST.

Location:
icGREP/icgrep-devel/icgrep
Files:
3 added
46 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/CMakeLists.txt

    r5156 r5160  
    7070SET(IDISA_SRC IDISA/idisa_builder.cpp IDISA/idisa_avx_builder.cpp IDISA/idisa_i64_builder.cpp IDISA/idisa_sse_builder.cpp IDISA/idisa_nvptx_builder.cpp IDISA/idisa_target.cpp)
    7171
    72 SET(PABLO_SRC pablo/pabloAST.cpp pablo/ps_if.cpp pablo/ps_while.cpp pablo/function.cpp pablo/codegenstate.cpp pablo/builder.cpp pablo/symbol_generator.cpp pablo/printer_pablos.cpp pablo/pablo_toolchain.cpp pablo/passes/flattenif.cpp)
     72SET(PABLO_SRC pablo/pablo_type.cpp pablo/pabloAST.cpp pablo/ps_if.cpp pablo/ps_while.cpp pablo/function.cpp pablo/codegenstate.cpp pablo/builder.cpp pablo/symbol_generator.cpp pablo/printer_pablos.cpp pablo/pablo_toolchain.cpp pablo/passes/flattenif.cpp)
    7373SET(PABLO_SRC ${PABLO_SRC} pablo/pablo_compiler.cpp pablo/carry_manager.cpp pablo/carry_data.cpp pablo/pablo_kernel.cpp)
    7474SET(PABLO_SRC ${PABLO_SRC} kernels/s2p_kernel.cpp kernels/kernel.cpp kernels/streamset.cpp kernels/interface.cpp)
     
    7676SET(PABLO_SRC ${PABLO_SRC} pablo/optimizers/pablo_simplifier.cpp pablo/optimizers/codemotionpass.cpp)
    7777IF(ENABLE_MULTIPLEXING)
    78 SET(PABLO_SRC ${PABLO_SRC} pablo/optimizers/booleanreassociationpass.cpp pablo/optimizers/distributivepass.cpp pablo/passes/flattenassociativedfg.cpp pablo/passes/factorizedfg.cpp)
     78SET(PABLO_SRC ${PABLO_SRC} pablo/optimizers/booleanreassociationpass.cpp)
    7979SET(PABLO_SRC ${PABLO_SRC} pablo/optimizers/schedulingprepass.cpp pablo/optimizers/pablo_automultiplexing.cpp)
    8080ENDIF()
  • icGREP/icgrep-devel/icgrep/UCD/ucd_compiler.cpp

    r5156 r5160  
    485485 ** ------------------------------------------------------------------------------------------------------------- */
    486486void UCDCompiler::generateWithDefaultIfHierarchy(NameMap & names, PabloBuilder & entry) {
    487     addTargets(names);
     487    addTargets(entry, names);
    488488    generateRange(defaultIfHierachy, entry);
    489489    updateNames(names, entry);
     
    495495PabloAST * UCDCompiler::generateWithDefaultIfHierarchy(const UnicodeSet * set, PabloBuilder & entry) {
    496496    // mTargetMap.insert(std::make_pair<const UnicodeSet *, PabloAST *>(set, PabloBlock::createZeroes()));
    497     mTargetMap.emplace(set, PabloBlock::createZeroes());
     497    mTargetMap.emplace(set, entry.createZeroes());
    498498    generateRange(defaultIfHierachy, entry);
    499499    return mTargetMap.begin()->second;
     
    504504 ** ------------------------------------------------------------------------------------------------------------- */
    505505void UCDCompiler::generateWithoutIfHierarchy(NameMap & names, PabloBuilder & entry) {
    506     addTargets(names);
     506    addTargets(entry, names);
    507507    generateRange(noIfHierachy, entry);
    508508    updateNames(names, entry);
     
    513513 ** ------------------------------------------------------------------------------------------------------------- */
    514514PabloAST * UCDCompiler::generateWithoutIfHierarchy(const UnicodeSet * set, PabloBuilder & entry) {
    515     mTargetMap.emplace(set, PabloBlock::createZeroes());
     515    mTargetMap.emplace(set, entry.createZeroes());
    516516    generateRange(noIfHierachy, entry);
    517517    return mTargetMap.begin()->second;
     
    521521 * @brief addTargets
    522522 ** ------------------------------------------------------------------------------------------------------------- */
    523 inline void UCDCompiler::addTargets(const NameMap & names) {
     523inline void UCDCompiler::addTargets(PabloBuilder & entry, const NameMap & names) {
    524524    for (const auto t : names) {
    525525        if (LLVM_LIKELY(isa<CC>(t.first->getDefinition()))) {
    526             mTargetMap.emplace(cast<CC>(t.first->getDefinition()), t.second ? t.second : PabloBlock::createZeroes());
     526            mTargetMap.emplace(cast<CC>(t.first->getDefinition()), t.second ? t.second : entry.createZeroes());
    527527        } else {
    528528            throw std::runtime_error(t.first->getName() + " is not defined by a CC!");
  • icGREP/icgrep-devel/icgrep/UCD/ucd_compiler.hpp

    r5045 r5160  
    8080    static RangeList innerRanges(const RangeList & list);
    8181
    82     void addTargets(const NameMap & names);
     82    void addTargets(PabloBuilder & entry, const NameMap & names);
    8383
    8484    void updateNames(NameMap & names, PabloBuilder & entry);
  • icGREP/icgrep-devel/icgrep/cc/cc_compiler.cpp

    r5140 r5160  
    3030, mBasisBit(encodingBits)
    3131, mEncodingBits(encodingBits) {
     32    const PabloType * streamType = getPabloType(PabloType::Stream, 1);
    3233    for (unsigned i = 0; i != mEncodingBits; i++) {
    33         Var * var = mBuilder.createVar(prefix + std::to_string(i));
     34        Var * var = mBuilder.createVar(prefix + std::to_string(i), streamType);
    3435        function.setParameter(i, var);
    3536        mBasisBit[i] = var;
     
    9596PabloAST * CC_Compiler::bit_pattern_expr(const unsigned pattern, unsigned selected_bits, PabloBlockOrBuilder & pb) {
    9697    if (LLVM_UNLIKELY(selected_bits == 0)) {
    97         return PabloBlock::createOnes();
     98        return pb.createOnes();
    9899    } else {
    99100        std::vector<PabloAST*> terms;
    100101        for (unsigned i = 0; selected_bits; ++i) {
    101102            unsigned test_bit = static_cast<unsigned>(1) << i;
    102             PabloAST * term = PabloBlock::createOnes();
     103            PabloAST * term = pb.createOnes();
    103104            if (selected_bits & test_bit) {
    104105                term = getBasisVar(i);
  • icGREP/icgrep-devel/icgrep/icgrep-devel.files

    r5156 r5160  
    18441844util/papi_helper.hpp
    18451845util/slab_allocator.h
     1846pablo/type.h
     1847pablo/type.cpp
     1848pablo/pablo_type.cpp
     1849pablo/pablo_type.h
     1850pablo/pe_constant.h
     1851cc/cc_compiler.cpp
     1852cc/cc_compiler.h
     1853IDISA/CudaDriver.h
     1854IDISA/idisa_avx_builder.cpp
     1855IDISA/idisa_avx_builder.h
     1856IDISA/idisa_builder.cpp
     1857IDISA/idisa_builder.h
     1858IDISA/idisa_i64_builder.cpp
     1859IDISA/idisa_i64_builder.h
     1860IDISA/idisa_nvptx_builder.cpp
     1861IDISA/idisa_nvptx_builder.h
     1862IDISA/idisa_sse_builder.cpp
     1863IDISA/idisa_sse_builder.h
     1864IDISA/idisa_target.cpp
     1865IDISA/idisa_target.h
     1866IDISA/llvm2ptx.h
     1867kernels/cc_kernel.cpp
     1868kernels/cc_kernel.h
     1869kernels/deletion.cpp
     1870kernels/deletion.h
     1871kernels/interface.cpp
     1872kernels/interface.h
     1873kernels/kernel.cpp
     1874kernels/kernel.h
     1875kernels/p2s_kernel.cpp
     1876kernels/p2s_kernel.h
     1877kernels/pipeline.cpp
     1878kernels/pipeline.h
     1879kernels/s2p_kernel.cpp
     1880kernels/s2p_kernel.h
     1881kernels/scanmatchgen.cpp
     1882kernels/scanmatchgen.h
     1883kernels/stdout_kernel.cpp
     1884kernels/stdout_kernel.h
     1885kernels/streamset.cpp
     1886kernels/streamset.h
     1887kernels/symboltablepipeline.cpp
     1888kernels/symboltablepipeline.h
     1889pablo/analysis/pabloverifier.cpp
     1890pablo/analysis/pabloverifier.hpp
     1891pablo/optimizers/booleanreassociationpass.cpp
     1892pablo/optimizers/booleanreassociationpass.h
     1893pablo/optimizers/codemotionpass.cpp
     1894pablo/optimizers/codemotionpass.h
     1895pablo/optimizers/distributivepass.cpp
     1896pablo/optimizers/distributivepass.h
     1897pablo/optimizers/graph-facade.hpp
     1898pablo/optimizers/maxsat.hpp
     1899pablo/optimizers/pablo_automultiplexing.cpp
     1900pablo/optimizers/pablo_automultiplexing.hpp
     1901pablo/optimizers/pablo_bddminimization.cpp
     1902pablo/optimizers/pablo_bddminimization.h
     1903pablo/optimizers/pablo_simplifier.cpp
     1904pablo/optimizers/pablo_simplifier.hpp
     1905pablo/optimizers/schedulingprepass.cpp
     1906pablo/optimizers/schedulingprepass.h
     1907pablo/passes/factorizedfg.cpp
     1908pablo/passes/factorizedfg.h
     1909pablo/passes/flattenassociativedfg.cpp
     1910pablo/passes/flattenassociativedfg.h
     1911pablo/passes/flattenif.cpp
     1912pablo/passes/flattenif.hpp
     1913pablo/builder.cpp
     1914pablo/builder.hpp
     1915pablo/carry_data.cpp
     1916pablo/carry_data.h
     1917pablo/carry_manager.cpp
     1918pablo/carry_manager.h
     1919pablo/codegenstate.cpp
     1920pablo/codegenstate.h
     1921pablo/expression_map.hpp
     1922pablo/function.cpp
     1923pablo/function.h
     1924pablo/pablo_compiler.cpp
     1925pablo/pablo_compiler.h
     1926pablo/pablo_kernel.cpp
     1927pablo/pablo_kernel.h
     1928pablo/pablo_toolchain.cpp
     1929pablo/pablo_toolchain.h
     1930pablo/pablo_type.cpp
     1931pablo/pablo_type.h
     1932pablo/pabloAST.cpp
     1933pablo/pabloAST.h
     1934pablo/pe_advance.h
     1935pablo/pe_and.h
     1936pablo/pe_call.h
     1937pablo/pe_constant.h
     1938pablo/pe_count.h
     1939pablo/pe_infile.h
     1940pablo/pe_integer.h
     1941pablo/pe_lookahead.h
     1942pablo/pe_matchstar.h
     1943pablo/pe_next.h
     1944pablo/pe_not.h
     1945pablo/pe_ones.h
     1946pablo/pe_or.h
     1947pablo/pe_scanthru.h
     1948pablo/pe_sel.h
     1949pablo/pe_setithbit.h
     1950pablo/pe_string.h
     1951pablo/pe_var.h
     1952pablo/pe_xor.h
     1953pablo/pe_zeroes.h
     1954pablo/printer_pablos.cpp
     1955pablo/printer_pablos.h
     1956pablo/ps_assign.h
     1957pablo/ps_if.cpp
     1958pablo/ps_if.h
     1959pablo/ps_while.cpp
     1960pablo/ps_while.h
     1961pablo/symbol_generator.cpp
     1962pablo/symbol_generator.h
     1963re/parsefailure.cpp
     1964re/parsefailure.h
     1965re/printer_re.cpp
     1966re/printer_re.h
     1967re/re_alt.h
     1968re/re_analysis.cpp
     1969re/re_analysis.h
     1970re/re_any.h
     1971re/re_assertion.h
     1972re/re_cc.cpp
     1973re/re_cc.h
     1974re/re_compiler.cpp
     1975re/re_compiler.h
     1976re/re_diff.cpp
     1977re/re_diff.h
     1978re/re_end.h
     1979re/re_intersect.cpp
     1980re/re_intersect.h
     1981re/re_memoizer.hpp
     1982re/re_name.h
     1983re/re_name_resolve.cpp
     1984re/re_name_resolve.h
     1985re/re_nullable.cpp
     1986re/re_nullable.h
     1987re/re_parser.cpp
     1988re/re_parser.h
     1989re/re_re.cpp
     1990re/re_re.h
     1991re/re_rep.cpp
     1992re/re_rep.h
     1993re/re_seq.h
     1994re/re_simplifier.cpp
     1995re/re_simplifier.h
     1996re/re_start.h
     1997re/re_toolchain.cpp
     1998re/re_toolchain.h
     1999UCD/Blocks.h
     2000UCD/CaseFolding_txt.cpp
     2001UCD/CaseFolding_txt.h
     2002UCD/DerivedAge.h
     2003UCD/DerivedBidiClass.h
     2004UCD/DerivedBinaryProperties.h
     2005UCD/DerivedCombiningClass.h
     2006UCD/DerivedCoreProperties.h
     2007UCD/DerivedDecompositionType.h
     2008UCD/DerivedGeneralCategory.h
     2009UCD/DerivedJoiningGroup.h
     2010UCD/DerivedJoiningType.h
     2011UCD/DerivedNormalizationProps.h
     2012UCD/DerivedNumericType.h
     2013UCD/EastAsianWidth.h
     2014UCD/GraphemeBreakProperty.h
     2015UCD/HangulSyllableType.h
     2016UCD/LineBreak.h
     2017UCD/PropertyAliases.h
     2018UCD/PropertyObjects.cpp
     2019UCD/PropertyObjects.h
     2020UCD/PropertyObjectTable.h
     2021UCD/PropertyValueAliases.h
     2022UCD/PropList.h
     2023UCD/resolve_properties.cpp
     2024UCD/resolve_properties.h
     2025UCD/ScriptExtensions.h
     2026UCD/Scripts.h
     2027UCD/SentenceBreakProperty.h
     2028UCD/ucd_compiler.cpp
     2029UCD/ucd_compiler.hpp
     2030UCD/unicode_set.cpp
     2031UCD/unicode_set.h
     2032UCD/UnicodeNameData.cpp
     2033UCD/UnicodeNameData.h
     2034UCD/WordBreakProperty.h
     2035util/papi_helper.hpp
     2036util/slab_allocator.h
     2037grep_engine.cpp
     2038grep_engine.h
     2039hrtime.h
     2040icgrep.cpp
     2041object_cache.cpp
     2042object_cache.h
     2043symboltable.cpp
     2044toolchain.cpp
     2045toolchain.h
     2046u8u16.cpp
     2047utf16_encoder.cpp
     2048utf16_encoder.h
     2049utf8_encoder.cpp
     2050utf8_encoder.h
     2051wc.cpp
  • icGREP/icgrep-devel/icgrep/pablo/analysis/pabloverifier.cpp

    r5156 r5160  
    201201            return false;
    202202        }
    203         parent = parent->getParent();
     203        parent = parent->getPredecessor ();
    204204    }
    205205    return true;
     
    308308            if (LLVM_UNLIKELY(nested->getBranch() != stmt)) {
    309309                throwMisreportedBranchError(stmt, nested->getBranch());
    310             } else if (LLVM_UNLIKELY(nested->getParent() != block)) {
     310            } else if (LLVM_UNLIKELY(nested->getPredecessor () != block)) {
    311311                throwReportedScopeError(stmt);
    312312            }
  • icGREP/icgrep-devel/icgrep/pablo/builder.hpp

    r5061 r5160  
    3636
    3737    inline static PabloBuilder Create(PabloBuilder & builder) noexcept {
    38         return PabloBuilder(new PabloBlock(builder.mPb->mSymbolGenerator), builder);
    39     }
    40 
    41     static inline Zeroes * createZeroes() {
    42         return PabloBlock::createZeroes();
    43     }
    44 
    45     static inline Ones * createOnes() {
    46         return PabloBlock::createOnes();
    47     }
    48 
    49     inline Var * createVar(const std::string name) {
    50         return mPb->createVar(name);
    51     }
    52 
    53     inline Var * createVar(String * const name) {
    54         return mPb->createVar(name);
    55     }
    56 
    57     inline Var * createVar(PabloAST * const name) {
    58         return mPb->createVar(name);
     38        return PabloBuilder(PabloBlock::Create(builder.getPabloBlock()), builder);
     39    }
     40
     41    inline Zeroes * createZeroes(const PabloType * const type = nullptr) {
     42        return mPb->createZeroes(type);
     43    }
     44
     45    inline Ones * createOnes(const PabloType * const type = nullptr) {
     46        return mPb->createOnes(type);
     47    }
     48
     49    inline Var * createVar(const std::string name, const PabloType * const type) {
     50        return mPb->createVar(name, type);
     51    }
     52
     53    inline Var * createVar(String * const name, const PabloType * const type) {
     54        return mPb->createVar(name, type);
     55    }
     56
     57    inline Var * createVar(PabloAST * const name, const PabloType * const type) {
     58        return mPb->createVar(name, type);
    5959    }
    6060
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp

    r5156 r5160  
    8181    assert (mCurrentScope != mRootScope);
    8282    mCurrentFrameIndex -= mCarryInfo->getFrameIndex();
    83     mCurrentScope = mCurrentScope->getParent();
     83    mCurrentScope = mCurrentScope->getPredecessor ();
    8484    mCarryInfo = mCarryInfoVector[mCurrentScope->getScopeIndex()];
    8585    assert(summaryPack() < mCarryOutPack.size());
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp

    r5063 r5160  
    1010
    1111namespace pablo {
    12 
    13 Zeroes PabloBlock::mZeroes;
    14 
    15 Ones PabloBlock::mOnes;
    1612
    1713inline PabloAST * PabloBlock::renameNonNamedNode(PabloAST * expr, const std::string && prefix) {
     
    5046
    5147PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
     48    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    5249    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
    5350        return expr;
     
    5754
    5855PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
     56    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    5957    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
    6058        return expr;
     
    6462
    6563PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount) {
     64    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    6665    if (isa<Zeroes>(expr) || shiftAmount == 0) {
    6766        return expr;
     
    7170
    7271PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
     72    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    7373    if (isa<Zeroes>(expr) || shiftAmount == 0) {
    7474        return renameNonNamedNode(expr, std::move(prefix));
     
    7878
    7979Count * PabloBlock::createCount(const std::string counterName, PabloAST * const expr)  {
     80    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    8081    return insertAtInsertionPoint(new Count(expr, makeName(counterName, false)));
    8182}
     
    9091
    9192PabloAST * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
     93    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    9294    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
    9395        return expr;
     
    9799
    98100PabloAST * PabloBlock::createLookahead(PabloAST * expr, const Integer::Type shiftAmount) {
     101    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    99102    if (isa<Zeroes>(expr) || shiftAmount == 0) {
    100103        return expr;
     
    104107
    105108PabloAST * PabloBlock::createLookahead(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
     109    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    106110    if (isa<Zeroes>(expr) || shiftAmount == 0) {
    107111        return renameNonNamedNode(expr, std::move(prefix));
     
    118122PabloAST * PabloBlock::createNot(PabloAST * expr) {
    119123    assert (expr);
     124    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    120125    if (isa<Ones>(expr)) {
    121         return createZeroes();
     126        return createZeroes(expr->getType());
    122127    }
    123128    else if (isa<Zeroes>(expr)){
    124         return createOnes();
     129        return createOnes(expr->getType());
    125130    }
    126131    else if (Not * not1 = dyn_cast<Not>(expr)) {
     
    132137PabloAST * PabloBlock::createNot(PabloAST * expr, const std::string prefix) {
    133138    assert (expr);
     139    PabloAST::throwIfNonMatchingType(expr, PabloType::Stream);
    134140    if (isa<Ones>(expr)) {
    135         return createZeroes();
     141        return createZeroes(expr->getType());
    136142    }
    137143    else if (isa<Zeroes>(expr)){
    138         return createOnes();
     144        return createOnes(expr->getType());
    139145    }
    140146    else if (Not * not1 = dyn_cast<Not>(expr)) {       
     
    144150}
    145151
    146 Var * PabloBlock::createVar(PabloAST * name) {
     152Var * PabloBlock::createVar(PabloAST * name, const PabloType * const type) {
    147153    assert (name);
    148     return new Var(name);
     154    return new Var(name, type);
    149155}
    150156
     
    179185
    180186PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass) {
    181     assert (marker && charclass);
     187    throwIfNonMatchingTypes(marker, charclass);
    182188    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
    183189        return marker;
     
    186192}
    187193
    188 PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const std::string prefix) {
    189     assert (marker && charclass);
     194PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const std::string prefix) {   
     195    throwIfNonMatchingTypes(marker, charclass);
     196    throwIfNonMatchingType(marker, PabloType::Stream);
    190197    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
    191198        return renameNonNamedNode(marker, std::move(prefix));
     
    194201}
    195202
    196 PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {
    197     assert (from && thru);
     203PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {   
     204    throwIfNonMatchingTypes(from, thru);
     205    throwIfNonMatchingType(from, PabloType::Stream);
    198206    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
    199207        return from;
     
    203211
    204212PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, const std::string prefix) {
    205     assert (from && thru);
     213    throwIfNonMatchingTypes(from, thru);
     214    throwIfNonMatchingType(from, PabloType::Stream);
    206215    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {       
    207216        return renameNonNamedNode(from, std::move(prefix));
     
    219228
    220229PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
    221     assert (expr1 && expr2);
     230    throwIfNonMatchingTypes(expr1, expr2);
    222231    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
    223232        return expr2;
     
    228237            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)));
    229238        } else if (equals(not1->getOperand(0), expr2)) {
    230             return createZeroes();
     239            return createZeroes(expr1->getType());
    231240        }
    232241    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    233242        if (equals(expr1, not2->getOperand(0))) {
    234             return createZeroes();
     243            return createZeroes(expr1->getType());
    235244        }
    236245    } else if (Or * or1 = isBinary<Or>(expr1)) {
     
    243252        }
    244253    }
    245     return insertAtInsertionPoint(new And(expr1, expr2, makeName("and_")));
     254    return insertAtInsertionPoint(new And(expr1->getType(), expr1, expr2, makeName("and_")));
    246255}
    247256
    248257PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    249     assert (expr1 && expr2);
     258    throwIfNonMatchingTypes(expr1, expr2);
    250259    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
    251260        return renameNonNamedNode(expr2, std::move(prefix));
     
    258267        }
    259268        else if (equals(not1->getOperand(0), expr2)) {
    260             return createZeroes();
     269            return createZeroes(expr1->getType());
    261270        }
    262271    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
    263272        if (equals(expr1, not2->getOperand(0))) {
    264             return createZeroes();
     273            return createZeroes(expr1->getType());
    265274        }
    266275    } else if (Or * or1 = isBinary<Or>(expr1)) {
     
    273282        }
    274283    }
    275     return insertAtInsertionPoint(new And(expr1, expr2, makeName(prefix, false)));
    276 }
    277 
    278 And * PabloBlock::createAnd(const unsigned reserved) {
    279     return insertAtInsertionPoint(new And(reserved, makeName("and_")));
    280 }
    281 
    282 And * PabloBlock::createAnd(const unsigned reserved, const std::string prefix) {
    283     return insertAtInsertionPoint(new And(reserved, makeName(prefix, false)));
     284    return insertAtInsertionPoint(new And(expr1->getType(), expr1, expr2, makeName(prefix, false)));
     285}
     286
     287And * PabloBlock::createAnd(const PabloType * const type, const unsigned reserved) {
     288    return insertAtInsertionPoint(new And(type, reserved, makeName("and_")));
     289}
     290
     291And * 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
     295And * 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
     299And * PabloBlock::createAnd(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end) {
     300    return insertAtInsertionPoint(new And(type, begin, end, makeName("and_")));
    284301}
    285302
    286303PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
    287     assert (expr1 && expr2);
     304    throwIfNonMatchingTypes(expr1, expr2);
    288305    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    289306        return expr2;
     
    325342        }
    326343    }
    327     return insertAtInsertionPoint(new Or(expr1, expr2, makeName("or_")));
     344    return insertAtInsertionPoint(new Or(expr1->getType(), expr1, expr2, makeName("or_")));
    328345}
    329346
    330347PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    331     assert (expr1 && expr2);
     348    throwIfNonMatchingTypes(expr1, expr2);
    332349    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
    333350        return renameNonNamedNode(expr2, std::move(prefix));
     
    367384        }
    368385    }
    369     return insertAtInsertionPoint(new Or(expr1, expr2, makeName(prefix, false)));
    370 }
    371 
    372 Or * PabloBlock::createOr(const unsigned reserved) {
    373     return insertAtInsertionPoint(new Or(reserved, makeName("or_")));
    374 }
    375 
    376 Or * PabloBlock::createOr(const unsigned reserved, const std::string prefix) {
    377     return insertAtInsertionPoint(new Or(reserved, makeName(prefix, false)));
     386    return insertAtInsertionPoint(new Or(expr1->getType(), expr1, expr2, makeName(prefix, false)));
     387}
     388
     389Or * PabloBlock::createOr(const PabloType * const type, const unsigned reserved) {
     390    return insertAtInsertionPoint(new Or(type, reserved, makeName("or_")));
     391}
     392
     393Or * 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
     397Or * 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
     401Or * PabloBlock::createOr(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end) {
     402    return insertAtInsertionPoint(new Or(type, begin, end, makeName("or_")));
    378403}
    379404
    380405PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
    381     assert (expr1 && expr2);
     406    throwIfNonMatchingTypes(expr1, expr2);
    382407    if (expr1 == expr2) {
    383         return PabloBlock::createZeroes();
    384     }
    385     if (isa<Ones>(expr1)) {
     408        return PabloBlock::createZeroes(expr1->getType());
     409    } else if (isa<Ones>(expr1)) {
    386410        return createNot(expr2);
    387411    } else if (isa<Zeroes>(expr1)){
     
    396420        }
    397421    }
    398     return insertAtInsertionPoint(new Xor(expr1, expr2, makeName("xor_")));
     422    return insertAtInsertionPoint(new Xor(expr1->getType(), expr1, expr2, makeName("xor_")));
    399423}
    400424
    401425PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
    402     assert (expr1 && expr2);
     426    throwIfNonMatchingTypes(expr1, expr2);
    403427    if (expr1 == expr2) {
    404         return PabloBlock::createZeroes();
    405     }
    406     if (isa<Ones>(expr1)) {
     428        return PabloBlock::createZeroes(expr1->getType());
     429    } else if (isa<Ones>(expr1)) {
    407430        return createNot(expr2, prefix);
    408431    } else if (isa<Zeroes>(expr1)){
     
    417440        }
    418441    }
    419     return insertAtInsertionPoint(new Xor(expr1, expr2, makeName(prefix, false)));
    420 }
    421 
    422 Xor * PabloBlock::createXor(const unsigned reserved) {
    423     return insertAtInsertionPoint(new Xor(reserved, makeName("xor_")));
    424 }
    425 
    426 Xor * PabloBlock::createXor(const unsigned reserved, const std::string prefix) {
    427     return insertAtInsertionPoint(new Xor(reserved, makeName(prefix, false)));
     442    return insertAtInsertionPoint(new Xor(expr1->getType(), expr1, expr2, makeName(prefix, false)));
     443}
     444
     445Xor * PabloBlock::createXor(const PabloType * const type, const unsigned reserved) {
     446    return insertAtInsertionPoint(new Xor(type, reserved, makeName("xor_")));
     447}
     448
     449Xor * 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
     453Xor * 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
     457Xor * PabloBlock::createXor(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end) {
     458    return insertAtInsertionPoint(new Xor(type, begin, end, makeName("xor_")));
    428459}
    429460
     
    431462
    432463PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
    433     assert (condition && trueExpr && falseExpr);
     464    throwIfNonMatchingTypes(trueExpr, falseExpr);
    434465    if (isa<Ones>(condition)) {
    435466        return trueExpr;
     
    455486
    456487PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const std::string prefix) {
    457     assert (condition && trueExpr && falseExpr);
     488    throwIfNonMatchingTypes(trueExpr, falseExpr);
    458489    if (isa<Zeroes>(condition)){
    459490        return renameNonNamedNode(falseExpr, std::move(prefix));
    460     }
    461     else if (isa<Ones>(condition) || equals(trueExpr, falseExpr)) {
     491    } else if (isa<Ones>(condition) || equals(trueExpr, falseExpr)) {
    462492        return renameNonNamedNode(trueExpr, std::move(prefix));
    463     }
    464     else if (isa<Ones>(trueExpr)) {
     493    } else if (isa<Ones>(trueExpr)) {
    465494        return createOr(condition, falseExpr, prefix);
    466     }
    467     else if (isa<Zeroes>(trueExpr)){
     495    } else if (isa<Zeroes>(trueExpr)){
    468496        return createAnd(createNot(condition), falseExpr, prefix);
    469     }
    470     else if (isa<Ones>(falseExpr)) {
     497    } else if (isa<Ones>(falseExpr)) {
    471498        return createOr(createNot(condition), trueExpr, prefix);
    472     }
    473     else if (isa<Zeroes>(falseExpr)){
     499    } else if (isa<Zeroes>(falseExpr)){
    474500        return createAnd(condition, trueExpr, prefix);
    475     }
    476     else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
     501    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
    477502        return createXor(condition, falseExpr, prefix);
    478     }
    479     else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
     503    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
    480504        return createXor(condition, trueExpr, prefix);
    481505    }
     
    545569/// CONSTRUCTOR
    546570
    547 PabloBlock::PabloBlock(SymbolGenerator * symbolGenerator) noexcept
    548 : PabloAST(PabloAST::ClassTypeId::Block)
    549 , mSymbolGenerator(symbolGenerator)
    550 , mParent(nullptr)
     571PabloBlock::PabloBlock(PabloFunction * parent, PabloBlock *predecessor) noexcept
     572: PabloAST(PabloAST::ClassTypeId::Block, nullptr)
     573, mParent(parent)
     574, mPredecessor(predecessor)
    551575, mBranch(nullptr)
    552576, mScopeIndex(0)
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.h

    r5061 r5160  
    5757    }
    5858
    59     inline static PabloBlock * Create(PabloFunction & function) noexcept {
    60         return new PabloBlock(function.mSymbolTable);
    61     }
    62 
    63     inline static PabloBlock * Create(PabloBlock * const block) noexcept {
    64         return new PabloBlock(block->mSymbolGenerator);
     59    inline static PabloBlock * Create(PabloFunction & parent) noexcept {
     60        return new PabloBlock(&parent, nullptr);
     61    }
     62
     63    inline static PabloBlock * Create(PabloBlock * const predecessor) noexcept {
     64        return new PabloBlock(predecessor->mParent, predecessor);
    6565    }
    6666
     
    8181    PabloAST * createLookahead(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix);
    8282
    83     static inline Zeroes * createZeroes() {
    84         return &mZeroes;
    85     }
    86 
    87     static inline Ones * createOnes() {
    88         return &mOnes;
     83    inline Zeroes * createZeroes(const PabloType * const type = nullptr) {
     84        return mParent->getNullValue(type);
     85    }
     86
     87    inline Ones * createOnes(const PabloType * const type = nullptr) {
     88        return mParent->getAllOnesValue(type);
    8989    }
    9090
     
    105105    Assign * createAssign(const std::string && prefix, PabloAST * const expr);
    106106
    107     inline Var * createVar(const std::string name) {
    108         return createVar(getName(name, false));
    109     }
    110 
    111     inline Var * createVar(String * name) {
    112         return createVar(cast<PabloAST>(name));
     107    inline Var * createVar(const std::string name, const PabloType * const type) {
     108        return createVar(getName(name, false), type);
     109    }
     110
     111    inline Var * createVar(String * name, const PabloType * const type) {
     112        return createVar(cast<PabloAST>(name), type);
    113113    }
    114114
     
    119119    PabloAST * createAnd(PabloAST * expr1, PabloAST * expr2, const std::string prefix);
    120120
    121     And * createAnd(const unsigned reserved);
    122 
    123     And * createAnd(const unsigned reserved, const std::string prefix);
    124 
    125     And * createAnd(std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end) {
    126         return insertAtInsertionPoint(new And(begin, end, makeName("and_")));
    127     }
    128 
    129     And * createAnd(Variadic::iterator begin, Variadic::iterator end) {
    130         return insertAtInsertionPoint(new And(begin, end, makeName("and_")));
    131     }
     121    And * createAnd(const PabloType * const type, const unsigned reserved);
     122
     123    And * createAnd(const PabloType * const type, const unsigned reserved, const std::string prefix);
     124
     125    And * createAnd(const PabloType * const type, std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end);
     126
     127    And * createAnd(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end);
    132128
    133129    PabloAST * createNot(PabloAST * expr);
     
    139135    PabloAST * createOr(PabloAST * expr1, PabloAST * expr2, const std::string prefix);
    140136
    141     Or * createOr(std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end) {
    142         return insertAtInsertionPoint(new Or(begin, end, makeName("or_")));
    143     }
    144 
    145     Or * createOr(Variadic::iterator begin, Variadic::iterator end) {
    146         return insertAtInsertionPoint(new Or(begin, end, makeName("or_")));
    147     }
    148 
    149     Or * createOr(const unsigned reserved);
    150 
    151     Or * createOr(const unsigned reserved, const std::string prefix);
     137    Or * createOr(const PabloType * const type, std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end);
     138
     139    Or * createOr(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end);
     140
     141    Or * createOr(const PabloType * const type, const unsigned reserved);
     142
     143    Or * createOr(const PabloType * const type, const unsigned reserved, const std::string prefix);
    152144
    153145    PabloAST * createXor(PabloAST * expr1, PabloAST * expr2);
     
    155147    PabloAST * createXor(PabloAST * expr1, PabloAST * expr2, const std::string prefix);
    156148
    157     Xor * createXor(std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end) {
    158         return insertAtInsertionPoint(new Xor(begin, end, makeName("xor_")));
    159     }
    160 
    161     Xor * createXor(Variadic::iterator begin, Variadic::iterator end) {
    162         return insertAtInsertionPoint(new Xor(begin, end, makeName("xor_")));
    163     }
    164 
    165     Xor * createXor(const unsigned reserved);
    166 
    167     Xor * createXor(const unsigned reserved, const std::string prefix);
     149    Xor * createXor(const PabloType * const type, std::vector<PabloAST *>::iterator begin, std::vector<PabloAST *>::iterator end);
     150
     151    Xor * createXor(const PabloType * const type, Variadic::iterator begin, Variadic::iterator end);
     152
     153    Xor * createXor(const PabloType * const type, const unsigned reserved);
     154
     155    Xor * createXor(const PabloType * const type, const unsigned reserved, const std::string prefix);
    168156
    169157    PabloAST * createMatchStar(PabloAST * marker, PabloAST * charclass);
     
    210198
    211199    inline String * getName(const std::string name, const bool generated = true) const {
    212         return mSymbolGenerator->get(name, generated);
     200        return getSymbolTable()->get(name, generated);
    213201    }
    214202
    215203    inline String * makeName(const std::string prefix, const bool generated = true) const {
    216         return mSymbolGenerator->make(prefix, generated);
     204        return getSymbolTable()->make(prefix, generated);
    217205    }
    218206
    219207    inline Integer * getInteger(Integer::Type value) {
    220         return mSymbolGenerator->getInteger(value);
    221     }
    222 
    223     inline PabloBlock * getParent() const {
     208        return getSymbolTable()->getInteger(value);
     209    }
     210
     211    inline PabloBlock * getPredecessor() const {
     212        return mPredecessor;
     213    }
     214   
     215    void setPredecessor(PabloBlock * const predecessor) {
     216        mPredecessor = predecessor;
     217    }
     218
     219    inline PabloFunction * getParent() const {
    224220        return mParent;
    225221    }
    226    
    227     void setParent(PabloBlock * parent) {
     222
     223    void setParent(PabloFunction * const parent) {
    228224        mParent = parent;
    229         // Add test to assert this block is in the same function.
    230225    }
    231226
     
    244239    }
    245240
     241    SymbolGenerator * getSymbolTable() const {
     242        return mParent->getSymbolTable();
     243    }
     244
    246245    virtual ~PabloBlock();
    247246
    248247protected:
    249248
    250     explicit PabloBlock(SymbolGenerator * symbolGenerator) noexcept;
     249    explicit PabloBlock(PabloFunction * parent, PabloBlock * predecessor) noexcept;
    251250
    252251    PabloAST * renameNonNamedNode(PabloAST * expr, const std::string && prefix);
     
    257256            if (LLVM_UNLIKELY(isa<If>(expr) || isa<While>(expr))) {
    258257                PabloBlock * const body = isa<If>(expr) ? cast<If>(expr)->getBody() : cast<While>(expr)->getBody();
    259                 body->setParent(this);
     258                body->setPredecessor (this);
    260259                addUser(body);
    261260            }
     
    273272    Call * createCall(PabloAST * prototype, const std::vector<PabloAST *> &);
    274273
    275     Var * createVar(PabloAST * name);
     274    Var * createVar(PabloAST * name, const PabloType * const type);
    276275
    277276private:       
    278     static Zeroes                                       mZeroes;
    279     static Ones                                         mOnes;
    280     SymbolGenerator *                                   mSymbolGenerator; // TODO: need a better way of passing a symbol generator around
    281     PabloBlock *                                        mParent;
     277    PabloFunction *                                     mParent;
     278    PabloBlock *                                        mPredecessor;
    282279    Statement *                                         mBranch; // What statement branches into this scope block?
    283280    unsigned                                            mScopeIndex;
  • icGREP/icgrep-devel/icgrep/pablo/function.cpp

    r4870 r5160  
    66
    77Prototype::Prototype(const PabloAST::ClassTypeId type, std::string && name, const unsigned numOfParameters, const unsigned numOfResults, void * functionPtr)
    8 : PabloAST(type)
     8: PabloAST(type, nullptr)
    99, mName(GlobalSymbolGenerator.get(name, false))
    1010, mNumOfParameters(numOfParameters)
     
    1717: Prototype(ClassTypeId::Function, std::move(name), numOfParameters, numOfResults, nullptr)
    1818, mSymbolTable(new SymbolGenerator())
     19, mBitStreamType(getPabloType(PabloType::Stream, 1))
    1920, mEntryBlock(PabloBlock::Create(*this))
    20 , mParameters(reinterpret_cast<Var **>(mAllocator.allocate(sizeof(Var *) * numOfParameters)))
    21 , mResults(reinterpret_cast<Assign **>(mAllocator.allocate(sizeof(Assign *) * numOfResults))) {
    22     std::memset(mParameters, 0, sizeof(Var *) * numOfParameters);
    23     std::memset(mResults, 0, sizeof(Assign *) * numOfResults);
     21, mParameters(numOfParameters, nullptr)
     22, mResults(numOfResults, nullptr)
     23, mConstants(0, nullptr) {
     24
     25}
     26
     27Zeroes * PabloFunction::getNullValue(const PabloType * type) {
     28    if (type == nullptr) {
     29        type = mBitStreamType;
     30    }
     31    for (PabloAST * constant : mConstants) {
     32        if (isa<Zeroes>(constant) && constant->getType() == type) {
     33            return cast<Zeroes>(constant);
     34        }
     35    }
     36    Zeroes * value = new Zeroes(type);
     37    mConstants.push_back(value);
     38    return value;
     39}
     40
     41Ones * PabloFunction::getAllOnesValue(const PabloType * type) {
     42    if (type == nullptr) {
     43        type = mBitStreamType;
     44    }
     45    for (PabloAST * constant : mConstants) {
     46        if (isa<Ones>(constant) && constant->getType() == type) {
     47            return cast<Ones>(constant);
     48        }
     49    }
     50    Ones * value = new Ones(type);
     51    mConstants.push_back(value);
     52    return value;
    2453}
    2554
  • icGREP/icgrep-devel/icgrep/pablo/function.h

    r5063 r5160  
    33
    44#include <pablo/pabloAST.h>
     5#include <pablo/symbol_generator.h>
    56#include <pablo/pe_var.h>
    67#include <pablo/ps_assign.h>
    78#include <pablo/pe_count.h>
    8 #include <pablo/symbol_generator.h>
     9#include <pablo/pe_zeroes.h>
     10#include <pablo/pe_ones.h>
    911
    1012namespace pablo {
    11 
    12 class Var;
    13 class Assign;
    14 class PabloBlock;
    15 class String;
    1613
    1714class Prototype : public PabloAST {
     
    5956class PabloFunction : public Prototype {
    6057    friend class PabloBlock;
    61     using ParamAllocator = Allocator::rebind<Var *>::other;
    62     using ResultAllocator = Allocator::rebind<Assign *>::other;
     58    using Allocator = SlabAllocator<PabloAST *>;
    6359public:
    6460
     
    9995    Var * getParameter(const unsigned index) {
    10096        if (LLVM_LIKELY(index < getNumOfParameters()))
    101             return mParameters[index];
     97            return cast<Var>(mParameters[index]);
    10298        else throwInvalidParameterIndex(index);
    10399    }
     
    105101    const Var * getParameter(const unsigned index) const {
    106102        if (LLVM_LIKELY(index < getNumOfParameters()))
    107             return mParameters[index];
     103            return cast<Var>(mParameters[index]);
    108104        else throwInvalidParameterIndex(index);
    109105    }
     
    117113    Assign * getResult(const unsigned index) {
    118114        if (LLVM_LIKELY(index < getNumOfResults()))
    119             return mResults[index];
     115            return cast<Assign>(mResults[index]);
    120116        else throwInvalidResultIndex(index);
    121117    }
     
    123119    const Assign * getResult(const unsigned index) const {
    124120        if (LLVM_LIKELY(index < getNumOfResults()))
    125             return mResults[index];
     121            return cast<Assign>(mResults[index]);
    126122        else throwInvalidResultIndex(index);
    127123    }
     
    148144    }
    149145
     146    Zeroes * getNullValue(const PabloType * const type);
     147
     148    Ones * getAllOnesValue(const PabloType * const type);
     149
    150150    void operator delete (void*);
    151151
    152152    virtual ~PabloFunction() { }
     153
     154    inline SymbolGenerator * getSymbolTable() const {
     155        return mSymbolTable;
     156    }
    153157
    154158protected:
     
    160164    PabloFunction(std::string && name, const unsigned numOfParameters, const unsigned numOfResults);
    161165private:
    162     SymbolGenerator *   mSymbolTable;
    163     PabloBlock *        mEntryBlock;
    164     Var ** const        mParameters;
    165     Assign ** const     mResults;
     166    SymbolGenerator *                           mSymbolTable;
     167    const PabloType *                           mBitStreamType;
     168    PabloBlock *                                mEntryBlock;
     169    std::vector<PabloAST *, Allocator>          mParameters;
     170    std::vector<PabloAST *, Allocator>          mResults;
     171    std::vector<PabloAST *, Allocator>          mConstants;
    166172};
    167173
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/booleanreassociationpass.cpp

    r5157 r5160  
    302302 ** ------------------------------------------------------------------------------------------------------------- */
    303303inline bool BooleanReassociationPass::processScopes(PabloFunction & function) {
    304     mRefs.clear();
    305304    CharacterizationMap C;
    306305    PabloBlock * const entry = function.getEntryBlock();
     
    313312    mInFile = makeVar();
    314313    processScopes(entry, C);
     314    for (auto i = mRefs.begin(); i != mRefs.end(); ++i) {
     315        Z3_dec_ref(mContext, *i);
     316    }
     317    mRefs.clear();
    315318    return mModified;
    316319}
     
    345348            }
    346349        } else { // characterize this statement then check whether it is equivalent to any existing one.
    347             stmt = characterize(stmt, C);
     350            PabloAST * const folded = Simplifier::fold(stmt, block);
     351            if (LLVM_UNLIKELY(folded != nullptr)) {
     352                stmt = stmt->replaceWith(folded);
     353            } else {
     354                stmt = characterize(stmt, C);
     355            }
    348356        }
    349357    }   
     
    359367 ** ------------------------------------------------------------------------------------------------------------- */
    360368inline Statement * BooleanReassociationPass::characterize(Statement * const stmt, CharacterizationMap & C) {
     369
    361370    Z3_ast node = nullptr;
    362371    const size_t n = stmt->getNumOperands(); assert (n > 0);
     372    bool use_expensive_simplification = false;
    363373    if (isa<Variadic>(stmt)) {
    364374        Z3_ast operands[n];
    365375        for (size_t i = 0; i < n; ++i) {
    366             operands[i] = C.get(stmt->getOperand(i)); assert (operands[i]);
     376            PabloAST * const op = stmt->getOperand(i);
     377            if (isa<Not>(op)) {
     378                use_expensive_simplification = true;
     379            }
     380            operands[i] = C.get(op); assert (operands[i]);
    367381        }
    368382        if (isa<And>(stmt)) {
     
    395409        check[1] = isa<InFile>(stmt) ? mInFile : Z3_mk_not(mContext, mInFile); assert (check[1]);
    396410        node = Z3_mk_and(mContext, 2, check);
    397     } else {
    398         if (LLVM_UNLIKELY(isa<Assign>(stmt) || isa<Next>(stmt))) {
    399             Z3_ast op = C.get(stmt->getOperand(0)); assert (op);
    400             C.add(stmt, op, true);
    401         } else {
    402             C.add(stmt, makeVar());
    403         }
     411    } else if (LLVM_UNLIKELY(isa<Assign>(stmt) || isa<Next>(stmt))) {
    404412        return stmt->getNextNode();
    405     }
    406     Z3_inc_ref(mContext, node);
    407     node = simplify(node);
     413    }  else {
     414        C.add(stmt, makeVar());
     415        return stmt->getNextNode();
     416    }
     417    node = simplify(node, use_expensive_simplification);
    408418    PabloAST * const replacement = C.findKey(node);
    409419    if (LLVM_LIKELY(replacement == nullptr)) {
     
    440450 * are "flattened" (i.e., allowed to have any number of inputs.)
    441451 ** ------------------------------------------------------------------------------------------------------------- */
     452Vertex BooleanReassociationPass::transcribeSel(Sel * const stmt, CharacterizationMap & C, StatementMap & S, VertexMap & M, Graph & G) {
     453
     454    Z3_ast args[2];
     455
     456    const Vertex c = makeVertex(TypeId::Var, stmt->getCondition(), C, S, M, G);
     457    const Vertex t = makeVertex(TypeId::Var, cast<Sel>(stmt)->getTrueExpr(), C, S, M, G);
     458    const Vertex f = makeVertex(TypeId::Var, cast<Sel>(stmt)->getFalseExpr(), C, S, M, G);
     459
     460    args[0] = getDefinition(G[c]);
     461    args[1] = getDefinition(G[t]);
     462
     463    Z3_ast trueExpr = Z3_mk_and(mContext, 2, args);
     464    Z3_inc_ref(mContext, trueExpr);
     465    mRefs.push_back(trueExpr);
     466
     467    const Vertex x = makeVertex(TypeId::And, nullptr, G, trueExpr);
     468    add_edge(nullptr, c, x, G);
     469    add_edge(nullptr, t, x, G);
     470
     471    Z3_ast notCond = Z3_mk_not(mContext, args[0]);
     472    Z3_inc_ref(mContext, notCond);
     473    mRefs.push_back(notCond);
     474
     475    args[0] = notCond;
     476    args[1] = getDefinition(G[f]);
     477
     478    Z3_ast falseExpr = Z3_mk_and(mContext, 2, args);
     479    Z3_inc_ref(mContext, falseExpr);
     480    mRefs.push_back(falseExpr);
     481
     482    const Vertex n = makeVertex(TypeId::Not, nullptr, G, notCond);
     483
     484    add_edge(nullptr, c, n, G);
     485
     486    const Vertex y = makeVertex(TypeId::And, nullptr, G, falseExpr);
     487    add_edge(nullptr, n, y, G);
     488    add_edge(nullptr, f, y, G);
     489
     490    const Vertex u = makeVertex(TypeId::Or, stmt, C, S, M, G);
     491    add_edge(nullptr, x, u, G);
     492    add_edge(nullptr, y, u, G);
     493
     494    return u;
     495}
     496
     497/** ------------------------------------------------------------------------------------------------------------- *
     498 * @brief summarizeAST
     499 *
     500 * This function scans through a scope block and computes a DAG G in which any sequences of AND, OR or XOR functions
     501 * are "flattened" (i.e., allowed to have any number of inputs.)
     502 ** ------------------------------------------------------------------------------------------------------------- */
    442503void BooleanReassociationPass::transformAST(CharacterizationMap & C, Graph & G) {
    443504
    444505    StatementMap S;
     506
     507    VertexMap M;
    445508
    446509    // Compute the base def-use graph ...
    447510    for (Statement * stmt : *mBlock) {
    448         const Vertex u = makeVertex(stmt->getClassTypeId(), stmt, S, G, C.get(stmt));
    449         for (unsigned i = 0; i < stmt->getNumOperands(); ++i) {
    450             PabloAST * const op = stmt->getOperand(i);
    451             if (LLVM_LIKELY(isa<Statement>(op) || isa<Var>(op))) {
    452                 add_edge(op, makeVertex(TypeId::Var, op, C, S, G), u, G);
    453             }
    454         }
    455         if (LLVM_UNLIKELY(isa<If>(stmt))) {
    456             for (Assign * def : cast<const If>(stmt)->getDefined()) {
    457                 const Vertex v = makeVertex(TypeId::Var, def, C, S, G);
    458                 add_edge(def, u, v, G);
    459                 resolveNestedUsages(def, v, C, S, G, stmt);
    460             }
    461         } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
    462             // To keep G a DAG, we need to do a bit of surgery on loop variants because
    463             // the next variables it produces can be used within the condition. Instead,
    464             // we make the loop dependent on the original value of each Next node and
    465             // the Next node dependent on the loop.
    466             for (Next * var : cast<const While>(stmt)->getVariants()) {
    467                 const Vertex v = makeVertex(TypeId::Var, var, C, S, G);
    468                 assert (in_degree(v, G) == 1);
    469                 auto e = first(in_edges(v, G));
    470                 add_edge(G[e], source(e, G), u, G);
    471                 remove_edge(v, u, G);
    472                 add_edge(var, u, v, G);
    473                 resolveNestedUsages(var, v, C, S, G, stmt);
    474             }
     511        if (LLVM_UNLIKELY(isa<Sel>(stmt))) {
     512
     513            const Vertex u = transcribeSel(cast<Sel>(stmt), C, S, M, G);
     514
     515            resolveNestedUsages(stmt, u, C, S, M, G, stmt);
     516
    475517        } else {
    476             resolveNestedUsages(stmt, u, C, S, G, stmt);
    477         }
    478     }
    479 
    480 //    printGraph(G, "G");
    481 
    482     VertexMap M;
     518
     519
     520            const Vertex u = makeVertex(stmt->getClassTypeId(), stmt, C, S, M, G);
     521            for (unsigned i = 0; i < stmt->getNumOperands(); ++i) {
     522                PabloAST * const op = stmt->getOperand(i);
     523                if (LLVM_LIKELY(isa<Statement>(op) || isa<Var>(op))) {
     524                    add_edge(op, makeVertex(TypeId::Var, op, C, S, M, G), u, G);
     525                }
     526            }
     527            if (LLVM_UNLIKELY(isa<If>(stmt))) {
     528                for (Assign * def : cast<const If>(stmt)->getDefined()) {
     529                    const Vertex v = makeVertex(TypeId::Var, def, C, S, M, G);
     530                    add_edge(def, u, v, G);
     531                    resolveNestedUsages(def, v, C, S, M, G, stmt);
     532                }
     533                continue;
     534            } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
     535                // To keep G a DAG, we need to do a bit of surgery on loop variants because
     536                // the next variables it produces can be used within the condition. Instead,
     537                // we make the loop dependent on the original value of each Next node and
     538                // the Next node dependent on the loop.
     539                for (Next * var : cast<const While>(stmt)->getVariants()) {
     540                    const Vertex v = makeVertex(TypeId::Var, var, C, S, M, G);
     541                    assert (in_degree(v, G) == 1);
     542                    auto e = first(in_edges(v, G));
     543                    add_edge(G[e], source(e, G), u, G);
     544                    remove_edge(v, u, G);
     545                    add_edge(var, u, v, G);
     546                    resolveNestedUsages(var, v, C, S, M, G, stmt);
     547                }
     548                continue;
     549            } else {
     550                resolveNestedUsages(stmt, u, C, S, M, G, stmt);
     551            }
     552        }
     553
     554    }
     555
    483556    if (redistributeGraph(C, M, G)) {
    484557        factorGraph(G);
    485 
    486 //        printGraph(G, "H");
    487 
    488         rewriteAST(C, M, G);
     558        rewriteAST(G);
    489559        mModified = true;
    490560    }
     
    496566 ** ------------------------------------------------------------------------------------------------------------- */
    497567void BooleanReassociationPass::resolveNestedUsages(PabloAST * const expr, const Vertex u,
    498                                                    CharacterizationMap & C, StatementMap & S, Graph & G,
     568                                                   CharacterizationMap & C, StatementMap & S, VertexMap & M, Graph & G,
    499569                                                   const Statement * const ignoreIfThis) const {
    500570    assert ("Cannot resolve nested usages of a null expression!" && expr);
     
    504574            if (LLVM_UNLIKELY(parent != mBlock)) {
    505575                for (;;) {
    506                     if (parent->getParent() == mBlock) {
     576                    if (parent->getPredecessor () == mBlock) {
    507577                        Statement * const branch = parent->getBranch();
    508578                        if (LLVM_UNLIKELY(branch != ignoreIfThis)) {
    509579                            // Add in a Var denoting the user of this expression so that it can be updated if expr changes.
    510                             const Vertex v = makeVertex(TypeId::Var, user, C, S, G);
     580                            const Vertex v = makeVertex(TypeId::Var, user, C, S, M, G);
    511581                            add_edge(expr, u, v, G);
    512582                            const Vertex w = makeVertex(branch->getClassTypeId(), branch, S, G);
     
    515585                        break;
    516586                    }
    517                     parent = parent->getParent();
     587                    parent = parent->getPredecessor ();
    518588                    if (LLVM_UNLIKELY(parent == nullptr)) {
    519589                        assert (isa<Assign>(expr) || isa<Next>(expr));
     
    783853
    784854/** ------------------------------------------------------------------------------------------------------------- *
     855 * @brief recomputeDefinition
     856 ** ------------------------------------------------------------------------------------------------------------- */
     857inline Z3_ast BooleanReassociationPass::computeDefinition(const TypeId typeId, const Vertex u, Graph & G, const bool use_expensive_minimization) const {
     858    const unsigned n = in_degree(u, G);
     859    Z3_ast operands[n];
     860    unsigned k = 0;
     861    for (const auto e : make_iterator_range(in_edges(u, G))) {
     862        const auto v = source(e, G);
     863        if (LLVM_UNLIKELY(getDefinition(G[v]) == nullptr)) {
     864            throw std::runtime_error("No definition for " + std::to_string(v));
     865        }
     866        operands[k++] = getDefinition(G[v]);
     867    }
     868    assert (k == n);
     869    Z3_ast const node = (typeId == TypeId::And) ? Z3_mk_and(mContext, n, operands) : Z3_mk_or(mContext, n, operands);
     870    return simplify(node, use_expensive_minimization);
     871}
     872
     873/** ------------------------------------------------------------------------------------------------------------- *
     874 * @brief updateDefinition
     875 *
     876 * Apply the distribution law to reduce computations whenever possible.
     877 ** ------------------------------------------------------------------------------------------------------------- */
     878Vertex BooleanReassociationPass::updateIntermediaryDefinition(const TypeId typeId, const Vertex u, VertexMap & M, Graph & G) {
     879
     880    Z3_ast def = computeDefinition(typeId, u, G);
     881    Z3_ast orig = getDefinition(G[u]); assert (orig);
     882
     883    Z3_dec_ref(mContext, orig);
     884
     885    const auto g = M.find(orig);
     886    if (LLVM_LIKELY(g != M.end())) {
     887        M.erase(g);
     888    }
     889
     890    const auto f = std::find(mRefs.rbegin(), mRefs.rend(), orig);
     891    assert (f != mRefs.rend());
     892    *f = def;
     893
     894    const auto h = M.find(def);
     895    if (LLVM_UNLIKELY(h != M.end())) {
     896        const auto v = h->second;
     897        if (v != u) {
     898            for (auto e : make_iterator_range(out_edges(u, G))) {
     899                add_edge(G[e], v, target(e, G), G);
     900            }
     901            removeVertex(u, G);
     902            return v;
     903        }
     904    }
     905
     906    getDefinition(G[u]) = def;
     907    M.emplace(def, u);
     908    return u;
     909}
     910
     911/** ------------------------------------------------------------------------------------------------------------- *
     912 * @brief updateDefinition
     913 *
     914 * Apply the distribution law to reduce computations whenever possible.
     915 ** ------------------------------------------------------------------------------------------------------------- */
     916Vertex BooleanReassociationPass::updateSinkDefinition(const TypeId typeId, const Vertex u, CharacterizationMap & C, VertexMap & M, Graph & G) {
     917
     918    Z3_ast const def = computeDefinition(typeId, u, G);
     919
     920    auto f = M.find(def);
     921
     922    if (LLVM_UNLIKELY(f != M.end())) {
     923        Z3_dec_ref(mContext, def);
     924        Vertex v = f->second; assert (v != u);
     925        for (auto e : make_iterator_range(out_edges(u, G))) {
     926            add_edge(G[e], v, target(e, G), G);
     927        }
     928        removeVertex(u, G);
     929        return v;
     930    } else if (LLVM_LIKELY(C.predecessor() != nullptr)) {
     931        PabloAST * const factor = C.predecessor()->findKey(def);
     932        if (LLVM_UNLIKELY(factor != nullptr)) {
     933            getValue(G[u]) = factor;
     934            getType(G[u]) = TypeId::Var;
     935            clear_in_edges(u, G);
     936        }
     937    }
     938
     939    getDefinition(G[u]) = def;
     940    mRefs.push_back(def);
     941
     942    graph_traits<Graph>::in_edge_iterator begin, end;
     943
     944restart:
     945
     946    if (in_degree(u, G) > 1) {
     947        std::tie(begin, end) = in_edges(u, G);
     948        for (auto i = begin; ++i != end; ) {
     949            const auto v = source(*i, G);
     950            for (auto j = begin; j != i; ++j) {
     951                const auto w = source(*j, G);
     952                Z3_ast operands[2] = { getDefinition(G[v]), getDefinition(G[w]) };
     953                Z3_ast test = nullptr;
     954                switch (typeId) {
     955                    case TypeId::And:
     956                        test = Z3_mk_and(mContext, 2, operands); break;
     957                    case TypeId::Or:
     958                        test = Z3_mk_or(mContext, 2, operands); break;
     959                    case TypeId::Xor:
     960                        test = Z3_mk_xor(mContext, operands[0], operands[1]); break;
     961                    default:
     962                        llvm_unreachable("impossible type id");
     963                }
     964                test = simplify(test, true);
     965
     966                bool replacement = false;
     967                Vertex x = 0;
     968                const auto f = M.find(test);
     969                if (LLVM_UNLIKELY(f != M.end())) {
     970                    x = f->second;
     971                    Z3_ast orig = getDefinition(G[x]);
     972                    if (LLVM_UNLIKELY(orig != test)) {
     973                        std::string tmp;
     974                        raw_string_ostream out(tmp);
     975                        out << "vertex " << x << " is mapped to:\n"
     976                            << Z3_ast_to_string(mContext, test)
     977                            << "\n\nBut is recorded as:\n\n";
     978                        if (orig) {
     979                            out << Z3_ast_to_string(mContext, orig);
     980                        } else {
     981                            out << "<null>";
     982                        }
     983                        throw std::runtime_error(out.str());
     984                    }
     985                    Z3_dec_ref(mContext, test);
     986                    replacement = true;
     987                } else if (LLVM_LIKELY(C.predecessor() != nullptr)) {
     988                    PabloAST * const factor = C.predecessor()->findKey(test);
     989                    if (LLVM_UNLIKELY(factor != nullptr)) {
     990                        x = makeVertex(TypeId::Var, factor, G, test);
     991                        M.emplace(test, x);
     992                        replacement = true;
     993                        mRefs.push_back(test);
     994                    }
     995                }
     996
     997                if (LLVM_UNLIKELY(replacement)) {
     998
     999                    assert (G[*i] == nullptr);
     1000                    assert (G[*j] == nullptr);
     1001
     1002                    remove_edge(*i, G);
     1003                    remove_edge(*j, G);
     1004
     1005                    add_edge(nullptr, x, u, G);
     1006
     1007                    goto restart;
     1008                }
     1009
     1010                Z3_dec_ref(mContext, test);
     1011            }
     1012        }
     1013    }
     1014
     1015    M.emplace(def, u);
     1016
     1017    return u;
     1018}
     1019
     1020/** ------------------------------------------------------------------------------------------------------------- *
    7851021 * @brief redistributeAST
    7861022 *
     
    7911027    bool modified = false;
    7921028
     1029//    errs() << "=====================================================\n";
     1030
    7931031    DistributionGraph H;
    7941032
    795     contractGraph(G);
    796 
    7971033    for (;;) {
    7981034
    799         for (;;) {
    800 
    801             generateDistributionGraph(G, H);
    802 
    803             // If we found no potential opportunities then we cannot apply the distribution law to any part of G.
    804             if (num_vertices(H) == 0) {
    805                 break;
    806             }
    807 
    808             const DistributionSets distributionSets = safeDistributionSets(G, H);
    809 
    810             if (LLVM_UNLIKELY(distributionSets.empty())) {
    811                 break;
    812             }
    813 
    814             modified = true;
    815 
    816             for (const DistributionSet & set : distributionSets) {
    817 
    818                 // Each distribution tuple consists of the sources, intermediary, and sink nodes.
    819                 const VertexSet & sources = std::get<0>(set);
    820                 const VertexSet & intermediary = std::get<1>(set);
    821                 const VertexSet & sinks = std::get<2>(set);
    822 
    823                 const TypeId outerTypeId = getType(G[H[sinks.front()]]);
    824                 assert (outerTypeId == TypeId::And || outerTypeId == TypeId::Or);
    825                 const TypeId innerTypeId = (outerTypeId == TypeId::Or) ? TypeId::And : TypeId::Or;
    826 
    827                 const Vertex x = makeVertex(outerTypeId, nullptr, G);
    828                 const Vertex y = makeVertex(innerTypeId, nullptr, G);
    829 
    830                 // Update G to reflect the distributed operations (including removing the subgraph of
    831                 // the to-be distributed edges.)
    832 
    833                 add_edge(nullptr, x, y, G);
    834 
    835                 for (const Vertex i : sources) {
    836                     const auto u = H[i];
    837                     for (const Vertex j : intermediary) {
    838                         const auto v = H[j];
    839                         const auto e = edge(u, v, G); assert (e.second);
    840                         remove_edge(e.first, G);
    841                     }
    842                     add_edge(nullptr, u, y, G);
    843                 }
    844 
    845                 for (const Vertex i : intermediary) {
    846                     const auto u = H[i];
    847                     for (const Vertex j : sinks) {
    848                         const auto v = H[j];
    849                         const auto e = edge(u, v, G); assert (e.second);
    850                         add_edge(G[e.first], y, v, G);
    851                         remove_edge(e.first, G);
    852                     }
    853                     add_edge(nullptr, u, x, G);
    854                     getDefinition(G[u]) = nullptr;
    855                 }
    856 
    857             }
    858 
    859             H.clear();
    860 
    861             contractGraph(G);
    862         }
    863 
    864         // Although exceptionally unlikely, it's possible that if we can reduce the graph, we could
    865         // further simplify it. Restart the process if and only if we succeed.
    866         if (reduceGraph(C, M, G)) {
    867             if (LLVM_UNLIKELY(contractGraph(G))) {
    868                 H.clear();
    869                 continue;
    870             }
    871         }
    872 
    873         break;
     1035        contractGraph(M, G);
     1036
     1037//        printGraph(G, "G");
     1038
     1039        generateDistributionGraph(G, H);
     1040
     1041        // If we found no potential opportunities then we cannot apply the distribution law to any part of G.
     1042        if (num_vertices(H) == 0) {
     1043            break;
     1044        }
     1045
     1046        const DistributionSets distributionSets = safeDistributionSets(G, H);
     1047
     1048        if (LLVM_UNLIKELY(distributionSets.empty())) {
     1049            break;
     1050        }
     1051
     1052        modified = true;
     1053
     1054        mRefs.reserve(distributionSets.size() * 2);
     1055
     1056        for (const DistributionSet & set : distributionSets) {
     1057
     1058            // Each distribution tuple consists of the sources, intermediary, and sink nodes.
     1059            const VertexSet & sources = std::get<0>(set);
     1060            const VertexSet & intermediary = std::get<1>(set);
     1061            const VertexSet & sinks = std::get<2>(set);
     1062
     1063            const TypeId outerTypeId = getType(G[H[sinks.front()]]);
     1064            assert (outerTypeId == TypeId::And || outerTypeId == TypeId::Or);
     1065            const TypeId innerTypeId = (outerTypeId == TypeId::Or) ? TypeId::And : TypeId::Or;
     1066
     1067            const Vertex x = makeVertex(outerTypeId, nullptr, G);
     1068            const Vertex y = makeVertex(innerTypeId, nullptr, G);
     1069
     1070            // Update G to reflect the distributed operations (including removing the subgraph of
     1071            // the to-be distributed edges.)
     1072
     1073            add_edge(nullptr, x, y, G);
     1074
     1075            for (const Vertex i : sources) {
     1076                const auto u = H[i];
     1077                for (const Vertex j : intermediary) {
     1078                    const auto v = H[j];
     1079                    assert (getType(G[v]) == innerTypeId);
     1080                    const auto e = edge(u, v, G); assert (e.second);
     1081                    remove_edge(e.first, G);
     1082                }
     1083                add_edge(nullptr, u, y, G);
     1084            }
     1085
     1086            for (const Vertex i : intermediary) {
     1087
     1088                const auto u = updateIntermediaryDefinition(innerTypeId, H[i], M, G);
     1089
     1090                for (const Vertex j : sinks) {
     1091                    const auto v = H[j];
     1092                    assert (getType(G[v]) == outerTypeId);
     1093                    const auto e = edge(u, v, G); assert (e.second);
     1094                    add_edge(G[e.first], y, v, G);
     1095                    remove_edge(e.first, G);
     1096                }
     1097                add_edge(nullptr, u, x, G);
     1098            }
     1099
     1100            updateSinkDefinition(outerTypeId, x, C, M, G);
     1101
     1102            updateSinkDefinition(innerTypeId, y, C, M, G);
     1103
     1104        }
     1105
     1106        H.clear();
     1107
    8741108    }
    8751109
     
    9301164}
    9311165
    932 
    9331166/** ------------------------------------------------------------------------------------------------------------- *
    9341167 * @brief contractGraph
    9351168 ** ------------------------------------------------------------------------------------------------------------- */
    936 bool BooleanReassociationPass::contractGraph(Graph & G) const {
     1169bool BooleanReassociationPass::contractGraph(VertexMap & M, Graph & G) const {
    9371170
    9381171    bool contracted = false;
     
    9571190                        add_edge(G[ej], v, target(ej, G), G);
    9581191                    }
    959                     removeVertex(u, G);
     1192                    removeVertex(u, M, G);
    9601193                    contracted = true;
    9611194                } else if (LLVM_UNLIKELY(has_unique_target(u, G))) {
     
    9691202                            add_edge(G[ej], source(ej, G), v, G);
    9701203                        }
    971                         removeVertex(u, G);
     1204                        removeVertex(u, M, G);
    9721205                        contracted = true;
    9731206                    }
     
    9751208            }
    9761209        } else if (LLVM_UNLIKELY(isNonEscaping(G[u]))) {
    977             removeVertex(u, G);
     1210            removeVertex(u, M, G);
    9781211            contracted = true;
    9791212        }
    9801213    }
    9811214    return contracted;
    982 }
    983 
    984 /** ------------------------------------------------------------------------------------------------------------- *
    985  * @brief isReducible
    986  ** ------------------------------------------------------------------------------------------------------------- */
    987 inline bool isReducible(const VertexData & data) {
    988     switch (getType(data)) {
    989         case TypeId::Var:
    990         case TypeId::If:
    991         case TypeId::While:
    992             return false;
    993         default:
    994             return true;
    995     }
    996 }
    997 
    998 /** ------------------------------------------------------------------------------------------------------------- *
    999  * @brief reduceGraph
    1000  ** ------------------------------------------------------------------------------------------------------------- */
    1001 BooleanReassociationPass::Reduction BooleanReassociationPass::reduceVertex(const Vertex u, CharacterizationMap & C, VertexMap & M, Graph & G, const bool use_expensive_simplification) {
    1002 
    1003     Reduction reduction = Reduction::NoChange;
    1004 
    1005     assert (isReducible(G[u]));
    1006 
    1007     Z3_ast node = getDefinition(G[u]);
    1008     if (isAssociative(G[u])) {
    1009         const TypeId typeId = getType(G[u]);
    1010         if (node == nullptr) {
    1011             const auto n = in_degree(u, G); assert (n > 1);
    1012             Z3_ast operands[n];
    1013             unsigned i = 0;
    1014             for (auto e : make_iterator_range(in_edges(u, G))) {
    1015                 const Vertex v = source(e, G);
    1016                 assert (getDefinition(G[v]));
    1017                 operands[i++] = getDefinition(G[v]);
    1018             }
    1019             switch (typeId) {
    1020                 case TypeId::And:
    1021                     node = Z3_mk_and(mContext, n, operands);
    1022                     break;
    1023                 case TypeId::Or:
    1024                     node = Z3_mk_or(mContext, n, operands);
    1025                     break;
    1026                 case TypeId::Xor:
    1027                     node = Z3_mk_xor(mContext, operands[0], operands[1]);
    1028                     for (unsigned i = 2; LLVM_UNLIKELY(i < n); ++i) {
    1029                         node = Z3_mk_xor(mContext, node, operands[i]);
    1030                     }
    1031                     break;
    1032                 default: llvm_unreachable("unexpected type id");
    1033             }
    1034             assert (node);
    1035             Z3_inc_ref(mContext, node);
    1036             mRefs.push_back(node);
    1037             getDefinition(G[u]) = node;
    1038         }
    1039 
    1040         graph_traits<Graph>::in_edge_iterator begin, end;
    1041 restart:if (in_degree(u, G) > 1) {
    1042             std::tie(begin, end) = in_edges(u, G);
    1043             for (auto i = begin; ++i != end; ) {
    1044                 const auto v = source(*i, G);
    1045                 for (auto j = begin; j != i; ++j) {
    1046                     const auto w = source(*j, G);
    1047                     Z3_ast operands[2] = { getDefinition(G[v]), getDefinition(G[w]) };
    1048                     Z3_ast test = nullptr;
    1049                     switch (typeId) {
    1050                         case TypeId::And:
    1051                             test = Z3_mk_and(mContext, 2, operands); break;
    1052                         case TypeId::Or:
    1053                             test = Z3_mk_or(mContext, 2, operands); break;
    1054                         case TypeId::Xor:
    1055                             test = Z3_mk_xor(mContext, operands[0], operands[1]); break;
    1056                         default:
    1057                             llvm_unreachable("impossible type id");
    1058                     }
    1059                     assert (test);
    1060                     Z3_inc_ref(mContext, test);
    1061                     test = simplify(test, use_expensive_simplification);
    1062                     bool replacement = false;
    1063                     Vertex x = 0;
    1064                     const auto f = M.find(test);
    1065                     if (LLVM_UNLIKELY(f != M.end())) {
    1066                         x = f->second;
    1067                         assert (getDefinition(G[x]) == test);
    1068                         Z3_dec_ref(mContext, test);
    1069                         replacement = true;
    1070                     } else if (LLVM_LIKELY(C.predecessor() != nullptr)) {
    1071                         PabloAST * const factor = C.predecessor()->findKey(test);
    1072                         if (LLVM_UNLIKELY(factor != nullptr)) {
    1073                             x = makeVertex(TypeId::Var, factor, G, test);
    1074                             M.emplace(test, x);
    1075                             replacement = true;
    1076                             mRefs.push_back(test);
    1077                         }
    1078                     }
    1079 
    1080                     if (LLVM_UNLIKELY(replacement)) {
    1081 
    1082                         // note: unless both edges carry an Pablo AST replacement value, they will converge into a single edge.
    1083                         PabloAST * const r1 = G[*i];
    1084                         PabloAST * const r2 = G[*j];
    1085 
    1086                         remove_edge(*i, G);
    1087                         remove_edge(*j, G);
    1088 
    1089                         if (LLVM_UNLIKELY(r1 && r2)) {
    1090                             add_edge(r1, x, u, G);
    1091                             add_edge(r2, x, u, G);
    1092                         } else {
    1093                             add_edge(r1 ? r1 : r2, x, u, G);
    1094                         }
    1095 
    1096                         reduction = Reduction::Simplified;
    1097 
    1098                         goto restart;
    1099                     }
    1100 
    1101                     Z3_dec_ref(mContext, test);
    1102                 }
    1103             }
    1104         }
    1105     }
    1106 
    1107     if (LLVM_UNLIKELY(node == nullptr)) {
    1108         throw std::runtime_error("No Z3 characterization for vertex " + std::to_string(u));
    1109     }
    1110 
    1111     auto f = M.find(node);
    1112     if (LLVM_LIKELY(f == M.end())) {
    1113         M.emplace(node, u);
    1114     } else if (isAssociative(G[u])) {
    1115         const Vertex v = f->second;
    1116         for (auto e : make_iterator_range(out_edges(u, G))) {
    1117             add_edge(G[e], v, target(e, G), G);
    1118         }
    1119         removeVertex(u, G);
    1120         reduction = Reduction::Removed;
    1121     }
    1122 
    1123     return reduction;
    1124 }
    1125 
    1126 /** ------------------------------------------------------------------------------------------------------------- *
    1127  * @brief reduceGraph
    1128  ** ------------------------------------------------------------------------------------------------------------- */
    1129 bool BooleanReassociationPass::reduceGraph(CharacterizationMap & C, VertexMap & M, Graph & G) {
    1130 
    1131     bool reduced = false;
    1132 
    1133     circular_buffer<Vertex> ordering(num_vertices(G));
    1134 
    1135     topological_sort(G, std::front_inserter(ordering)); // topological ordering
    1136 
    1137     M.clear();
    1138 
    1139     // first contract the graph
    1140     for (const Vertex u : ordering) {
    1141         if (isReducible(G[u])) {
    1142             if (reduceVertex(u, C, M, G, false) != Reduction::NoChange) {
    1143                 reduced = true;
    1144             }
    1145         }
    1146     }
    1147     return reduced;
    11481215}
    11491216
     
    12401307}
    12411308
    1242 
     1309/** ------------------------------------------------------------------------------------------------------------- *
     1310 * @brief isMutable
     1311 ** ------------------------------------------------------------------------------------------------------------- */
    12431312inline bool isMutable(const Vertex u, const Graph & G) {
    12441313    return getType(G[u]) != TypeId::Var;
     
    12481317 * @brief rewriteAST
    12491318 ** ------------------------------------------------------------------------------------------------------------- */
    1250 bool BooleanReassociationPass::rewriteAST(CharacterizationMap & C, VertexMap & M, Graph & G) {
     1319bool BooleanReassociationPass::rewriteAST(Graph & G) {
    12511320
    12521321    using line_t = long long int;
    12531322
    12541323    enum : line_t { MAX_INT = std::numeric_limits<line_t>::max() };
     1324
     1325    // errs() << "---------------------------------------------------------\n";
     1326
     1327    // printGraph(G, "X");
    12551328
    12561329    Z3_config cfg = Z3_mk_config();
     
    13271400    std::vector<line_t> L(num_vertices(G));
    13281401
    1329 
    1330 
    13311402    for (const Vertex u : make_iterator_range(vertices(G))) {
    13321403        line_t line = LoadEarly ? 0 : MAX_INT;
     
    13451416
    13461417    Z3_model_dec_ref(ctx, model);
     1418    Z3_solver_dec_ref(ctx, solver);
     1419    Z3_del_context(ctx);
    13471420
    13481421    std::sort(S.begin(), S.end(), [&L](const Vertex u, const Vertex v){ return L[u] < L[v]; });
     
    13531426
    13541427    line_t count = 1;
    1355 
    1356 //    errs() << "--------------------------------------------------\n";
    1357 
    1358 //    printGraph(G, "G");
    13591428
    13601429    for (auto u : S) {
     
    13641433        assert (L[u] > 0 && L[u] < MAX_INT);
    13651434
     1435        bool append = true;
     1436
    13661437        if (isAssociative(G[u])) {
    13671438
     
    13741445
    13751446            const auto typeId = getType(G[u]);
    1376 
    1377 // retry:
    13781447
    13791448            T.clear();
     
    14291498                            llvm_unreachable("Invalid TypeId!");
    14301499                    }
    1431 
    1432 //                    // If the insertion point isn't the statement we just attempted to create
    1433 //                    // we must have unexpectidly reused a prior statement (or Var.)
    1434 //                    if (LLVM_UNLIKELY(expr != mBlock->getInsertPoint())) {
    1435 //                        const auto reduction = reduceVertex(u, C, M, G, true);
    1436 //                        if (LLVM_UNLIKELY(reduction == Reduction::NoChange)) {
    1437 //                            throw std::runtime_error("Unable to reduce vertex " + std::to_string(u));
    1438 //                        } else if (LLVM_UNLIKELY(reduction == Reduction::Simplified)) {
    1439 //                            goto retry;
    1440 //                        } else { // if (reduction == Reduction::Removed) {
    1441 //                            mBlock->setInsertPoint(ip->getPrevNode());
    1442 //                            goto next_statement;
    1443 //                        }
    1444 //                    }
    14451500                }
    14461501                join = expr;
     
    14521507
    14531508            mBlock->setInsertPoint(ip->getPrevNode());
    1454 
    1455             for (auto e : make_iterator_range(out_edges(u, G))) {
    1456                 if (G[e]) {
    1457                     if (PabloAST * user = getValue(G[target(e, G)])) {
    1458                         cast<Statement>(user)->replaceUsesOfWith(G[e], expr);
    1459                     }
    1460                 }
    1461             }
    14621509
    14631510            stmt = expr;
     
    14791526                    }
    14801527                }
    1481                 continue;
    1482             }
    1483         }
    1484 
    1485         assert (stmt);
    1486 
    1487         if (LLVM_UNLIKELY(isa<If>(stmt) || isa<While>(stmt))) {
     1528                append = false;
     1529            }
     1530        } else if (stmt == nullptr) {
     1531            assert (getType(G[u]) == TypeId::Not);
     1532            assert (in_degree(u, G) == 1);
     1533            PabloAST * op = getValue(G[source(first(in_edges(u, G)), G)]); assert (op);
     1534            stmt = mBlock->createNot(op);
     1535        } else if (LLVM_UNLIKELY(isa<If>(stmt) || isa<While>(stmt))) {
    14881536            for (auto e : make_iterator_range(out_edges(u, G))) {
    14891537                const auto v = target(e, G);
     
    14931541        }
    14941542
    1495 //        PabloPrinter::print(cast<Statement>(stmt), errs()); errs() << "\n";
    1496 
    1497         mBlock->insert(cast<Statement>(stmt));
    1498         L[u] = count++; // update the line count with the actual one.
    1499 //        next_statement: continue;
    1500     }
    1501 
    1502     Z3_solver_dec_ref(ctx, solver);
    1503     Z3_del_context(ctx);
     1543        for (auto e : make_iterator_range(out_edges(u, G))) {
     1544            if (G[e]) {
     1545                if (PabloAST * user = getValue(G[target(e, G)])) {
     1546                    cast<Statement>(user)->replaceUsesOfWith(G[e], stmt);
     1547                }
     1548            }
     1549        }
     1550
     1551        if (LLVM_LIKELY(append)) {
     1552            mBlock->insert(cast<Statement>(stmt));
     1553            L[u] = count++; // update the line count with the actual one.
     1554        }
     1555    }
    15041556
    15051557    Statement * const end = mBlock->getInsertPoint(); assert (end);
     
    15341586
    15351587/** ------------------------------------------------------------------------------------------------------------- *
    1536  * @brief addSummaryVertex
     1588* @brief makeVertex
     1589** ------------------------------------------------------------------------------------------------------------- */
     1590Vertex BooleanReassociationPass::makeVertex(const TypeId typeId, PabloAST * const expr, CharacterizationMap & C, StatementMap & S, VertexMap & M, Graph & G) {
     1591    assert (expr);
     1592    const auto f = S.find(expr);
     1593    if (f != S.end()) {
     1594        assert (getValue(G[f->second]) == expr);
     1595        return f->second;
     1596    }
     1597    const auto node = C.get(expr);   
     1598    const Vertex u = makeVertex(typeId, expr, G, node);
     1599    S.emplace(expr, u);
     1600    if (node) {
     1601        M.emplace(node, u);
     1602    }
     1603    return u;
     1604}
     1605
     1606/** ------------------------------------------------------------------------------------------------------------- *
     1607 * @brief makeVertex
     1608 ** ------------------------------------------------------------------------------------------------------------- */
     1609Vertex BooleanReassociationPass::makeVertex(const TypeId typeId, PabloAST * const expr, StatementMap & M, Graph & G, Z3_ast node) {
     1610    assert (expr);
     1611    const auto f = M.find(expr);
     1612    if (f != M.end()) {
     1613        assert (getValue(G[f->second]) == expr);
     1614        return f->second;
     1615    }
     1616    const Vertex u = makeVertex(typeId, expr, G, node);
     1617    M.emplace(expr, u);
     1618    return u;
     1619}
     1620
     1621/** ------------------------------------------------------------------------------------------------------------- *
     1622 * @brief makeVertex
    15371623 ** ------------------------------------------------------------------------------------------------------------- */
    15381624Vertex BooleanReassociationPass::makeVertex(const TypeId typeId, PabloAST * const expr, Graph & G, Z3_ast node) {
     
    15481634
    15491635/** ------------------------------------------------------------------------------------------------------------- *
    1550  * @brief addSummaryVertex
    1551  ** ------------------------------------------------------------------------------------------------------------- */
    1552 Vertex BooleanReassociationPass::makeVertex(const TypeId typeId, PabloAST * const expr, StatementMap & M, Graph & G, Z3_ast node) {
    1553     assert (expr);
    1554     const auto f = M.find(expr);
    1555     if (f != M.end()) {
    1556         assert (getValue(G[f->second]) == expr);
    1557         return f->second;
    1558     }
    1559     const Vertex u = makeVertex(typeId, expr, G, node);
    1560     M.emplace(expr, u);
    1561     return u;
    1562 }
    1563 
    1564 /** ------------------------------------------------------------------------------------------------------------- *
    1565  * @brief addSummaryVertex
    1566  ** ------------------------------------------------------------------------------------------------------------- */
    1567 Vertex BooleanReassociationPass::makeVertex(const TypeId typeId, PabloAST * const expr, CharacterizationMap & C, StatementMap & M, Graph & G) {
    1568     assert (expr);
    1569     const auto f = M.find(expr);
    1570     if (f != M.end()) {
    1571         assert (getValue(G[f->second]) == expr);
    1572         return f->second;
    1573     }
    1574     const Vertex u = makeVertex(typeId, expr, G, C.get(expr));
    1575     M.emplace(expr, u);
    1576     return u;
    1577 }
    1578 
    1579 /** ------------------------------------------------------------------------------------------------------------- *
    1580  * @brief removeSummaryVertex
    1581  ** ------------------------------------------------------------------------------------------------------------- */
    1582 inline void BooleanReassociationPass::removeVertex(const Vertex u, StatementMap & M, Graph & G) const {
     1636 * @brief removeVertex
     1637 ** ------------------------------------------------------------------------------------------------------------- */
     1638inline void BooleanReassociationPass::removeVertex(const Vertex u, VertexMap & M, Graph & G) const {
    15831639    VertexData & ref = G[u];
    1584     if (std::get<1>(ref)) {
    1585         auto f = M.find(std::get<1>(ref));
    1586         assert (f != M.end());
    1587         M.erase(f);
    1588     }
     1640    Z3_ast def = getDefinition(ref); assert (def);
     1641    auto f = M.find(def); assert (f != M.end());
     1642    M.erase(f);
    15891643    removeVertex(u, G);
    15901644}
    15911645
    15921646/** ------------------------------------------------------------------------------------------------------------- *
    1593  * @brief removeSummaryVertex
     1647 * @brief removeVertex
    15941648 ** ------------------------------------------------------------------------------------------------------------- */
    15951649inline void BooleanReassociationPass::removeVertex(const Vertex u, Graph & G) const {
     
    16141668 * @brief simplify
    16151669 ** ------------------------------------------------------------------------------------------------------------- */
    1616 Z3_ast BooleanReassociationPass::simplify(Z3_ast const node, bool use_expensive_minimization) const {
     1670inline Z3_ast BooleanReassociationPass::simplify(Z3_ast const node, bool use_expensive_minimization) const {
    16171671    assert (node);
    1618     Z3_ast result = Z3_simplify_ex(mContext, node, mParams);
    1619     Z3_inc_ref(mContext, result);
     1672    Z3_inc_ref(mContext, node);
     1673    Z3_ast result = nullptr;
    16201674    if (use_expensive_minimization) {
    1621         Z3_goal g = Z3_mk_goal(mContext, true, false, false);
     1675
     1676        Z3_goal g = Z3_mk_goal(mContext, true, false, false); assert (g);
    16221677        Z3_goal_inc_ref(mContext, g);
    1623         Z3_goal_assert(mContext, g, result);
    1624 
    1625         Z3_apply_result r = Z3_tactic_apply(mContext, mTactic, g);
     1678        Z3_goal_assert(mContext, g, node);
     1679
     1680        Z3_apply_result r = Z3_tactic_apply(mContext, mTactic, g); assert (r);
    16261681        Z3_apply_result_inc_ref(mContext, r);
     1682        Z3_goal_dec_ref(mContext, g);
     1683
    16271684        assert (Z3_apply_result_get_num_subgoals(mContext, r) == 1);
    16281685
    1629         Z3_goal h = Z3_apply_result_get_subgoal(mContext, r, 0);
     1686        Z3_goal h = Z3_apply_result_get_subgoal(mContext, r, 0); assert (h);
    16301687        Z3_goal_inc_ref(mContext, h);
    1631         Z3_goal_dec_ref(mContext, g);
     1688        Z3_apply_result_dec_ref(mContext, r);
    16321689
    16331690        const unsigned n = Z3_goal_size(mContext, h);
    16341691
    1635         Z3_ast optimized = nullptr;
    16361692        if (n == 1) {
    1637             optimized = Z3_goal_formula(mContext, h, 0);
    1638             Z3_inc_ref(mContext, optimized);
    1639 
     1693            result = Z3_goal_formula(mContext, h, 0); assert (result);
     1694            Z3_inc_ref(mContext, result);
    16401695        } else if (n > 1) {
    16411696            Z3_ast operands[n];
     
    16441699                Z3_inc_ref(mContext, operands[i]);
    16451700            }
    1646             optimized = Z3_mk_and(mContext, n, operands);
    1647             Z3_inc_ref(mContext, optimized);
     1701            result = Z3_mk_and(mContext, n, operands); assert (result);
     1702            Z3_inc_ref(mContext, result);
    16481703            for (unsigned i = 0; i < n; ++i) {
    16491704                Z3_dec_ref(mContext, operands[i]);
    16501705            }
     1706        } else {
     1707            result = Z3_mk_true(mContext); assert (result);
    16511708        }
    16521709        Z3_goal_dec_ref(mContext, h);
    1653         Z3_apply_result_dec_ref(mContext, r);
    1654         Z3_dec_ref(mContext, result);
    1655         result = optimized;
    1656     }
     1710
     1711    } else {       
     1712        result = Z3_simplify_ex(mContext, node, mParams); assert (result);
     1713        Z3_inc_ref(mContext, result);
     1714    }   
    16571715    Z3_dec_ref(mContext, node);
     1716    assert (result);
    16581717    return result;
    16591718}
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/booleanreassociationpass.h

    r5157 r5160  
    1111class BooleanReassociationPass {
    1212public:
    13     using VertexData = std::tuple<PabloAST::ClassTypeId, PabloAST *, Z3_ast>;
     13    using TypeId = PabloAST::ClassTypeId;
     14    using VertexData = std::tuple<TypeId, PabloAST *, Z3_ast>;
    1415    using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, VertexData, PabloAST *>;
    1516    using Vertex = Graph::vertex_descriptor;
     
    4748    void distributeScope(PabloBlock * const block, CharacterizationMap & C);
    4849
     50    Vertex transcribeSel(Sel * const stmt, CharacterizationMap & C, StatementMap & S, VertexMap & M, Graph & G);
    4951    void transformAST(CharacterizationMap & C, Graph & G);
    50     void resolveNestedUsages(PabloAST * const expr, const Vertex u, CharacterizationMap &C, StatementMap & S, Graph & G, const Statement * const ignoreIfThis = nullptr) const;
     52    void resolveNestedUsages(PabloAST * const expr, const Vertex u, CharacterizationMap & C, StatementMap & S, VertexMap &M, Graph & G, const Statement * const ignoreIfThis = nullptr) const;
    5153
    52     bool contractGraph(Graph & G) const;
     54    bool contractGraph(VertexMap & M, Graph & G) const;
    5355
    54     bool reduceGraph(CharacterizationMap & C, VertexMap & M, Graph & G);
     56    void reduceVertex(const Vertex u, CharacterizationMap & C, VertexMap & M, Graph & G);
    5557
    56     enum class Reduction {
    57         NoChange
    58         , Simplified
    59         , Removed
    60     };
    61 
    62     Reduction reduceVertex(const Vertex u, CharacterizationMap & C, VertexMap & M, Graph & G, const bool use_expensive_simplification);
    63 
    64     bool factorGraph(const PabloAST::ClassTypeId typeId, Graph & G, std::vector<Vertex> & factors) const;
     58    bool factorGraph(const TypeId typeId, Graph & G, std::vector<Vertex> & factors) const;
    6559    bool factorGraph(Graph & G) const;
    6660
    67     static Vertex makeVertex(const PabloAST::ClassTypeId typeId, PabloAST * const expr, Graph & G, Z3_ast node = nullptr);
    68     static Vertex makeVertex(const PabloAST::ClassTypeId typeId, PabloAST * const expr, StatementMap & M, Graph & G, Z3_ast node = nullptr);
    69     static Vertex makeVertex(const PabloAST::ClassTypeId typeId, PabloAST * const expr, CharacterizationMap & C, StatementMap & M, Graph & G);
    70     void removeVertex(const Vertex u, StatementMap & M, Graph & G) const;
     61    static Vertex makeVertex(const TypeId typeId, PabloAST * const expr, Graph & G, Z3_ast node = nullptr);
     62    static Vertex makeVertex(const TypeId typeId, PabloAST * const expr, StatementMap & M, Graph & G, Z3_ast node = nullptr);
     63    static Vertex makeVertex(const TypeId typeId, PabloAST * const expr, CharacterizationMap & C, StatementMap & S, VertexMap & M, Graph & G);
     64
     65    void removeVertex(const Vertex u, VertexMap & M, Graph & G) const;
    7166    void removeVertex(const Vertex u, Graph & G) const;
    7267
     68    Z3_ast computeDefinition(const TypeId typeId, const Vertex u, Graph & G, const bool use_expensive_minimization = false) const;
     69    Vertex updateIntermediaryDefinition(const TypeId typeId, const Vertex u, VertexMap & M, Graph & G);
     70    Vertex updateSinkDefinition(const TypeId typeId, const Vertex u, CharacterizationMap &C, VertexMap & M, Graph & G);
    7371    bool redistributeGraph(CharacterizationMap & C, VertexMap & M, Graph & G);
    7472
    75     bool rewriteAST(CharacterizationMap & C, VertexMap &M, Graph & G);
     73    bool rewriteAST(Graph & G);
    7674
    7775    Statement * characterize(Statement * const stmt, CharacterizationMap & map);
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/codemotionpass.cpp

    r4927 r5160  
    5757        ++depth;
    5858        assert (scope);
    59         scope = scope->getParent();
     59        scope = scope->getPredecessor ();
    6060    }
    6161    return depth;
     
    126126                // the scope tree until both scopes are at the same depth.
    127127                while (depth1 > depth2) {
    128                     scope1 = scope1->getParent();
     128                    scope1 = scope1->getPredecessor ();
    129129                    --depth1;
    130130                }
    131131                while (depth1 < depth2) {
    132                     scope2 = scope2->getParent();
     132                    scope2 = scope2->getPredecessor ();
    133133                    --depth2;
    134134                }
     
    138138                while (scope1 != scope2) {
    139139                    assert (scope1 && scope2);
    140                     scope1 = scope1->getParent();
    141                     scope2 = scope2->getParent();
     140                    scope1 = scope1->getPredecessor ();
     141                    scope2 = scope2->getPredecessor ();
    142142                }
    143143                assert (scope1);
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/distributivepass.cpp

    r5082 r5160  
    239239inline unsigned scopeDepthOf(const PabloBlock * block) {
    240240    unsigned depth = 0;
    241     for (; block; ++depth, block = block->getParent());
     241    for (; block; ++depth, block = block->getPredecessor ());
    242242    return depth;
    243243}
     
    267267        // the scope tree until both scopes are at the same depth.
    268268        while (depth1 > depth2) {
    269             scope1 = scope1->getParent();
     269            scope1 = scope1->getPredecessor ();
    270270            --depth1;
    271271        }
    272272        while (depth1 < depth2) {
    273             scope2 = scope2->getParent();
     273            scope2 = scope2->getPredecessor ();
    274274            --depth2;
    275275        }
     
    278278        // the LCA of our original pair.
    279279        while (scope1 != scope2) {
    280             scope1 = scope1->getParent();
    281             scope2 = scope2->getParent();
     280            scope1 = scope1->getPredecessor ();
     281            scope2 = scope2->getPredecessor ();
    282282        }
    283283        assert (scope1 && scope2);
     
    297297            assert (scope);
    298298            user = scope->getBranch();
    299             scope = scope->getParent();
     299            scope = scope->getPredecessor ();
    300300        }
    301301        usages.insert(user);
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_automultiplexing.cpp

    r5156 r5160  
    7070void MultiplexingPass::optimize() {
    7171    // Map the constants and input variables
    72     add(PabloBlock::createZeroes(), Z3_mk_false(mContext), -1);
    73     add(PabloBlock::createOnes(), Z3_mk_true(mContext), -1);
     72    PabloBlock * entryBlock = mFunction.getEntryBlock();
     73    add(entryBlock->createZeroes(), Z3_mk_false(mContext), -1);
     74    add(entryBlock->createOnes(), Z3_mk_true(mContext), -1);
    7475    for (unsigned i = 0; i < mFunction.getNumOfParameters(); ++i) {
    7576        add(mFunction.getParameter(i), makeVar(), -1);
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_simplifier.cpp

    r5156 r5160  
    5555        if (LLVM_UNLIKELY(isa<Zeroes>(var->getOperand(i)))) {
    5656            if (LLVM_UNLIKELY(isa<And>(var))) {
    57                 return PabloBlock::createZeroes();
     57                return block->createZeroes(var->getType());
    5858            }
    5959            var->removeOperand(i);
     
    6161        } else if (LLVM_UNLIKELY(isa<Ones>(var->getOperand(i)))) {
    6262            if (LLVM_UNLIKELY(isa<Or>(var))) {
    63                 return PabloBlock::createOnes();
     63                return block->createOnes(var->getType());
    6464            } else if (LLVM_UNLIKELY(isa<Xor>(var))) {
    6565                negated = !negated;
     
    140140                                        block->setInsertPoint(var->getPrevNode());
    141141                                        if (typeId == TypeId::And) {
    142                                             expr = block->createAnd(operands - 1);
     142                                            expr = block->createAnd(var->getType(), operands - 1);
    143143                                        } else { // if (typeId == TypeId::Or) {
    144                                             expr = block->createOr(operands - 1);
     144                                            expr = block->createOr(var->getType(), operands - 1);
    145145                                        }
    146146                                        for (unsigned k = 0; k != di; ++k) {
     
    221221                    if (LLVM_UNLIKELY(var->getOperand(j) == negated)) {
    222222                        if (isa<And>(var)) { // (A ∧ ¬A) ∧ B ⇔ 0 for any B
    223                             return PabloBlock::createZeroes();
     223                            return block->createZeroes(var->getType());
    224224                        } else { // if (isa<Or>(var)) { // (A √ ¬A) √ B ⇔ 1 for any B
    225                             return PabloBlock::createOnes();
     225                            return block->createOnes(var->getType());
    226226                        }
    227227                    }
     
    234234    if (LLVM_UNLIKELY(var->getNumOperands() < 2)) {
    235235        if (LLVM_UNLIKELY(var->getNumOperands() == 0)) {
    236             return PabloBlock::createZeroes();
     236            return block->createZeroes(var->getType());
    237237        }
    238238        replacement = var->getOperand(0);
     
    249249 * @brief fold
    250250 ** ------------------------------------------------------------------------------------------------------------- */
    251 inline PabloAST * Simplifier::fold(Statement * stmt, PabloBlock * const block) {
     251PabloAST * Simplifier::fold(Statement * stmt, PabloBlock * const block) {
    252252    if (isa<Variadic>(stmt)) {
    253253        return fold(cast<Variadic>(stmt), block);
     
    257257            return cast<Not>(value)->getOperand(0); // ¬¬A ⇔ A
    258258        } else if (LLVM_UNLIKELY(isa<Zeroes>(value))) {
    259             return PabloBlock::createOnes(); // ¬0 ⇔ 1
     259            return block->createOnes(stmt->getType()); // ¬0 ⇔ 1
    260260        }  else if (LLVM_UNLIKELY(isa<Ones>(value))) {
    261             return PabloBlock::createZeroes(); // ¬1 ⇔ 0
     261            return block->createZeroes(stmt->getType()); // ¬1 ⇔ 0
    262262        }
    263263    } else if (isa<Advance>(stmt)) {
    264264        if (LLVM_UNLIKELY(isa<Zeroes>(stmt->getOperand(0)))) {
    265             return PabloBlock::createZeroes();
     265            return block->createZeroes(stmt->getType());
    266266        }
    267267    } else {
     
    292292                    case PabloAST::ClassTypeId::ScanThru:
    293293                        if (LLVM_UNLIKELY(i == 1)) {
    294                             return PabloBlock::createZeroes();
     294                            return block->createZeroes(stmt->getType());
    295295                        }
    296296                        break;
    297297                    case PabloAST::ClassTypeId::MatchStar:
    298298                        if (LLVM_UNLIKELY(i == 0)) {
    299                             return PabloBlock::createOnes();
     299                            return block->createOnes(stmt->getType());
    300300                        }
    301301                        break;
     
    370370                    break;
    371371                }
    372                 parent = parent->getParent();
     372                parent = parent->getPredecessor ();
    373373            }
    374374        }
     
    430430    ExpressionTable encountered(predecessor);
    431431    Statement * stmt = block->front();
    432 
    433432    while (stmt) {
    434433        if (Assign * assign = dyn_cast<Assign>(stmt)) {
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_simplifier.hpp

    r5156 r5160  
    1212    friend class DistributivePass;
    1313    friend class FactorizeDFG;
     14    friend class BooleanReassociationPass;
    1415public:
    1516    static bool optimize(PabloFunction & function);
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/schedulingprepass.cpp

    r4919 r5160  
    7171            const PabloBlock * scope = cast<Statement>(use)->getParent();
    7272            if (scope != block) {
    73                 for (PabloBlock * prior = scope->getParent(); prior; scope = prior, prior = prior->getParent()) {
     73                for (PabloBlock * prior = scope->getPredecessor (); prior; scope = prior, prior = prior->getPredecessor ()) {
    7474                    if (prior == block) {
    7575                        assert (scope->getBranch());
     
    114114                    // if this statement isn't an Assign or Next node, it cannot come from a nested scope
    115115                    // unless the function is invalid.
    116                     for (PabloBlock * prior = scope->getParent(); prior; scope = prior, prior = prior->getParent()) {
     116                    for (PabloBlock * prior = scope->getPredecessor (); prior; scope = prior, prior = prior->getPredecessor ()) {
    117117                        // Was this instruction computed by a nested block?
    118118                        if (prior == block) {
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.cpp

    r5156 r5160  
    133133}
    134134
    135 
    136135/** ------------------------------------------------------------------------------------------------------------- *
    137136 * @brief checkEscapedValueList
     
    154153                            return;
    155154                        }
    156                         parent = parent->getParent();
     155                        parent = parent->getPredecessor ();
    157156                        if (parent == nullptr) {
    158157                            break;
     
    188187 * @brief setOperand
    189188 ** ------------------------------------------------------------------------------------------------------------- */
    190 void Statement::setOperand(const unsigned index, PabloAST * const value) {
     189void Statement::setOperand(const unsigned index, PabloAST * const value) {   
    191190    assert ("Operand cannot be null!" && value);
    192191    assert (index < getNumOperands());
     
    196195        return;
    197196    }   
     197    throwIfNonMatchingTypes(prior, value);
    198198    prior->removeUser(this);
    199199    mOperand[index] = value;
     
    227227    if (LLVM_UNLIKELY(isa<If>(this) || isa<While>(this))) {
    228228        PabloBlock * body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
    229         body->setParent(mParent);
     229        body->setPredecessor (mParent);
    230230    }
    231231}
     
    255255    if (LLVM_UNLIKELY(isa<If>(this) || isa<While>(this))) {
    256256        PabloBlock * body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
    257         body->setParent(mParent);
     257        body->setPredecessor (mParent);
    258258    }
    259259}
     
    282282        if (LLVM_UNLIKELY(isa<If>(this) || isa<While>(this))) {
    283283            PabloBlock * body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
    284             body->setParent(nullptr);
     284            body->setPredecessor (nullptr);
    285285        }
    286286    }
     
    295295 ** ------------------------------------------------------------------------------------------------------------- */
    296296Statement * Statement::eraseFromParent(const bool recursively) {
     297
     298    if (LLVM_UNLIKELY(getParent() == nullptr)) {
     299        return nullptr;
     300    }
    297301
    298302    SmallVector<Statement *, 1> redundantBranches;
     
    334338    }
    335339
    336     replaceAllUsesWith(PabloBlock::createZeroes());
     340    replaceAllUsesWith(getParent()->createZeroes(getType()));
    337341
    338342    if (recursively) {
     
    394398 ** ------------------------------------------------------------------------------------------------------------- */
    395399void Variadic::addOperand(PabloAST * const expr) {
     400    throwIfNonMatchingTypes(this, expr);
    396401    if (LLVM_UNLIKELY(mOperands == mCapacity)) {
    397402        mCapacity = std::max<unsigned>(mCapacity * 2, 2);
     
    446451            const PabloBlock * used = cast<Statement>(user)->getParent();
    447452            while (used != parent) {
    448                 used = used->getParent();
     453                used = used->getPredecessor ();
    449454                if (used == nullptr) {
    450455                    assert (isa<Assign>(statement) || isa<Next>(statement));
     
    550555}
    551556
    552 
    553 }
     557/** ------------------------------------------------------------------------------------------------------------- *
     558 * @brief throwIfNonMatchingTypes
     559 ** ------------------------------------------------------------------------------------------------------------- */
     560void PabloAST::throwIfNonMatchingTypes(const PabloAST * const a, const PabloAST * const b) {
     561    if (LLVM_UNLIKELY(a->getType() != b->getType())) {
     562        std::string tmp;
     563        raw_string_ostream out(tmp);
     564        out << "Error: ";
     565        PabloPrinter::print(a, out);
     566        out << "'s type does not match ";
     567        PabloPrinter::print(b, out);
     568        throw std::runtime_error(out.str());
     569    }
     570}
     571
     572/** ------------------------------------------------------------------------------------------------------------- *
     573 * @brief throwIfNonMatchingTypes
     574 ** ------------------------------------------------------------------------------------------------------------- */
     575void PabloAST::throwIfNonMatchingType(const PabloAST * const a, const PabloType::TypeId typeId) {
     576    if (LLVM_UNLIKELY(a->getType() == nullptr || a->getType()->getTypeId() != typeId)) {
     577        std::string tmp;
     578        raw_string_ostream out(tmp);
     579        out << "Error: ";
     580        PabloPrinter::print(a, out);
     581        out << "'s type is invalid.";
     582        throw std::runtime_error(out.str());
     583    }
     584}
     585
     586}
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.h

    r5156 r5160  
    1616#include <unordered_map>
    1717#include <vector>
     18#include <pablo/pablo_type.h>
    1819
    1920using namespace llvm;
     
    2223
    2324class PabloBlock;
     25class Statement;
    2426class String;
    25 class Statement;
    2627
    2728class PabloAST {
     
    110111    }
    111112
     113    inline const PabloType * getType() const {
     114        return mType;
     115    }
     116
    112117    void replaceAllUsesWith(PabloAST * const expr);
    113118
     
    125130
    126131protected:
    127     inline PabloAST(const ClassTypeId id)
     132    inline PabloAST(const ClassTypeId id, const PabloType * const type)
    128133    : mClassTypeId(id)
     134    , mType(type)
    129135    , mUsers(mVectorAllocator)
    130136    {
     
    135141    virtual ~PabloAST() {
    136142        mUsers.clear();
    137     }
     143    }   
     144    static void throwIfNonMatchingTypes(const PabloAST * const a, const PabloAST * const b);
     145    static void throwIfNonMatchingType(const PabloAST * const a, const PabloType::TypeId typeId);
    138146    static Allocator        mAllocator;
    139147    static VectorAllocator  mVectorAllocator;
    140148private:
    141149    const ClassTypeId       mClassTypeId;
     150    const PabloType * const mType;
    142151    Users                   mUsers;
    143152};
     
    218227    virtual ~Statement() {}
    219228protected:
    220     explicit Statement(const ClassTypeId id, std::initializer_list<PabloAST *> operands, const String * const name)
    221     : PabloAST(id)
     229    explicit Statement(const ClassTypeId id, const PabloType * const type, std::initializer_list<PabloAST *> operands, const String * const name)
     230    : PabloAST(id, type)
    222231    , mName(name)
    223232    , mNext(nullptr)
     
    234243        }
    235244    }
    236     explicit Statement(const ClassTypeId id, const unsigned reserved, const String * const name)
    237     : PabloAST(id)
     245    explicit Statement(const ClassTypeId id, const PabloType * const type, const unsigned reserved, const String * const name)
     246    : PabloAST(id, type)
    238247    , mName(name)
    239248    , mNext(nullptr)
     
    245254    }
    246255    template<typename iterator>
    247     explicit Statement(const ClassTypeId id, iterator begin, iterator end, const String * const name)
    248     : PabloAST(id)
     256    explicit Statement(const ClassTypeId id, const PabloType * const type, iterator begin, iterator end, const String * const name)
     257    : PabloAST(id, type)
    249258    , mName(name)
    250259    , mNext(nullptr)
     
    334343
    335344protected:
    336     explicit Variadic(const ClassTypeId id, std::initializer_list<PabloAST *> operands, const String * const name)
    337     : Statement(id, operands, name)
     345    explicit Variadic(const ClassTypeId id, const PabloType * const type, std::initializer_list<PabloAST *> operands, const String * const name)
     346    : Statement(id, type, operands, name)
    338347    , mCapacity(operands.size()) {
    339348
    340349    }
    341     explicit Variadic(const ClassTypeId id, const unsigned reserved, String * name)
    342     : Statement(id, reserved, name)
     350    explicit Variadic(const ClassTypeId id, const PabloType * const type, const unsigned reserved, String * name)
     351    : Statement(id, type, reserved, name)
    343352    , mCapacity(reserved) {
    344353
    345354    }
    346355    template<typename iterator>
    347     explicit Variadic(const ClassTypeId id, iterator begin, iterator end, String * name)
    348     : Statement(id, begin, end, name)
     356    explicit Variadic(const ClassTypeId id, const PabloType * const type, iterator begin, iterator end, String * name)
     357    : Statement(id, type, begin, end, name)
    349358    , mCapacity(std::distance(begin, end)) {
    350359
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r5156 r5160  
    7171    }
    7272
    73     mMarkerMap.emplace(PabloBlock::createZeroes(), iBuilder->allZeroes());
    74     mMarkerMap.emplace(PabloBlock::createOnes(), iBuilder->allOnes());
     73    PabloBlock * const entryBlock = mPabloFunction->getEntryBlock();
     74    mMarkerMap.emplace(entryBlock->createZeroes(), iBuilder->allZeroes());
     75    mMarkerMap.emplace(entryBlock->createOnes(), iBuilder->allOnes());
    7576    for (unsigned j = 0; j < mPabloFunction->getNumOfParameters(); ++j) {
    7677        Value * inputVal = iBuilder->CreateGEP(inputSet_ptr, {iBuilder->getInt32(0), iBuilder->getInt32(j)});
     
    7980            iBuilder->CallPrintRegister(var->getName()->to_string(), iBuilder->CreateBlockAlignedLoad(inputVal));
    8081        }
    81         mMarkerMap.insert(std::make_pair(var, inputVal));
    82     }
    83    
    84     compileBlock(mPabloFunction->getEntryBlock());
     82        mMarkerMap.emplace(var, inputVal);
     83    }
     84   
     85    compileBlock(entryBlock);
    8586   
    8687    for (unsigned j = 0; j < mPabloFunction->getNumOfResults(); ++j) {
     
    132133        compileStatement(statement);
    133134    }
    134     mPabloBlock = block->getParent();
     135    mPabloBlock = block->getPredecessor ();
    135136}
    136137
     
    186187        phi->addIncoming(iBuilder->allZeroes(), ifEntryBlock);
    187188        phi->addIncoming(f->second, ifExitBlock);
    188         mMarkerMap[assign] = phi;
     189        f->second = phi;
     190        assert (mMarkerMap[assign] == phi);
    189191    }
    190192    // Create the phi Node for the summary variable, if needed.
     
    229231        assert (f != mMarkerMap.end());
    230232        phi->addIncoming(f->second, whileEntryBlock);
    231         mMarkerMap[n->getInitial()] = phi;
     233        f->second = phi;
     234        assert(mMarkerMap[n->getInitial()] == phi);
    232235        nextPhis.push_back(phi);
    233236    }
     
    252255    for (unsigned i = 0; i < nextNodes.size(); i++) {
    253256        const Next * n = nextNodes[i];
    254         auto f = mMarkerMap.find(n->getExpr());
     257        const auto f = mMarkerMap.find(n->getExpr());
    255258        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
    256259            throw std::runtime_error("Next node expression was not compiled!");
     
    400403        throw std::runtime_error(msg.str());
    401404    }
    402     mMarkerMap[stmt] = expr;
     405    mMarkerMap.emplace(stmt, expr);
    403406    if (DebugOptionIsSet(DumpTrace)) {
    404407        iBuilder->CallPrintRegister(stmt->getName()->to_string(), expr);
     
    415418    auto f = mMarkerMap.find(expr);
    416419    if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
    417         std::string o;
    418         llvm::raw_string_ostream str(o);
    419         str << "\"";
    420         PabloPrinter::print(expr, str);
    421         str << "\" was used before definition!";
    422         throw std::runtime_error(str.str());
     420        std::string tmp;
     421        llvm::raw_string_ostream out(tmp);
     422        out << "\"";
     423        PabloPrinter::print(expr, out);
     424        out << "\" was used before definition!";
     425        throw std::runtime_error(out.str());
    423426    }
    424427    Value * result = f->second;
  • icGREP/icgrep-devel/icgrep/pablo/passes/factorizedfg.cpp

    r5156 r5160  
    125125        for (PabloAST * user : op->users()) {
    126126            if (user->getClassTypeId() == var->getClassTypeId()) {               
    127                 for (PabloBlock * scope = cast<Variadic>(user)->getParent(); scope; scope = scope->getParent()) {
     127                for (PabloBlock * scope = cast<Variadic>(user)->getParent(); scope; scope = scope->getPredecessor ()) {
    128128                    if (LLVM_UNLIKELY(scope == var->getParent())) {
    129129                        tmp.push_back(user);
     
    285285                    assert (nested);
    286286                    value = nested->getBranch();
    287                     nested = nested->getParent();
     287                    nested = nested->getPredecessor ();
    288288                    if (nested == scope) {
    289289                        break;
     
    349349        // the scope tree until both scopes are at the same depth.
    350350        while (depth1 > depth2) {
    351             scope1 = scope1->getParent();
     351            scope1 = scope1->getPredecessor ();
    352352            --depth1;
    353353        }
    354354        while (depth1 < depth2) {
    355             scope2 = scope2->getParent();
     355            scope2 = scope2->getPredecessor ();
    356356            --depth2;
    357357        }
     
    360360        // must be the LCA of our original scopes.
    361361        while (scope1 != scope2) {
    362             scope1 = scope1->getParent();
    363             scope2 = scope2->getParent();
     362            scope1 = scope1->getPredecessor ();
     363            scope2 = scope2->getPredecessor ();
    364364        }
    365365        assert (scope1 && scope2);
     
    608608                    }
    609609                    usage = scope->getBranch();
    610                     assert (scope != scope->getParent());
    611                     scope = scope->getParent();
     610                    assert (scope != scope->getPredecessor ());
     611                    scope = scope->getPredecessor ();
    612612                }
    613613            }
     
    836836                    }
    837837                    op = scope->getBranch();
    838                     scope = scope->getParent();
     838                    scope = scope->getPredecessor ();
    839839                }
    840840            }
  • icGREP/icgrep-devel/icgrep/pablo/passes/flattenassociativedfg.cpp

    r5081 r5160  
    8989                        }
    9090                        br = scope->getBranch();
    91                         scope = scope->getParent();
     91                        scope = scope->getPredecessor ();
    9292                    }
    9393                }
  • icGREP/icgrep-devel/icgrep/pablo/pe_advance.h

    r4980 r5160  
    3939protected:
    4040    Advance(PabloAST * expr, PabloAST * shiftAmount, String * name)
    41     : Statement(ClassTypeId::Advance, {expr, shiftAmount}, name)
     41    : Statement(ClassTypeId::Advance, expr->getType(), {expr, shiftAmount}, name)
    4242    {
    4343        assert(isa<Integer>(shiftAmount));
  • icGREP/icgrep-devel/icgrep/pablo/pe_and.h

    r4886 r5160  
    2323    virtual ~And() { }
    2424protected:
    25     And(PabloAST * expr1, PabloAST * expr2, String * name)
    26     : Variadic(ClassTypeId::And, {expr1, expr2}, name)
     25    And(const PabloType * const type, PabloAST * expr1, PabloAST * expr2, String * name)
     26    : Variadic(ClassTypeId::And, type, {expr1, expr2}, name)
    2727    {
    2828
    2929    }
    30     And(const unsigned reserved, String * name)
    31     : Variadic(ClassTypeId::And, reserved, name)
     30    And(const PabloType * const type, const unsigned reserved, String * name)
     31    : Variadic(ClassTypeId::And, type, reserved, name)
    3232    {
    3333
    3434    }
    3535    template<typename iterator>
    36     And(iterator begin, iterator end, String * name)
    37     : Variadic(ClassTypeId::And, begin, end, name) {
     36    And(const PabloType * const type, iterator begin, iterator end, String * name)
     37    : Variadic(ClassTypeId::And, type, begin, end, name) {
    3838
    3939    }
  • icGREP/icgrep-devel/icgrep/pablo/pe_call.h

    r4681 r5160  
    3232protected:
    3333    Call(PabloAST * prototype)
    34     : Statement(ClassTypeId::Call, {prototype}, cast<Prototype>(prototype)->getName())
     34    : Statement(ClassTypeId::Call, nullptr, {prototype}, cast<Prototype>(prototype)->getName())
    3535    , mLocalCarryIndex(0) {
    3636
  • icGREP/icgrep-devel/icgrep/pablo/pe_count.h

    r5063 r5160  
    2828protected:
    2929    explicit Count(PabloAST * expr, String * counter)
    30     : Statement(ClassTypeId::Count, {expr}, counter)
     30    : Statement(ClassTypeId::Count, getPabloType(PabloType::Scalar, 64), {expr}, counter)
    3131    {
     32
    3233    }
    3334private:
  • icGREP/icgrep-devel/icgrep/pablo/pe_infile.h

    r5042 r5160  
    2727    }
    2828protected:
    29     InFile(PabloAST * expr, String * name) : Statement(ClassTypeId::InFile, {expr}, name) { }
     29    InFile(PabloAST * expr, String * name)
     30    : Statement(ClassTypeId::InFile, expr->getType(), {expr}, name) {
     31
     32    }
    3033};
    3134
     
    4548    }
    4649protected:
    47     AtEOF(PabloAST * expr, String * name) : Statement(ClassTypeId::AtEOF, {expr}, name) { }
     50    AtEOF(PabloAST * expr, String * name)
     51    : Statement(ClassTypeId::AtEOF, expr->getType(), {expr}, name) {
     52
     53    }
    4854};
    4955   
  • icGREP/icgrep-devel/icgrep/pablo/pe_integer.h

    r4699 r5160  
    2424protected:
    2525    Integer(const Type value) noexcept
    26     : PabloAST(ClassTypeId::Integer)
     26    : PabloAST(ClassTypeId::Integer, getPabloType(PabloType::Scalar, 64))
    2727    , mValue(value)
    2828    {
  • icGREP/icgrep-devel/icgrep/pablo/pe_lookahead.h

    r4980 r5160  
    3939protected:
    4040    Lookahead(PabloAST * expr, PabloAST * shiftAmount, String * name)
    41     : Statement(ClassTypeId::Lookahead, {expr, shiftAmount}, name)
     41    : Statement(ClassTypeId::Lookahead, expr->getType(), {expr, shiftAmount}, name)
    4242    {
    4343        assert(isa<Integer>(shiftAmount));
  • icGREP/icgrep-devel/icgrep/pablo/pe_matchstar.h

    r4980 r5160  
    3535    virtual ~MatchStar() {}
    3636protected:
    37     MatchStar(PabloAST * marker, PabloAST * cc, String * name)
    38     : Statement(ClassTypeId::MatchStar, {marker, cc}, name)
    39     {
     37    MatchStar(PabloAST * marker,  PabloAST * cc, String * name)
     38    : Statement(ClassTypeId::MatchStar, marker->getType(), {marker, cc}, name) {
    4039
    4140    }
  • icGREP/icgrep-devel/icgrep/pablo/pe_next.h

    r5156 r5160  
    2727protected:
    2828    explicit Next(PabloAST * initial, PabloAST * expr)
    29     : Statement(ClassTypeId::Next, {expr, cast<Assign>(initial)}, cast<Assign>(initial)->getName()) {
    30 
     29    : Statement(ClassTypeId::Next, initial->getType(), {expr, cast<Assign>(initial)}, cast<Assign>(initial)->getName()) {
     30        throwIfNonMatchingTypes(initial, expr);
    3131    }
    3232};
  • icGREP/icgrep-devel/icgrep/pablo/pe_not.h

    r4650 r5160  
    2828protected:
    2929    Not(PabloAST * expr, String * name)
    30     : Statement(ClassTypeId::Not, {expr}, name)
     30    : Statement(ClassTypeId::Not, expr->getType(), {expr}, name)
    3131    {
    3232
  • icGREP/icgrep-devel/icgrep/pablo/pe_ones.h

    r4683 r5160  
    99
    1010#include <pablo/pabloAST.h>
    11 #include <pablo/pe_var.h>
    1211
    1312namespace pablo {
     
    1514class Ones : public PabloAST {
    1615    friend class PabloBlock;
     16    friend class PabloFunction;
    1717public:
    1818    static inline bool classof(const PabloAST * e) {
     
    3131    }
    3232protected:
    33     Ones() : PabloAST(ClassTypeId::Ones) { }
     33    Ones(const PabloType * const type) : PabloAST(ClassTypeId::Ones, type) { }
    3434};
    3535
  • icGREP/icgrep-devel/icgrep/pablo/pe_or.h

    r4886 r5160  
    2323    virtual ~Or() { }
    2424protected:
    25     Or(PabloAST * expr1, PabloAST * expr2, String * name)
    26     : Variadic(ClassTypeId::Or, {expr1, expr2}, name)
     25    Or(const PabloType * const type, PabloAST * expr1, PabloAST * expr2, String * name)
     26    : Variadic(ClassTypeId::Or, type, {expr1, expr2}, name)
    2727    {
    2828
    2929    }
    30     Or(const unsigned reserved, String * name)
    31     : Variadic(ClassTypeId::Or, reserved, name)
     30    Or(const PabloType * const type, const unsigned reserved, String * name)
     31    : Variadic(ClassTypeId::Or, type, reserved, name)
    3232    {
    3333
    3434    }
    3535    template<typename iterator>
    36     Or(iterator begin, iterator end, String * name)
    37     : Variadic(ClassTypeId::Or, begin, end, name) {
     36    Or(const PabloType * const type, iterator begin, iterator end, String * name)
     37    : Variadic(ClassTypeId::Or, type, begin, end, name) {
    3838
    3939    }
  • icGREP/icgrep-devel/icgrep/pablo/pe_scanthru.h

    r4980 r5160  
    3737protected:
    3838    ScanThru(PabloAST * from, PabloAST * thru, String * name)
    39     : Statement(ClassTypeId::ScanThru, {from, thru}, name)
    40     {
     39    : Statement(ClassTypeId::ScanThru, from->getType(), {from, thru}, name) {
    4140
    4241    }
  • icGREP/icgrep-devel/icgrep/pablo/pe_sel.h

    r4650 r5160  
    3333    }
    3434protected:
    35     Sel(PabloAST* if_expr, PabloAST* t_expr, PabloAST* f_expr, String * name)
    36     : Statement(ClassTypeId::Sel, {if_expr, t_expr, f_expr}, name)
    37     {
     35    Sel(PabloAST * condExpr, PabloAST * trueExpr, PabloAST * falseExpr, String * name)
     36    : Statement(ClassTypeId::Sel, trueExpr->getType(), {condExpr, trueExpr, falseExpr}, name) {
    3837
    3938    }
  • icGREP/icgrep-devel/icgrep/pablo/pe_string.h

    r4692 r5160  
    4646protected:
    4747    String(const std::string & value, const bool generated) noexcept
    48     : PabloAST(ClassTypeId::String)
     48    : PabloAST(ClassTypeId::String, getPabloType(PabloType::String, 0))
    4949    , mValue(duplicate(value))
    5050    , mGenerated(generated)
  • icGREP/icgrep-devel/icgrep/pablo/pe_var.h

    r4657 r5160  
    4343    }
    4444protected:
    45     Var(PabloAST * var)
    46     : PabloAST(ClassTypeId::Var)
     45    Var(PabloAST * var, const PabloType * const type)
     46    : PabloAST(ClassTypeId::Var, type)
    4747    , mName(cast<String>(var)) {
    4848
  • icGREP/icgrep-devel/icgrep/pablo/pe_xor.h

    r4886 r5160  
    2323    virtual ~Xor() { }
    2424protected:
    25     Xor(PabloAST * expr1, PabloAST * expr2, String * name)
    26     : Variadic(ClassTypeId::Xor, {expr1, expr2}, name)
     25    Xor(const PabloType * const type, PabloAST * expr1, PabloAST * expr2, String * name)
     26    : Variadic(ClassTypeId::Xor, type, {expr1, expr2}, name)
    2727    {
    2828
    2929    }
    30     Xor(const unsigned reserved, String * name)
    31     : Variadic(ClassTypeId::Xor, reserved, name)
     30    Xor(const PabloType * const type, const unsigned reserved, String * name)
     31    : Variadic(ClassTypeId::Xor, type, reserved, name)
    3232    {
    3333
    3434    }
    3535    template<typename iterator>
    36     Xor(iterator begin, iterator end, String * name)
    37     : Variadic(ClassTypeId::Xor, begin, end, name) {
     36    Xor(const PabloType * const type, iterator begin, iterator end, String * name)
     37    : Variadic(ClassTypeId::Xor, type, begin, end, name) {
    3838
    3939    }
  • icGREP/icgrep-devel/icgrep/pablo/pe_zeroes.h

    r4683 r5160  
    1515class Zeroes : public PabloAST {
    1616    friend class PabloBlock;
     17    friend class PabloFunction;
    1718public:
    1819    static inline bool classof(const PabloAST * expr) {
     
    3233    }
    3334protected:
    34     Zeroes() : PabloAST(ClassTypeId::Zeroes) { }
     35    Zeroes(const PabloType * const type) : PabloAST(ClassTypeId::Zeroes, type) { }
    3536};
    3637
  • icGREP/icgrep-devel/icgrep/pablo/ps_assign.h

    r4658 r5160  
    3333protected:
    3434    explicit Assign(PabloAST * expr, String * name)
    35     : Statement(ClassTypeId::Assign, {expr}, name)
     35    : Statement(ClassTypeId::Assign, expr->getType(), {expr}, name)
    3636    {
    3737
  • icGREP/icgrep-devel/icgrep/pablo/ps_if.cpp

    r5156 r5160  
    88
    99If::If(PabloAST * expr, const std::initializer_list<Assign *> definedVars, PabloBlock * body)
    10 : Statement(ClassTypeId::If, {expr}, nullptr)
     10: Statement(ClassTypeId::If, nullptr, {expr}, nullptr)
    1111, mBody(body)
    1212, mDefined(definedVars.begin(), definedVars.end(), mDefinedAllocator) {
     
    2222    // of it.
    2323    mBody->setBranch(this);
    24     mBody->setParent(getParent());
     24    mBody->setPredecessor (getParent());
    2525    for (Assign * def : mDefined) {
    2626        def->addUser(this);
     
    3030
    3131If::If(PabloAST * expr, const std::vector<Assign *> & definedVars, PabloBlock * body)
    32 : Statement(ClassTypeId::If, {expr}, nullptr)
     32: Statement(ClassTypeId::If, nullptr, {expr}, nullptr)
    3333, mBody(body)
    3434, mDefined(definedVars.begin(), definedVars.end(), mDefinedAllocator) {
    3535    mBody->setBranch(this);
    36     mBody->setParent(getParent());
     36    mBody->setPredecessor (getParent());
    3737    for (Assign * def : mDefined) {
    3838        def->addUser(this);
     
    6161PabloBlock * If::setBody(PabloBlock * body) {
    6262    body->setBranch(this);
    63     body->setParent(mBody->getParent());
     63    body->setPredecessor (mBody->getPredecessor ());
    6464    std::swap(mBody, body);
    65     body->setParent(nullptr);
     65    body->setPredecessor (nullptr);
    6666    return body;
    6767}
  • icGREP/icgrep-devel/icgrep/pablo/ps_while.cpp

    r5156 r5160  
    77
    88While::While(PabloAST * expr, const std::initializer_list<Next *> nextVars, PabloBlock * body)
    9 : Statement(ClassTypeId::While, {expr}, nullptr)
     9: Statement(ClassTypeId::While, nullptr, {expr}, nullptr)
    1010, mBody(body)
    1111, mVariant(nextVars.begin(), nextVars.end(), mVariantAllocator) {
    1212    mBody->setBranch(this);
    13     mBody->setParent(getParent());
     13    mBody->setPredecessor (getParent());
    1414    for (Next * variant : nextVars) {
    1515        variant->addUser(this);
     
    1919
    2020While::While(PabloAST * expr, const std::vector<Next *> & nextVars, PabloBlock * body)
    21 : Statement(ClassTypeId::While, {expr}, nullptr)
     21: Statement(ClassTypeId::While, nullptr, {expr}, nullptr)
    2222, mBody(body)
    2323, mVariant(nextVars.begin(), nextVars.end(), mVariantAllocator) {
    2424    mBody->setBranch(this);
    25     mBody->setParent(getParent());
     25    mBody->setPredecessor (getParent());
    2626    for (Next * variant : nextVars) {
    2727        variant->addUser(this);
     
    3232PabloBlock * While::setBody(PabloBlock * body) {
    3333    body->setBranch(this);
    34     body->setParent(mBody->getParent());
     34    body->setPredecessor (mBody->getPredecessor ());
    3535    std::swap(mBody, body);
    36     body->setParent(nullptr);
     36    body->setPredecessor (nullptr);
    3737    return body;
    3838}
Note: See TracChangeset for help on using the changeset viewer.