Changeset 4665 for icGREP/icgrep-devel


Ignore:
Timestamp:
Jul 13, 2015, 3:55:59 PM (4 years ago)
Author:
nmedfort
Message:

Made pablo compiler reenterant through alternate compile method that takes a Module parameter.

Location:
icGREP/icgrep-devel/icgrep
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.cpp

    r4662 r4665  
    1010#include <llvm/IR/Intrinsics.h>
    1111#include <llvm/IR/Function.h>
    12 #include <iostream>
    1312
    14 using namespace IDISA;
     13namespace IDISA {
    1514
    1615Value * IDISA_Builder::bitBlockCast(Value * a) {
    17     return llvm_builder->CreateBitCast(a, mBitBlockType);
     16    return mLLVMBuilder->CreateBitCast(a, mBitBlockType);
    1817}
    1918
    2019VectorType * IDISA_Builder::fwVectorType(unsigned fw) {
    2120    int fieldCount = mBitBlockSize/fw;
    22     return VectorType::get(llvm_builder->getIntNTy(fw), fieldCount);
     21    return VectorType::get(mLLVMBuilder->getIntNTy(fw), fieldCount);
    2322}
    2423
    2524Value * IDISA_Builder::fwCast(unsigned fw, Value * a) {
    26     return llvm_builder->CreateBitCast(a, fwVectorType(fw));
     25    return mLLVMBuilder->CreateBitCast(a, fwVectorType(fw));
    2726}
    2827
    2928Value * IDISA_Builder::simd_add(unsigned fw, Value * a, Value * b) {
    30     return bitBlockCast(llvm_builder->CreateAdd(fwCast(fw, a), fwCast(fw, b)));
     29    return bitBlockCast(mLLVMBuilder->CreateAdd(fwCast(fw, a), fwCast(fw, b)));
    3130}
    3231
    3332Value * IDISA_Builder::simd_sub(unsigned fw, Value * a, Value * b) {
    34     return bitBlockCast(llvm_builder->CreateSub(fwCast(fw, a), fwCast(fw, b)));
     33    return bitBlockCast(mLLVMBuilder->CreateSub(fwCast(fw, a), fwCast(fw, b)));
    3534}
    3635
    3736Value * IDISA_Builder::simd_mult(unsigned fw, Value * a, Value * b) {
    38     return bitBlockCast(llvm_builder->CreateMul(fwCast(fw, a), fwCast(fw, b)));
     37    return bitBlockCast(mLLVMBuilder->CreateMul(fwCast(fw, a), fwCast(fw, b)));
    3938}
    4039
    4140Value * IDISA_Builder::simd_eq(unsigned fw, Value * a, Value * b) {
    42     return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpEQ(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
     41    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpEQ(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
    4342}
    4443
    4544Value * IDISA_Builder::simd_gt(unsigned fw, Value * a, Value * b) {
    46     return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpSGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
     45    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
    4746}
    4847
    4948Value * IDISA_Builder::simd_ugt(unsigned fw, Value * a, Value * b) {
    50     return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpUGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
     49    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpUGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
    5150}
    5251
    5352Value * IDISA_Builder::simd_lt(unsigned fw, Value * a, Value * b) {
    54     return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpSLT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
     53    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
    5554}
    5655
    5756Value * IDISA_Builder::simd_ult(unsigned fw, Value * a, Value * b) {
    58     return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpULT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
     57    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpULT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
    5958}
    6059
     
    6261    Value * aVec = fwCast(fw, a);
    6362    Value * bVec = fwCast(fw, b);
    64     return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpSGT(aVec, bVec), aVec, bVec));
     63    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSGT(aVec, bVec), aVec, bVec));
    6564}
    6665
     
    6867    Value * aVec = fwCast(fw, a);
    6968    Value * bVec = fwCast(fw, b);
    70     return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpUGT(aVec, bVec), aVec, bVec));
     69    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpUGT(aVec, bVec), aVec, bVec));
    7170}
    7271
     
    7473    Value * aVec = fwCast(fw, a);
    7574    Value * bVec = fwCast(fw, b);
    76     return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpSLT(aVec, bVec), aVec, bVec));
     75    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSLT(aVec, bVec), aVec, bVec));
    7776}
    7877
     
    8079    Value * aVec = fwCast(fw, a);
    8180    Value * bVec = fwCast(fw, b);
    82     return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpULT(aVec, bVec), aVec, bVec));
     81    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpULT(aVec, bVec), aVec, bVec));
    8382}
    8483
    8584Value * IDISA_Builder::simd_slli(unsigned fw, Value * a, unsigned shift) {
    86     return bitBlockCast(llvm_builder->CreateShl(fwCast(fw, a), shift));
     85    return bitBlockCast(mLLVMBuilder->CreateShl(fwCast(fw, a), shift));
    8786}
    8887
    8988Value * IDISA_Builder::simd_srli(unsigned fw, Value * a, unsigned shift) {
    90     return bitBlockCast(llvm_builder->CreateLShr(fwCast(fw, a), shift));
     89    return bitBlockCast(mLLVMBuilder->CreateLShr(fwCast(fw, a), shift));
    9190}
    9291
    9392Value * IDISA_Builder::simd_srai(unsigned fw, Value * a, unsigned shift) {
    94     return bitBlockCast(llvm_builder->CreateAShr(fwCast(fw, a), shift));
     93    return bitBlockCast(mLLVMBuilder->CreateAShr(fwCast(fw, a), shift));
    9594}
    9695
    9796Value * IDISA_Builder::simd_cttz(unsigned fw, Value * a) {
    9897    Value * cttzFunc = Intrinsic::getDeclaration(mMod, Intrinsic::cttz, fwVectorType(fw));
    99     Value * rslt = llvm_builder->CreateCall(cttzFunc, {fwCast(fw, a), ConstantInt::get(llvm_builder->getInt1Ty(), 0)});
     98    Value * rslt = mLLVMBuilder->CreateCall(cttzFunc, {fwCast(fw, a), ConstantInt::get(mLLVMBuilder->getInt1Ty(), 0)});
    10099    return bitBlockCast(rslt);
    101100}
     
    107106    std::vector<Constant*> Idxs;
    108107    for (unsigned i = field_count/2; i < field_count; i++) {
    109         Idxs.push_back(llvm_builder->getInt32(i));    // selects elements from first reg.
    110         Idxs.push_back(llvm_builder->getInt32(i + field_count)); // selects elements from second reg.
     108        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
     109        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
    111110    }
    112     return bitBlockCast(llvm_builder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
     111    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
    113112}
    114113
     
    119118    std::vector<Constant*> Idxs;
    120119    for (unsigned i = 0; i < field_count/2; i++) {
    121         Idxs.push_back(llvm_builder->getInt32(i));    // selects elements from first reg.
    122         Idxs.push_back(llvm_builder->getInt32(i + field_count)); // selects elements from second reg.
     120        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
     121        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
    123122    }
    124     return bitBlockCast(llvm_builder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
     123    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
    125124}
    126125
     
    131130    std::vector<Constant*> Idxs;
    132131    for (unsigned i = 0; i < field_count; i++) {
    133         Idxs.push_back(llvm_builder->getInt32(2*i));
     132        Idxs.push_back(mLLVMBuilder->getInt32(2*i));
    134133    }
    135     return bitBlockCast(llvm_builder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
     134    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
    136135}
    137136
     
    142141    std::vector<Constant*> Idxs;
    143142    for (unsigned i = 0; i < field_count; i++) {
    144         Idxs.push_back(llvm_builder->getInt32(2*i+1));
     143        Idxs.push_back(mLLVMBuilder->getInt32(2*i+1));
    145144    }
    146     return bitBlockCast(llvm_builder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
     145    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
    147146}
    148147
    149148Value * IDISA_Builder::hsimd_signmask(unsigned fw, Value * a) {
    150     Value * mask = llvm_builder->CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
    151     return llvm_builder->CreateBitCast(mask, llvm_builder->getIntNTy(mBitBlockSize/fw));
     149    Value * mask = mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
     150    return mLLVMBuilder->CreateBitCast(mask, mLLVMBuilder->getIntNTy(mBitBlockSize/fw));
    152151}
    153152
     
    158157    std::vector<Constant*> Idxs;
    159158    for (unsigned i = shift; i < field_count + shift; i++) {
    160         Idxs.push_back(llvm_builder->getInt32(i));
     159        Idxs.push_back(mLLVMBuilder->getInt32(i));
    161160    }
    162     return bitBlockCast(llvm_builder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
     161    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
    163162}
    164163
    165164Value * IDISA_Builder::bitblock_any(Value * a) {
    166     Type * iBitBlock = llvm_builder->getIntNTy(mBitBlockSize);
    167     return llvm_builder->CreateICmpNE(llvm_builder->CreateBitCast(a, iBitBlock),  ConstantInt::get(iBitBlock, 0));
     165    Type * iBitBlock = mLLVMBuilder->getIntNTy(mBitBlockSize);
     166    return mLLVMBuilder->CreateICmpNE(mLLVMBuilder->CreateBitCast(a, iBitBlock),  ConstantInt::get(iBitBlock, 0));
    168167}
     168
     169}
  • icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.h

    r4662 r4665  
    1818class IDISA_Builder {
    1919public:
    20     IDISA_Builder(Module * m, IRBuilder <> * b, Type * bitBlockType): mMod(m), llvm_builder(b), mBitBlockType(bitBlockType) {
    21         if (bitBlockType->isIntegerTy()) mBitBlockSize = dyn_cast<IntegerType>(bitBlockType)-> getIntegerBitWidth();
    22         else mBitBlockSize = dyn_cast<VectorType>(bitBlockType)-> getBitWidth();
     20
     21    IDISA_Builder(Type * bitBlockType)
     22    : mMod(nullptr)
     23    , mLLVMBuilder(nullptr)
     24    , mBitBlockType(bitBlockType)
     25    , mBitBlockSize(bitBlockType->isIntegerTy() ? cast<IntegerType>(bitBlockType)->getIntegerBitWidth() : cast<VectorType>(bitBlockType)->getBitWidth()) {
     26
     27    }
     28
     29    void initialize(Module * m, IRBuilder <> * b) {
     30        mMod = m;
     31        mLLVMBuilder = b;
    2332    }
    2433       
     
    5665private:
    5766    Module * mMod;
    58     IRBuilder <> * llvm_builder;
     67    IRBuilder <> * mLLVMBuilder;
    5968    Type * mBitBlockType;
    6069    unsigned mBitBlockSize;
  • icGREP/icgrep-devel/icgrep/cc/cc_namemap.cpp

    r4660 r4665  
    1515
    1616RE * CC_NameMap::process(RE * re, const CC_type type) {
    17 
    1817    if (Alt * alt = dyn_cast<Alt>(re)) {
    1918        for (auto i = alt->begin(); i != alt->end(); ++i) {
     
    4140    }
    4241    else if (Name * name = dyn_cast<Name>(re)) {
     42        RE * def = name->getDefinition();
     43        if (def && !isa<CC>(def)) {
     44            name->setDefinition(process(def, type));
     45        }
    4346        std::string classname = name->getName();
    4447        auto f = mNameMap.find(classname);
     
    4649            if (name->getType() == Name::Type::UnicodeProperty) {
    4750                resolveProperty(name);
    48             }
    49             RE * def = name->getDefinition();
    50             if (def) {
    51                 name->setDefinition(process(def, type));
     51                RE * def = name->getDefinition();
     52                if (def) {
     53                    name->setDefinition(process(def, type));
     54                }
    5255            }
    5356            return insert(std::move(classname), name);
  • icGREP/icgrep-devel/icgrep/cc/cc_namemap.hpp

    r4660 r4665  
    2121
    2222    re::RE * process(re::RE * re, const re::CC_type t);
    23 
    24     inline void clear() {
    25         mNameMap.clear();
    26         mNameVector.clear();
    27     }
    2823
    2924    inline iterator begin() const {
  • icGREP/icgrep-devel/icgrep/generate_predefined_ucd_functions.cpp

    r4661 r4665  
    44 *  icgrep is a trademark of International Characters.
    55 */
    6 
    7 #include <string>
    8 #include <iostream>
    9 #include <fstream>
    106
    117#include <cc/cc_compiler.h>
     
    2016#include <pablo/optimizers/pablo_simplifier.hpp>
    2117#include <pablo/optimizers/pablo_codesinking.hpp>
     18#ifdef ENABLE_MULTIPLEXING
    2219#include <pablo/optimizers/pablo_automultiplexing.hpp>
    23 #include <llvm/ExecutionEngine/ExecutionEngine.h>
     20#endif
     21#include <llvm/IR/Verifier.h>
     22#include <llvm/Support/Debug.h>
     23#include <llvm/Support/TargetRegistry.h>
     24#include <llvm/Support/TargetSelect.h>
     25#include <llvm/Target/TargetLibraryInfo.h>
     26#include <llvm/Target/TargetMachine.h>
     27#include <llvm/Support/Host.h>
     28#include <llvm/ADT/Triple.h>
     29#include <llvm/Support/ToolOutputFile.h>
     30#include <llvm/Pass.h>
     31#include <llvm/PassManager.h>
     32#include <llvm/ADT/STLExtras.h>
     33#include <llvm/Target/TargetSubtargetInfo.h>
     34#include <llvm/Support/FormattedStream.h>
     35
     36#include "llvm/Support/FileSystem.h"
     37
    2438#include <boost/algorithm/string/case_conv.hpp>
    25 
    2639#include <iostream>
    2740
     
    2942using namespace UCD;
    3043using namespace cc;
     44using namespace llvm;
    3145
    3246inline std::string lowercase(const std::string & name) {
     
    3549}
    3650
    37 ExecutionEngine * compile(std::string name, const UnicodeSet & set, PabloCompiler & pc, ExecutionEngine * engine) {
     51static cl::opt<std::string>
     52OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
    3853
     54/** ------------------------------------------------------------------------------------------------------------- *
     55 * @brief compileUnicodeSet
     56 ** ------------------------------------------------------------------------------------------------------------- */
     57void compileUnicodeSet(std::string name, const UnicodeSet & set, PabloCompiler & pc, Module * module) {
    3958    PabloFunction function = PabloFunction::Create(std::move(name));
    4059    Encoding encoding(Encoding::Type::UTF_8, 8);
     
    4261    UCDCompiler ucdCompiler(ccCompiler);
    4362    PabloBuilder builder(function.getEntryBlock());
    44 
    45     std::cerr << "Compiling " << name << std::endl;
    46 
    4763    // Build the unicode set function
    4864    ucdCompiler.generateWithDefaultIfHierarchy(set, builder);
     
    5066    Simplifier::optimize(function);
    5167    CodeSinking::optimize(function);
    52     // AutoMultiplexing::optimize(function);
    53 
    54 
    55     if (engine) {
    56         engine->removeModule(pc.getModule());
    57     }
    58 
     68    #ifdef ENABLE_MULTIPLEXING
     69    AutoMultiplexing::optimize(function);
     70    #endif
    5971    // Now compile the function ...
    60     return pc.compile(function).getExecutionEngine();
     72    pc.compile(function, module);
     73    releaseSlabAllocatorMemory();
    6174}
    6275
    63 int main(int argc, char *argv[]) {
    64 
     76/** ------------------------------------------------------------------------------------------------------------- *
     77 * @brief generateUCDModule
     78 ** ------------------------------------------------------------------------------------------------------------- */
     79Module * generateUCDModule() {
    6580    PabloCompiler pc;
    66     ExecutionEngine * engine = nullptr;
    67 
     81    Module * module = new Module("ucd", getGlobalContext());
    6882    for (PropertyObject * obj : property_object_table) {
    6983
     
    7387            for (const std::string value : *enumObj) {
    7488                const UnicodeSet & set = enumObj->GetCodepointSet(canonicalize_value_name(value));
    75                 engine = compile("__get_" + property_enum_name[enumObj->getPropertyCode()] + "_" + value, set, pc, engine);
     89                std::string name = "__get_" + property_enum_name[enumObj->getPropertyCode()] + "_" + lowercase(value);
     90                compileUnicodeSet(name, set, pc, module);
    7691            }
    7792            break;
    7893        }
    79 
    80 //        if (auto * extObj = dyn_cast<ExtensionPropertyObject>(obj)) {
    81 //            for (const std::string value : *extObj) {
    82 //                const UnicodeSet & set = extObj->GetCodepointSet(canonicalize_value_name(value));
    83 //                engine = compile("__get_" + property_enum_name[extObj->getPropertyCode()] + "_" + value, set, pc, engine);
    84 //            }
    85 //        }
    86 
    87 //        if (auto * binObj = dyn_cast<BinaryPropertyObject>(obj)) {
    88 //            const UnicodeSet & set = binObj->GetCodepointSet(Binary_ns::Y);
    89 //            compile("__get_" + property_enum_name[binObj->getPropertyCode()] + "_Y", set, pc);
    90 //        }
     94        else if (auto * extObj = dyn_cast<ExtensionPropertyObject>(obj)) {
     95            for (const std::string value : *extObj) {
     96                const UnicodeSet & set = extObj->GetCodepointSet(canonicalize_value_name(value));
     97                std::string name = "__get_" + property_enum_name[extObj->getPropertyCode()] + "_" + lowercase(value);
     98                compileUnicodeSet(name, set, pc, module);
     99            }
     100        }
     101        else if (auto * binObj = dyn_cast<BinaryPropertyObject>(obj)) {
     102            const UnicodeSet & set = binObj->GetCodepointSet(Binary_ns::Y);
     103            std::string name = "__get_" + property_enum_name[binObj->getPropertyCode()] + "_y";
     104            compileUnicodeSet(name, set, pc, module);
     105        }
    91106    }
    92107
    93     pc.getModule()->dump();
     108    // Print an error message if our module is malformed in any way.
     109    verifyModule(*module, &dbgs());
    94110
     111    return module;
     112}
     113
     114/** ------------------------------------------------------------------------------------------------------------- *
     115 * @brief compileUCDModule
     116 ** ------------------------------------------------------------------------------------------------------------- */
     117void compileUCDModule(Module * module) {
     118    Triple TheTriple;
     119
     120    if (TheTriple.getTriple().empty()) {
     121        TheTriple.setTriple(sys::getDefaultTargetTriple());
     122    }
     123
     124    // Get the target specific parser.
     125    std::string msg;
     126    const Target * TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), msg);
     127
     128    if (TheTarget == nullptr) {
     129        throw std::runtime_error(msg);
     130    }
     131
     132    auto MCPU = llvm::sys::getHostCPUName();
     133
     134    TargetOptions Options;
     135
     136    std::unique_ptr<TargetMachine> Target(
     137                TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, "", Options,
     138                                               Reloc::Default, CodeModel::Small, CodeGenOpt::Aggressive));
     139
     140    if (Target == nullptr) {
     141        throw std::runtime_error("Could not allocate target machine!");
     142    }
     143
     144    #ifdef USE_LLVM_3_5
     145    std::string error;
     146    std::unique_ptr<tool_output_file> Out = make_unique<tool_output_file>(OutputFilename.c_str(), error, sys::fs::F_None);
     147    if (!error.empty()) {
     148        throw std::runtime_error(error);
     149    }
     150    #else
     151    std::error_code error;
     152    std::unique_ptr<tool_output_file> Out = make_unique<tool_output_file>(OutputFilename, error, sys::fs::F_None);
     153    if (error) {
     154        throw std::runtime_error(error.message());
     155    }
     156    #endif
     157
     158    // Build up all of the passes that we want to do to the module.
     159    PassManager PM;
     160
     161    // Add an appropriate TargetLibraryInfo pass for the module's triple.
     162    TargetLibraryInfo * TLI = new TargetLibraryInfo(TheTriple);
     163
     164    PM.add(TLI);
     165
     166    // Add the target data from the target machine, if it exists, or the module.
     167    #ifdef USE_LLVM_3_5
     168    const DataLayout * DL = Target->getDataLayout();
     169    #else
     170    const DataLayout * DL = Target->getSubtargetImpl()->getDataLayout();
     171    #endif
     172    if (DL) {
     173        module->setDataLayout(DL);
     174    }
     175    PM.add(new DataLayoutPass());
     176
     177    formatted_raw_ostream FOS(Out->os());
     178    // Ask the target to add backend passes as necessary.
     179    if (Target->addPassesToEmitFile(PM, FOS, TargetMachine::CGFT_ObjectFile)) {
     180        throw std::runtime_error("Target does not support generation of this file type!\n");
     181    }
     182
     183    PM.run(*module);
     184
     185    Out->keep();
     186}
     187
     188/** ------------------------------------------------------------------------------------------------------------- *
     189 * @brief main
     190 ** ------------------------------------------------------------------------------------------------------------- */
     191int main(int argc, char *argv[]) {
     192    cl::ParseCommandLineOptions(argc, argv, "UCD Compiler\n");
     193    Module * module = generateUCDModule();
     194    compileUCDModule(module);
    95195    return 0;
    96196}
  • icGREP/icgrep-devel/icgrep/icgrep-devel.files

    r4660 r4665  
    334334UCD/resolve_properties.cpp
    335335UCD/resolve_properties.h
     336generate_predefined_ucd_functions.cpp
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_automultiplexing.cpp

    r4659 r4665  
    109109    AutoMultiplexing am;
    110110    RECORD_TIMESTAMP(start_initialize);
    111     am.initialize(function);
     111    const bool fewerThanThreeAdvances = am.initialize(function);
    112112    RECORD_TIMESTAMP(end_initialize);
    113113
     
    115115
    116116    LOG_NUMBER_OF_ADVANCES(function.getEntryBlock());
     117
     118    if (fewerThanThreeAdvances) {
     119        return false;
     120    }
    117121
    118122    RECORD_TIMESTAMP(start_characterize);
     
    162166/** ------------------------------------------------------------------------------------------------------------- *
    163167 * @brief initialize
    164  * @param vars the input vars for this program
    165  * @param entry the entry block
     168 * @param function the function to optimize
     169 * @returns true if there are fewer than three advances in this function
    166170 *
    167171 * Scan through the program to identify any advances and calls then initialize the BDD engine with
    168172 * the proper variable ordering.
    169173 ** ------------------------------------------------------------------------------------------------------------- */
    170 void AutoMultiplexing::initialize(PabloFunction & function) {
     174bool AutoMultiplexing::initialize(PabloFunction & function) {
    171175
    172176    flat_map<const PabloAST *, unsigned> map;   
     
    212216    }
    213217
     218    // If there are fewer than three Advances in this program, just abort. We cannot reduce it.
     219    if (mAdvanceMap.size() < 3) {
     220        return true;
     221    }
     222
    214223    // Create the transitive closure matrix of graph. From this we'll construct
    215224    // two graphs restricted to the relationships between advances. The first will
     
    298307        mCharacterizationMap[var] = Cudd_bddIthVar(mManager, i++);
    299308    }
     309
     310    return false;
    300311}
    301312
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_automultiplexing.hpp

    r4657 r4665  
    4040    static bool optimize(PabloFunction & function);
    4141protected:
    42     void initialize(PabloFunction & function);
     42    bool initialize(PabloFunction & function);
    4343    void characterize(PabloBlock &block);
    4444    DdNode * characterize(Statement * const stmt);
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4663 r4665  
    6767
    6868PabloCompiler::PabloCompiler()
    69 #ifdef USE_LLVM_3_5
    70 : mMod(new Module("icgrep", getGlobalContext()))
    71 #else
    72 : mModOwner(make_unique<Module>("icgrep", getGlobalContext()))
    73 , mMod(mModOwner.get())
    74 #endif
    75 , mBuilder(&LLVM_Builder)
     69: mMod(nullptr)
     70, mBuilder(nullptr)
    7671, mCarryManager(nullptr)
    77 , mBitBlockType(VectorType::get(IntegerType::get(mMod->getContext(), 64), BLOCK_SIZE / 64))
    78 , iBuilder(mMod, mBuilder, mBitBlockType)
    79 , mInputPtr(nullptr)
     72, mBitBlockType(VectorType::get(IntegerType::get(getGlobalContext(), 64), BLOCK_SIZE / 64))
     73, iBuilder(mBitBlockType)
     74, mInputType(nullptr)
    8075, mCarryDataPtr(nullptr)
    8176, mWhileDepth(0)
     
    9186}
    9287
    93 PabloCompiler::~PabloCompiler()
    94 {
    95 
     88PabloCompiler::~PabloCompiler() {
    9689}
    9790   
     
    10295void PabloCompiler::genPrintRegister(std::string regName, Value * bitblockValue) {
    10396    Constant * regNameData = ConstantDataArray::getString(mMod->getContext(), regName);
    104     GlobalVariable *regStrVar = new GlobalVariable(*mMod, 
     97    GlobalVariable *regStrVar = new GlobalVariable(*mMod,
    10598                                                   ArrayType::get(IntegerType::get(mMod->getContext(), 8), regName.length()+1),
    10699                                                   /*isConstant=*/ true,
     
    112105
    113106CompiledPabloFunction PabloCompiler::compile(PabloFunction & function) {
    114     mWhileDepth = 0;
    115     mIfDepth = 0;
    116     mMaxWhileDepth = 0;
    117     mCarryManager = new CarryManager(mBuilder, mBitBlockType, mZeroInitializer, mOneInitializer, &iBuilder);
    118 
    119     Examine(function.getEntryBlock());
    120    
     107
     108    Examine(function);
     109
    121110    InitializeNativeTarget();
    122111    InitializeNativeTargetAsmPrinter();
    123112    InitializeNativeTargetAsmParser();
    124113
     114    Module * module = new Module("", getGlobalContext());
     115
     116    mMod = module;
     117
    125118    std::string errMessage;
    126 #ifdef USE_LLVM_3_5
     119    #ifdef USE_LLVM_3_5
    127120    EngineBuilder builder(mMod);
    128 #else
    129     EngineBuilder builder(std::move(mModOwner));
    130 #endif
     121    #else
     122    EngineBuilder builder(std::move(std::unique_ptr<Module>(mMod)));
     123    #endif
    131124    builder.setErrorStr(&errMessage);
    132125    builder.setMCPU(sys::getHostCPUName());
    133 #ifdef USE_LLVM_3_5
     126    #ifdef USE_LLVM_3_5
    134127    builder.setUseMCJIT(true);
    135 #endif
     128    #endif
    136129    builder.setOptLevel(mMaxWhileDepth ? CodeGenOpt::Level::Less : CodeGenOpt::Level::None);
    137     ExecutionEngine * ee = builder.create();
    138     if (ee == nullptr) {
     130    ExecutionEngine * engine = builder.create();
     131    if (engine == nullptr) {
    139132        throw std::runtime_error("Could not create ExecutionEngine: " + errMessage);
    140133    }
     134    DeclareFunctions(engine);
     135    DeclareCallFunctions(function, engine);
     136
     137    auto func = compile(function, mMod);
     138
     139    //Display the IR that has been generated by this module.
     140    if (LLVM_UNLIKELY(DumpGeneratedIR)) {
     141        module->dump();
     142    }
     143    //Create a verifier.  The verifier will print an error message if our module is malformed in any way.
     144    verifyModule(*module, &dbgs());
     145
     146    engine->finalizeObject();
     147
     148    return CompiledPabloFunction(func.second, func.first, engine);
     149}
     150
     151std::pair<llvm::Function *, size_t> PabloCompiler::compile(PabloFunction & function, Module * module) {
     152
     153    Examine(function);
     154
     155    mMod = module;
     156
     157    mBuilder = new IRBuilder<>(mMod->getContext());
     158
     159    iBuilder.initialize(mMod, mBuilder);
     160
     161    mCarryManager = new CarryManager(mBuilder, mBitBlockType, mZeroInitializer, mOneInitializer, &iBuilder);
    141162
    142163    GenerateFunction(function);
    143     DeclareFunctions(ee);
    144     DeclareCallFunctions(ee);
    145 
    146     mWhileDepth = 0;
    147     mIfDepth = 0;
    148     mMaxWhileDepth = 0;
    149     BasicBlock * b = BasicBlock::Create(mMod->getContext(), "entry", mFunction,0);
    150     mBuilder->SetInsertPoint(b);
     164
     165    mBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mFunction,0));
    151166
    152167    //The basis bits structure
     
    172187    }
    173188   
    174     if (LLVM_UNLIKELY(mWhileDepth != 0)) {
    175         throw std::runtime_error("Non-zero nesting depth error (" + std::to_string(mWhileDepth) + ")");
    176     }
    177 
    178189    // Write the output values out
    179190    for (unsigned i = 0; i != function.getResults().size(); ++i) {
     
    184195    ReturnInst::Create(mMod->getContext(), mBuilder->GetInsertBlock());
    185196
    186     //Display the IR that has been generated by this module.
    187     if (LLVM_UNLIKELY(DumpGeneratedIR)) {
    188         mMod->dump();
    189     }
    190     //Create a verifier.  The verifier will print an error message if our module is malformed in any way.
    191     verifyModule(*mMod, &dbgs());
    192 
    193     ee->finalizeObject();
    194 
    195     delete mCarryManager;
    196     mCarryManager = nullptr;
     197    // Clean up
     198    delete mCarryManager; mCarryManager = nullptr;
     199    delete mBuilder; mBuilder = nullptr;
     200    mMod = nullptr; // don't delete this. It's either owned by the ExecutionEngine or the calling function.
    197201
    198202    //Return the required size of the carry data area to the process_block function.
    199     return CompiledPabloFunction(totalCarryDataSize * sizeof(BitBlock), mFunction, ee);
     203    return std::make_pair(mFunction, totalCarryDataSize * sizeof(BitBlock));
    200204}
    201205
    202206inline void PabloCompiler::GenerateFunction(PabloFunction & function) {
    203     std::vector<Type *> inputType(function.getParameters().size(), mBitBlockType);
    204     std::vector<Type *> outputType(function.getResults().size(), mBitBlockType);
    205     mInputPtr = PointerType::get(StructType::get(mMod->getContext(), inputType), 0);
    206     Type * carryPtr = PointerType::get(mBitBlockType, 0);
    207     Type * outputPtr = PointerType::get(StructType::get(mMod->getContext(), outputType), 0);
    208     FunctionType * functionType = FunctionType::get(Type::getVoidTy(mMod->getContext()), {{mInputPtr, carryPtr, outputPtr}}, false);
    209 
     207    mInputType = PointerType::get(StructType::get(mMod->getContext(), std::vector<Type *>(function.getParameters().size(), mBitBlockType)), 0);
     208    Type * carryType = PointerType::get(mBitBlockType, 0);
     209    Type * outputType = PointerType::get(StructType::get(mMod->getContext(), std::vector<Type *>(function.getResults().size(), mBitBlockType)), 0);
     210    FunctionType * functionType = FunctionType::get(Type::getVoidTy(mMod->getContext()), {{mInputType, carryType, outputType}}, false);
    210211
    211212#ifdef USE_UADD_OVERFLOW
     
    314315}
    315316
    316 inline void PabloCompiler::DeclareFunctions(ExecutionEngine * ee) {
    317     if (DumpTrace || TraceNext) {
    318         //This function can be used for testing to print the contents of a register from JIT'd code to the terminal window.
    319         mPrintRegisterFunction = mMod->getOrInsertFunction("wrapped_print_register", Type::getVoidTy(getGlobalContext()), Type::getInt8PtrTy(getGlobalContext()), mBitBlockType, NULL);
    320         ee->addGlobalMapping(cast<GlobalValue>(mPrintRegisterFunction), (void *)&wrapped_print_register);
    321     }
    322 }
    323    
    324 void PabloCompiler::Examine(PabloBlock & blk) {
    325     for (Statement * stmt : blk) {
     317inline void PabloCompiler::Examine(PabloFunction & function) {
     318    if (mMod == nullptr) {
     319
     320        mWhileDepth = 0;
     321        mIfDepth = 0;
     322        mMaxWhileDepth = 0;
     323
     324        Examine(function.getEntryBlock());
     325
     326        if (LLVM_UNLIKELY(mWhileDepth != 0 || mIfDepth != 0)) {
     327            throw std::runtime_error("Malformed Pablo AST: Unbalanced If or While nesting depth!");
     328        }
     329    }
     330}
     331
     332
     333void PabloCompiler::Examine(PabloBlock & block) {
     334    for (Statement * stmt : block) {
    326335        if (Call * call = dyn_cast<Call>(stmt)) {
    327336            mCalleeMap.insert(std::make_pair(call->getCallee(), nullptr));
    328337        }
    329338        else if (If * ifStatement = dyn_cast<If>(stmt)) {
    330             ++mIfDepth;
    331339            Examine(ifStatement->getBody());
    332             --mIfDepth;
    333340        }
    334341        else if (While * whileStatement = dyn_cast<While>(stmt)) {
     
    340347}
    341348
    342 void PabloCompiler::DeclareCallFunctions(ExecutionEngine * ee) {
     349inline void PabloCompiler::DeclareFunctions(ExecutionEngine * engine) {
     350    if (DumpTrace || TraceNext) {
     351        //This function can be used for testing to print the contents of a register from JIT'd code to the terminal window.
     352        mPrintRegisterFunction = mMod->getOrInsertFunction("wrapped_print_register", Type::getVoidTy(mMod->getContext()), Type::getInt8PtrTy(mMod->getContext()), mBitBlockType, NULL);
     353        engine->addGlobalMapping(cast<GlobalValue>(mPrintRegisterFunction), (void *)&wrapped_print_register);
     354    }
     355}
     356   
     357void PabloCompiler::DeclareCallFunctions(PabloFunction & function, ExecutionEngine * engine) {
    343358    for (auto mapping : mCalleeMap) {
    344359        const String * callee = mapping.first;
    345         //std::cerr << callee->str() << " to be declared\n";
    346360        auto ei = mExternalMap.find(callee->value());
    347361        if (ei != mExternalMap.end()) {
    348             void * fn_ptr = ei->second;
    349             Value * externalValue = mMod->getOrInsertFunction(callee->value(), mBitBlockType, mInputPtr, NULL);
     362
     363            PointerType * inputType = PointerType::get(StructType::get(mMod->getContext(), std::vector<Type *>(function.getParameters().size(), mBitBlockType)), 0);
     364            ArrayRef<Type*> args = {inputType};
     365            FunctionType * functionType = FunctionType::get(mBitBlockType, args, false);
     366
     367            SmallVector<AttributeSet, 4> Attrs;
     368            Attrs.push_back(AttributeSet::get(mMod->getContext(), ~0U, { Attribute::NoUnwind, Attribute::UWTable }));
     369            Attrs.push_back(AttributeSet::get(mMod->getContext(), 1U, { Attribute::ReadOnly, Attribute::NoCapture }));
     370            AttributeSet AttrSet = AttributeSet::get(mMod->getContext(), Attrs);
     371
     372            Value * externalValue = mMod->getOrInsertFunction(callee->value(), functionType, AttrSet);
     373
    350374            if (LLVM_UNLIKELY(externalValue == nullptr)) {
    351375                throw std::runtime_error("Could not create static method call for external function \"" + callee->to_string() + "\"");
    352376            }
    353             ee->addGlobalMapping(cast<GlobalValue>(externalValue), fn_ptr);
     377            engine->addGlobalMapping(cast<GlobalValue>(externalValue), ei->second);
    354378            mCalleeMap[callee] = externalValue;
    355379        }
     
    409433    //  body.
    410434    //
     435
    411436    BasicBlock * ifEntryBlock = mBuilder->GetInsertBlock();
    412437    BasicBlock * ifBodyBlock = BasicBlock::Create(mMod->getContext(), "if.body", mFunction, 0);
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.h

    r4663 r4665  
    5757class While;
    5858
    59 static IRBuilder<> LLVM_Builder(getGlobalContext());
    60 
    6159struct CompiledPabloFunction {
    6260    const size_t        CarryDataSize;
     
    111109    void InstallExternalFunction(std::string C_fn_name, void * fn_ptr);
    112110    CompiledPabloFunction compile(pablo::PabloFunction & function);
    113     Module * getModule();
     111    std::pair<Function *, size_t> compile(pablo::PabloFunction & function, Module *module);
     112    Module *getModule();
    114113private:
    115114    void GenerateFunction(PabloFunction & function);
    116     void DeclareFunctions(ExecutionEngine * ee);
    117     void Examine(PabloBlock & blk);
    118     void DeclareCallFunctions(ExecutionEngine * ee);
     115    void DeclareFunctions(ExecutionEngine * engine);
     116    void Examine(PabloFunction & function);
     117    void Examine(PabloBlock & block);
     118    void DeclareCallFunctions(PabloFunction & function, ExecutionEngine * engine);
    119119    void SetOutputValue(Value * marker, const unsigned index);
    120120
     
    144144    #endif
    145145
    146 
    147146    ASTToValueMap                       mMarkerMap;
    148147    CarryQueueVector                    mCarryInVector;
    149148    CarryQueueVector                    mCarryOutVector;
    150149
    151 #ifdef USE_LLVM_3_5
    152     Module* const                       mMod;
    153 #else
    154     std::unique_ptr<Module>             mModOwner;
     150
    155151    Module *                            mMod;
    156 #endif
    157152    IRBuilder <> *                      mBuilder;
    158153
     
    161156    VectorType* const                   mBitBlockType;
    162157    IDISA::IDISA_Builder                iBuilder;
    163     PointerType*                        mInputPtr;
     158    PointerType*                        mInputType;
    164159
    165160    PabloBlock *                        mPabloBlock;
  • icGREP/icgrep-devel/icgrep/utf8_encoder.cpp

    r4660 r4665  
    2323        if (const CC * cc = dyn_cast_or_null<CC>(name->getDefinition())) {
    2424            if (cc->size() == 1) {
    25                 RE * def = rangeToUTF8(cc->front());
    26                 name->setDefinition(def);
     25                name->setDefinition(rangeToUTF8(cc->front()));
    2726            }
    2827            else if (cc->size() > 1) {
     
    3130                    alt.push_back(rangeToUTF8(i));
    3231                }
    33                 RE * def = makeAlt(alt.begin(), alt.end());
    34                 name->setDefinition(def);
     32                name->setDefinition(makeAlt(alt.begin(), alt.end()));
    3533            }
    3634        }
    3735    }
    38     nameMap.clear();
    3936    return nameMap.process(ast, ByteClass);
    4037}
Note: See TracChangeset for help on using the changeset viewer.