source: icGREP/icgrep-devel/icgrep/kernels/toolchain.h @ 5424

Last change on this file since 5424 was 5424, checked in by cameron, 2 years ago

ShowKernelCycles? option

File size: 5.1 KB
Line 
1/*
2 *  Copyright (c) 2017 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#ifndef TOOLCHAIN_H
8#define TOOLCHAIN_H
9#include <string>
10#include <IR_Gen/idisa_builder.h>
11#include <llvm/IR/TypeBuilder.h>
12#include <kernels/kernel.h>
13#include <kernels/streamset.h>
14#include <boost/container/flat_map.hpp>
15
16namespace llvm { class ExecutionEngine; }
17namespace llvm { class Module; }
18namespace llvm { class TargetMachine; }
19namespace llvm { class formatted_raw_ostream; }
20namespace llvm { namespace cl { class OptionCategory; } }
21namespace IDISA { class IDISA_Builder; }
22namespace kernel { class KernelBuilder; }
23
24class ParabixObjectCache;
25
26namespace codegen {
27const llvm::cl::OptionCategory * codegen_flags();
28
29// Command Parameters
30enum DebugFlags {
31    ShowIR,
32#ifndef USE_LLVM_3_6
33    ShowASM,
34#endif
35    SerializeThreads
36};
37
38bool DebugOptionIsSet(DebugFlags flag);
39
40
41extern char OptLevel;  // set from command line
42extern int BlockSize;  // set from command line
43extern int SegmentSize;  // set from command line
44extern int BufferSegments;
45extern int ThreadNum;
46extern bool EnableAsserts;
47extern bool EnableCycleCounter;
48#ifdef CUDA_ENABLED
49extern bool NVPTX;
50extern int GroupNum;
51#endif
52}
53
54#ifdef CUDA_ENABLED
55void setNVPTXOption();
56void Compile2PTX (llvm::Module * m, std::string IRFilename, std::string PTXFilename);
57#endif
58
59void AddParabixVersionPrinter();
60
61bool AVX2_available();
62
63class ParabixDriver {
64    using ModuleMap = boost::container::flat_map<kernel::KernelBuilder *, llvm::Module *>;
65public:
66    ParabixDriver(IDISA::IDISA_Builder * iBuilder);
67
68    ~ParabixDriver();
69   
70    IDISA::IDISA_Builder * getIDISA_Builder() {return iBuilder;}
71   
72    parabix::ExternalFileBuffer * addExternalBuffer(std::unique_ptr<parabix::ExternalFileBuffer> b, llvm::Value * externalBuf);
73   
74    parabix::StreamSetBuffer * addBuffer(std::unique_ptr<parabix::StreamSetBuffer> b);
75   
76    kernel::KernelBuilder * addKernelInstance(std::unique_ptr<kernel::KernelBuilder> kb);
77   
78    void addKernelCall(kernel::KernelBuilder & kb, const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
79    void makeKernelCall(kernel::KernelBuilder * kb, const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
80   
81    void generatePipelineIR();
82   
83    template <typename ExternalFunctionType>
84    void addExternalLink(kernel::KernelBuilder & kb, llvm::StringRef name, ExternalFunctionType * functionPtr) const;
85
86    void linkAndFinalize();
87   
88    void * getPointerToMain();
89
90private:
91
92
93    void addExternalLink(kernel::KernelBuilder & kb, llvm::StringRef name, llvm::FunctionType * type, void * functionPtr) const;
94
95
96private:
97    IDISA::IDISA_Builder * const            iBuilder;
98    llvm::Module * const                    mMainModule;
99    llvm::TargetMachine *                   mTarget;
100    llvm::ExecutionEngine *                 mEngine;
101    ParabixObjectCache *                    mCache;
102    std::vector<kernel::KernelBuilder *>    mPipeline;
103    // Owned kernels and buffers that will persist with this ParabixDriver instance.
104    std::vector<std::unique_ptr<kernel::KernelBuilder>> mOwnedKernels;
105    std::vector<std::unique_ptr<parabix::StreamSetBuffer>> mOwnedBuffers;
106};
107
108namespace {
109
110// NOTE: Currently, LLVM TypeBuilder can deduce FuntionTypes for up to 5 arguments. The following
111// templates have no limit but should be deprecated if the TypeBuilder ever supports n-ary functions.
112
113template<unsigned i, typename... Args>
114struct ParameterTypeBuilder;
115
116template<unsigned i, typename A1, typename... An>
117struct ParameterTypeBuilder<i, A1, An...> {
118    static void get(llvm::LLVMContext & C, llvm::Type ** params) {
119        ParameterTypeBuilder<i, A1>::get(C, params);
120        ParameterTypeBuilder<i + 1, An...>::get(C, params);
121    }
122};
123
124template<unsigned i, typename A>
125struct ParameterTypeBuilder<i, A> {
126    static void get(llvm::LLVMContext & C, llvm::Type ** params) {
127        params[i] = llvm::TypeBuilder<A, false>::get(C);
128    }
129};
130
131template<typename T>
132struct FunctionTypeBuilder;
133
134template<typename R, typename... Args>
135struct FunctionTypeBuilder<R(Args...)> {
136    static llvm::FunctionType * get(llvm::LLVMContext & C) {
137        llvm::Type * params[sizeof...(Args)];
138        ParameterTypeBuilder<0, Args...>::get(C, params);
139        return llvm::FunctionType::get(llvm::TypeBuilder<R, false>::get(C), params, false);
140    }
141};
142
143template<typename R>
144struct FunctionTypeBuilder<R()> {
145    static llvm::FunctionType * get(llvm::LLVMContext & C) {
146        return llvm::FunctionType::get(llvm::TypeBuilder<R, false>::get(C), false);
147    }
148};
149
150}
151
152template <typename ExternalFunctionType>
153void ParabixDriver::addExternalLink(kernel::KernelBuilder & kb, llvm::StringRef name, ExternalFunctionType * functionPtr) const {
154    llvm::FunctionType * const type = FunctionTypeBuilder<ExternalFunctionType>::get(iBuilder->getContext());
155    assert ("FunctionTypeBuilder did not resolve a function type." && type);
156    addExternalLink(kb, name, type, reinterpret_cast<void *>(functionPtr));
157}
158
159#endif
Note: See TracBrowser for help on using the repository browser.