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

Last change on this file since 5913 was 5841, checked in by cameron, 20 months ago

LLVM_VERSION_CODE macro, CC-multiplex option, performance bug fixes

File size: 8.2 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#include <toolchain/toolchain.h>
8#include <pablo/pablo_toolchain.h>
9#include <UCD/UCD_Config.h>
10#include <llvm/CodeGen/CommandFlags.h>
11#include <llvm/Support/raw_ostream.h>
12
13using namespace llvm;
14
15#ifndef NDEBUG
16#define IN_DEBUG_MODE true
17#else
18#define IN_DEBUG_MODE false
19#endif
20
21namespace codegen {
22
23static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
24
25static cl::bits<DebugFlags>
26DebugOptions(cl::values(clEnumVal(VerifyIR, "Run the IR verification pass."),
27                        clEnumVal(SerializeThreads, "Force segment threads to run sequentially."),
28                        clEnumVal(TraceCounts, "Show kernel processed and produced item counts."),
29                        clEnumVal(TraceDynamicBuffers, "Show dynamic buffer allocations and deallocations."),
30                        clEnumVal(EnableAsserts, "Enable built-in Parabix framework asserts in generated IR."),
31                        clEnumVal(EnableCycleCounter, "Count and report CPU cycles per kernel."),
32                        clEnumVal(DisableIndirectBranch, "Disable use of indirect branches in kernel code.")
33                        CL_ENUM_VAL_SENTINEL), cl::cat(CodeGenOptions));
34
35std::string ShowIROption = OmittedOption;
36static cl::opt<std::string, true> IROutputOption("ShowIR", cl::location(ShowIROption), cl::ValueOptional,
37                                                         cl::desc("Print optimized LLVM IR to stderr (by omitting =<filename>) or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
38
39std::string ShowUnoptimizedIROption = OmittedOption;
40static cl::opt<std::string, true> UnoptimizedIROutputOption("ShowUnoptimizedIR", cl::location(ShowUnoptimizedIROption), cl::ValueOptional,
41                                                         cl::desc("Print generated LLVM IR to stderr (by omitting =<filename> or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
42
43#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
44std::string ShowASMOption = OmittedOption;
45static cl::opt<std::string, true> ASMOutputFilenameOption("ShowASM", cl::location(ShowASMOption), cl::ValueOptional,
46                                                         cl::desc("Print generated assembly code to stderr (by omitting =<filename> or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
47#endif
48
49static cl::opt<char> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
50                                    cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
51
52
53static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
54                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
55
56static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
57                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
58
59
60static cl::opt<unsigned, true> CacheLimitOption("cache-days-limit", cl::location(CacheDaysLimit), cl::init(15),
61                                          cl::desc("number of days a cache entry may be unused before auto deletion may be applied"), cl::cat(CodeGenOptions));
62
63
64static cl::opt<unsigned, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
65                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
66
67
68static cl::opt<unsigned, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(8),
69                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
70
71static cl::opt<unsigned, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
72                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
73
74
75static cl::opt<unsigned, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
76                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
77
78
79static cl::opt<bool, true> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel),
80                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
81
82static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
83                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
84
85static cl::opt<unsigned, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
86                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
87
88CodeGenOpt::Level OptLevel;
89
90bool SegmentPipelineParallel;
91
92const char * ObjectCacheDir;
93
94unsigned BlockSize;
95
96unsigned SegmentSize;
97
98unsigned BufferSegments;
99
100unsigned ThreadNum;
101
102bool EnableObjectCache;
103
104unsigned CacheDaysLimit;
105
106bool NVPTX = [](const bool nvptx) {
107    #ifndef CUDA_ENABLED
108    if (nvptx) {
109        report_fatal_error("CUDA compiler is not supported.");
110    }
111    #endif
112    return nvptx;
113}(NVPTXOption);
114
115unsigned GroupNum;
116
117const llvm::Reloc::Model RelocModel = ::RelocModel;
118
119const llvm::CodeModel::Model CMModel = ::CMModel;
120
121const std::string MArch = ::MArch;
122
123const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
124
125TargetOptions Options;
126
127const cl::OptionCategory * LLVM_READONLY codegen_flags() {
128    return &CodeGenOptions;
129}
130
131bool LLVM_READONLY DebugOptionIsSet(const DebugFlags flag) {
132    return DebugOptions.isSet(flag);
133}
134
135std::string getCPUStr() {
136    return ::getCPUStr();
137}
138
139std::string getFeaturesStr() {
140    return ::getFeaturesStr();
141}
142
143void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
144    return ::setFunctionAttributes(CPU, Features, M);
145}
146
147std::string ProgramName;
148
149void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
150    AddParabixVersionPrinter();
151    codegen::ProgramName = argv[0];
152#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
153    if (hiding.size() != 0) {
154        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
155    }
156#endif
157    cl::ParseCommandLineOptions(argc, argv);
158    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption) || (ShowASMOption != OmittedOption)
159        || (pablo::ShowPabloOption != OmittedOption) || (pablo::ShowOptimizedPabloOption != OmittedOption)) {
160        EnableObjectCache = false;
161    }
162    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
163    Options = InitTargetOptionsFromCodeGenFlags();
164#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
165    Options.MCOptions.AsmVerbose = true;
166#endif
167    switch (OptLevelOption) {
168        case '0': OptLevel = CodeGenOpt::None; break;
169        case '1': OptLevel = CodeGenOpt::Less; break;
170        case '2': OptLevel = CodeGenOpt::Default; break;
171        case '3': OptLevel = CodeGenOpt::Aggressive; break;
172        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
173    }
174#ifndef CUDA_ENABLED
175    if (NVPTX) {
176        report_fatal_error("CUDA compiler is not supported.");
177    }
178#endif
179}
180
181}
182#if LLVM_VERSION_INTEGER < LLVM_VERSION_CODE(6, 0, 0)
183void printParabixVersion () {
184    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
185    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
186}
187#else
188void printParabixVersion (raw_ostream & outs) {
189    outs << "Unicode version " << UCD::UnicodeVersion << "\n";
190    outs << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
191}
192#endif
193
194void AddParabixVersionPrinter() {
195    cl::AddExtraVersionPrinter(&printParabixVersion);
196}
Note: See TracBrowser for help on using the repository browser.