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

Last change on this file since 5773 was 5773, checked in by cameron, 19 months ago

Fix a segfault and add -cache-days-limit=N option

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