Ignore:
Timestamp:
May 6, 2016, 3:28:07 PM (3 years ago)
Author:
cameron
Message:

Refactor: move grep-specific code out of toolchain

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/toolchain.cpp

    r5025 r5033  
    11/*
    2  *  Copyright (c) 2015 International Characters.
     2 *  Copyright (c) 2016 International Characters.
    33 *  This software is licensed to the public under the Open Software License 3.0.
    44 *  icgrep is a trademark of International Characters.
     
    1010#include <sstream>
    1111
     12#include <toolchain.h>
    1213#include <llvm/IR/Function.h>
    1314#include <llvm/IR/Module.h>
     
    2223#include <llvm/Support/raw_ostream.h>
    2324
    24 // Dynamic processor detection
    25 #define ISPC_LLVM_VERSION ISPC_LLVM_3_6
    26 #include <util/ispc.cpp>
     25#include <util/ispc.h>
    2726
    28 #include <re/re_cc.h>
    2927#include <object_cache.h>
    3028
    31 static cl::OptionCategory bGrepOutputOptions("Output Options",
    32                                       "These options control the output.");
     29using namespace llvm;
    3330
    34 static cl::opt<bool> NormalizeLineBreaks("normalize-line-breaks", cl::desc("Normalize line breaks to std::endl."), cl::init(false),  cl::cat(bGrepOutputOptions));
     31namespace codegen {
    3532
    36 static cl::opt<bool> ShowFileNames("H", cl::desc("Show the file name with each matching line."), cl::cat(bGrepOutputOptions));
    37 static cl::alias ShowFileNamesLong("with-filename", cl::desc("Alias for -H"), cl::aliasopt(ShowFileNames));
    38 
    39 static cl::opt<bool> ShowLineNumbers("n", cl::desc("Show the line number with each matching line."), cl::cat(bGrepOutputOptions));
    40 static cl::alias ShowLineNumbersLong("line-number", cl::desc("Alias for -n"), cl::aliasopt(ShowLineNumbers));
    41 
    42 static cl::OptionCategory eIRDumpOptions("LLVM IR Dump Options", "These options control dumping of LLVM IR.");
    43 static cl::opt<bool> DumpGeneratedIR("dump-generated-IR", cl::init(false), cl::desc("Print LLVM IR generated by Pablo Compiler."), cl::cat(eIRDumpOptions));
    44 static cl::opt<std::string> IROutputFilename("dump-generated-IR-output", cl::init(""), cl::desc("output IR filename"), cl::cat(eIRDumpOptions));
     33static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
    4534
    4635
    47 static cl::OptionCategory cMachineCodeOptimization("Machine Code Optimizations", "These options control back-end compilier optimization levels.");
     36static cl::opt<bool> DumpGeneratedIR("dump-generated-IR", cl::init(false), cl::desc("Print LLVM IR generated by Pablo Compiler."), cl::cat(CodeGenOptions));
     37static cl::opt<std::string> IROutputFilename("dump-generated-IR-output", cl::init(""), cl::desc("output IR filename"), cl::cat(CodeGenOptions));
     38
     39char OptLevel;
     40static cl::opt<char, true> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"), cl::location(OptLevel),
     41                              cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
    4842
    4943
    50 static cl::opt<char> OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
    51                               cl::cat(cMachineCodeOptimization), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
     44static cl::opt<bool> EnableObjectCache("enable-object-cache", cl::init(false), cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
     45
     46static cl::opt<std::string> ObjectCacheDir("object-cache-dir", cl::init(""), cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
    5247
    5348
    54 static cl::OptionCategory cObjectCache("Object Caching", "These options control back-end object caching behaviours.");
     49int BlockSize;
     50int SegmentSize;
    5551
    56 static cl::opt<bool> EnableObjectCache("enable-object-cache", cl::init(false), cl::desc("Enable object caching"), cl::cat(cObjectCache));
     52static cl::opt<int, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0), cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
     53static cl::opt<int, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::desc("Segment Size"), cl::value_desc("positive integer"), cl::init(1));
    5754
    58 static cl::opt<std::string> ObjectCacheDir("object-cache-dir", cl::init(""), cl::desc("Path to the object cache diretory"), cl::cat(cObjectCache));
     55const cl::OptionCategory * codegen_flags() {return &CodeGenOptions;}
    5956
    60 
     57}
    6158
    6259ExecutionEngine * JIT_to_ExecutionEngine (Module * m) {
     
    8178    builder.setTargetOptions(opts);
    8279    CodeGenOpt::Level optLevel = CodeGenOpt::Level::None;
    83     switch (OptLevel) {
     80    switch (codegen::OptLevel) {
    8481        case '0': optLevel = CodeGenOpt::None; break;
    8582        case '1': optLevel = CodeGenOpt::Less; break;
    8683        case '2': optLevel = CodeGenOpt::Default; break;
    8784        case '3': optLevel = CodeGenOpt::Aggressive; break;
    88         default: errs() << OptLevel << " is an invalid optimization level.\n";
     85        default: errs() << codegen::OptLevel << " is an invalid optimization level.\n";
    8986    }
    9087    builder.setOptLevel(optLevel);
     
    9794    // builder.selectTarget();
    9895
    99     if (LLVM_UNLIKELY(DumpGeneratedIR)) {
    100         if (IROutputFilename.empty()) {
     96    if (LLVM_UNLIKELY(codegen::DumpGeneratedIR)) {
     97        if (codegen::IROutputFilename.empty()) {
    10198            m->dump();
    10299        } else {
    103100            std::error_code error;
    104             llvm::raw_fd_ostream out(IROutputFilename, error, sys::fs::OpenFlags::F_None);
     101            llvm::raw_fd_ostream out(codegen::IROutputFilename, error, sys::fs::OpenFlags::F_None);
    105102            m->print(out, nullptr);
    106103        }
     
    108105
    109106    ExecutionEngine * engine = builder.create();
    110     ICGrepObjectCache * cache = nullptr;
    111107    if (engine == nullptr) {
    112108        throw std::runtime_error("Could not create ExecutionEngine: " + errMessage);
    113     }
    114     if (EnableObjectCache) {
    115         if (ObjectCacheDir.empty())
     109    }   
     110    return engine;
     111}
     112
     113void ApplyObjectCache(ExecutionEngine * e) {
     114    ICGrepObjectCache * cache = nullptr;
     115    if (codegen::EnableObjectCache) {
     116        if (codegen::ObjectCacheDir.empty())
    116117            // Default is $HOME/.cache/icgrep
    117118            cache = new ICGrepObjectCache();
    118119        else
    119             cache = new ICGrepObjectCache(ObjectCacheDir);
    120         engine->setObjectCache(cache);
    121     }
    122     return engine;
     120            cache = new ICGrepObjectCache(codegen::ObjectCacheDir);
     121        e->setObjectCache(cache);
     122    }   
    123123}
    124 
    125 
    126 
    127 static int * total_count;
    128 static std::stringstream * resultStrs = nullptr;
    129 static std::vector<std::string> inputFiles;
    130 
    131 void initResult(std::vector<std::string> filenames){
    132     const int n = filenames.size();
    133     if (n > 1) {
    134         ShowFileNames = true;
    135     }
    136     inputFiles = filenames;
    137     resultStrs = new std::stringstream[n];
    138     total_count = new int[n];
    139     for (int i=0; i<inputFiles.size(); i++){
    140         total_count[i] = 0;
    141     }
    142 
    143 }
    144 
    145 extern "C" {
    146     void wrapped_report_match(uint64_t lineNum, uint64_t line_start, uint64_t line_end, const char * buffer, uint64_t filesize, int fileIdx) {
    147 
    148         int idx = fileIdx;
    149 
    150         if (ShowFileNames) {
    151             resultStrs[idx] << inputFiles[idx] << ':';
    152         }
    153         if (ShowLineNumbers) {
    154             resultStrs[idx] << lineNum << ":";
    155         }
    156 
    157         if ((buffer[line_start] == 0xA) && (line_start != line_end)) {
    158             // The line "starts" on the LF of a CRLF.  Really the end of the last line.
    159             line_start++;
    160         }
    161         if (line_end == filesize) {
    162             // The match position is at end-of-file.   We have a final unterminated line.
    163             resultStrs[idx].write(&buffer[line_start], line_end - line_start);
    164             if (NormalizeLineBreaks) {
    165                 resultStrs[idx] << '\n';  // terminate it
    166             }
    167             return;
    168         }
    169         unsigned char end_byte = (unsigned char)buffer[line_end];
    170         if (NormalizeLineBreaks) {
    171             if (end_byte == 0x85) {
    172                 // Line terminated with NEL, on the second byte.  Back up 1.
    173                 line_end--;
    174             } else if (end_byte > 0xD) {
    175                 // Line terminated with PS or LS, on the third byte.  Back up 2.
    176                 line_end -= 2;
    177             }
    178             resultStrs[idx].write(&buffer[line_start], line_end - line_start);
    179             resultStrs[idx] << '\n';
    180         }
    181         else{   
    182             if (end_byte == 0x0D) {
    183                 // Check for line_end on first byte of CRLF;  note that we don't
    184                 // want to access past the end of buffer.
    185                 if ((line_end + 1 < filesize) && (buffer[line_end + 1] == 0x0A)) {
    186                     // Found CRLF; preserve both bytes.
    187                     line_end++;
    188                 }
    189             }
    190             resultStrs[idx].write(&buffer[line_start], line_end - line_start + 1);
    191         }
    192     }
    193 }
    194 
    195 void PrintResult(bool CountOnly, std::vector<int> & total_CountOnly){
    196     if(CountOnly){
    197         if (!ShowFileNames) {
    198            for (int i=0; i<inputFiles.size(); i++){
    199                std::cout << total_CountOnly[i] << std::endl;
    200            }
    201         }
    202         else {
    203             for (int i=0; i<inputFiles.size(); i++){
    204                 std::cout << inputFiles[i] << ':' << total_CountOnly[i] << std::endl;
    205             };
    206         }
    207         return;
    208     }
    209 
    210     std::string out;
    211     for (int i=0; i<inputFiles.size(); i++){
    212         std::cout << resultStrs[i].str();
    213     }
    214 }
    215 
    216 re::CC * parsedCodePointSet;
    217 
    218 extern "C" {
    219     void insert_codepoints(uint64_t lineNum, uint64_t line_start, uint64_t line_end, const char * buffer) {
    220        re::codepoint_t c = 0;
    221         ssize_t line_pos = line_start;
    222         while (isxdigit(buffer[line_pos])) {
    223             if (isdigit(buffer[line_pos])) {
    224                 c = (c << 4) | (buffer[line_pos] - '0');
    225             }
    226             else {
    227                 c = (c << 4) | (tolower(buffer[line_pos]) - 'a' + 10);
    228             }
    229             line_pos++;
    230         }
    231         assert(((line_pos - line_start) >= 4) && ((line_pos - line_start) <= 6)); // UCD format 4 to 6 hex digits.       
    232         parsedCodePointSet->insert(c);
    233     }
    234 }
    235 
    236 void setParsedCodePointSet(){
    237     parsedCodePointSet = re::makeCC();
    238 }
    239 
    240 re::CC * getParsedCodePointSet(){
    241     return parsedCodePointSet;
    242 }
    243 
    244 void icgrep_Linking(Module * m, ExecutionEngine * e) {
    245     Module::FunctionListType & fns = m->getFunctionList();
    246     for (Module::FunctionListType::iterator it = fns.begin(), it_end = fns.end(); it != it_end; ++it) {
    247         std::string fnName = it->getName().str();
    248         if (fnName == "s2p_block") continue;
    249         if (fnName == "process_block") continue;
    250         if (fnName == "process_block_initialize_carries") continue;
    251        
    252         if (fnName == "wrapped_report_match") {
    253             e->addGlobalMapping(cast<GlobalValue>(it), (void *)&wrapped_report_match);
    254         }
    255         if (fnName == "insert_codepoints") {
    256             e->addGlobalMapping(cast<GlobalValue>(it), (void *)&insert_codepoints);
    257         }
    258 #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
    259         else {
    260             const UCD::ExternalProperty & ep = UCD::resolveExternalProperty(fnName);
    261             e->addGlobalMapping(cast<GlobalValue>(it), std::get<0>(ep));
    262         }
    263 #endif
    264     }
    265 }
Note: See TracChangeset for help on using the changeset viewer.