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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.