source: icGREP/icgrep-devel/icgrep/toolchain.cpp @ 5033

Last change on this file since 5033 was 5033, checked in by cameron, 3 years ago

Refactor: move grep-specific code out of toolchain

File size: 4.4 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include <string>
8#include <iostream>
9#include <fstream>
10#include <sstream>
11
12#include <toolchain.h>
13#include <llvm/IR/Function.h>
14#include <llvm/IR/Module.h>
15#include <llvm/ExecutionEngine/ExecutionEngine.h>
16#include <llvm/ExecutionEngine/MCJIT.h>
17#include <llvm/IRReader/IRReader.h>
18#include <llvm/Support/CommandLine.h>
19#include <llvm/CodeGen/CommandFlags.h>
20#include <llvm/Support/SourceMgr.h>
21#include <llvm/Support/TargetSelect.h>
22#include <llvm/Support/Host.h>
23#include <llvm/Support/raw_ostream.h>
24
25#include <util/ispc.h>
26
27#include <object_cache.h>
28
29using namespace llvm;
30
31namespace codegen {
32
33static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
34
35
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'));
42
43
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));
47
48
49int BlockSize;
50int SegmentSize;
51
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));
54
55const cl::OptionCategory * codegen_flags() {return &CodeGenOptions;}
56
57}
58
59ExecutionEngine * JIT_to_ExecutionEngine (Module * m) {
60
61    InitializeNativeTarget();
62    InitializeNativeTargetAsmPrinter();
63    InitializeNativeTargetAsmParser();
64
65    PassRegistry * Registry = PassRegistry::getPassRegistry();
66    initializeCore(*Registry);
67    initializeCodeGen(*Registry);
68    initializeLowerIntrinsicsPass(*Registry);
69
70    std::string errMessage;
71    EngineBuilder builder(std::move(std::unique_ptr<Module>(m)));
72    builder.setErrorStr(&errMessage);
73    builder.setMCPU(sys::getHostCPUName());
74    TargetOptions opts = InitTargetOptionsFromCodeGenFlags();
75    #ifndef NDEBUG
76    opts.JITEmitDebugInfo = 1;
77    #endif
78    builder.setTargetOptions(opts);
79    CodeGenOpt::Level optLevel = CodeGenOpt::Level::None;
80    switch (codegen::OptLevel) {
81        case '0': optLevel = CodeGenOpt::None; break;
82        case '1': optLevel = CodeGenOpt::Less; break;
83        case '2': optLevel = CodeGenOpt::Default; break;
84        case '3': optLevel = CodeGenOpt::Aggressive; break;
85        default: errs() << codegen::OptLevel << " is an invalid optimization level.\n";
86    }
87    builder.setOptLevel(optLevel);
88
89    if ((strncmp(lGetSystemISA(), "avx2", 4) == 0)) {
90        std::vector<std::string> attrs;
91        attrs.push_back("avx2");
92        builder.setMAttrs(attrs);
93    }
94    // builder.selectTarget();
95
96    if (LLVM_UNLIKELY(codegen::DumpGeneratedIR)) {
97        if (codegen::IROutputFilename.empty()) {
98            m->dump();
99        } else {
100            std::error_code error;
101            llvm::raw_fd_ostream out(codegen::IROutputFilename, error, sys::fs::OpenFlags::F_None);
102            m->print(out, nullptr);
103        }
104    }
105
106    ExecutionEngine * engine = builder.create();
107    if (engine == nullptr) {
108        throw std::runtime_error("Could not create ExecutionEngine: " + errMessage);
109    }   
110    return engine;
111}
112
113void ApplyObjectCache(ExecutionEngine * e) {
114    ICGrepObjectCache * cache = nullptr;
115    if (codegen::EnableObjectCache) {
116        if (codegen::ObjectCacheDir.empty())
117            // Default is $HOME/.cache/icgrep
118            cache = new ICGrepObjectCache();
119        else
120            cache = new ICGrepObjectCache(codegen::ObjectCacheDir);
121        e->setObjectCache(cache);
122    }   
123}
Note: See TracBrowser for help on using the repository browser.