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

Last change on this file since 5832 was 5793, checked in by nmedfort, 19 months ago

Bug fix for pipeline: it was terminating too early when there was insufficient output space to process all of the input for a kernel.

File size: 8.0 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> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel),
79                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
80
81static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
82                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
83
84static cl::opt<unsigned, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
85                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
86
87CodeGenOpt::Level OptLevel;
88
89bool SegmentPipelineParallel;
90
91const char * ObjectCacheDir;
92
93unsigned BlockSize;
94
95unsigned SegmentSize;
96
97unsigned BufferSegments;
98
99unsigned ThreadNum;
100
101bool EnableObjectCache;
102
103unsigned CacheDaysLimit;
104
105bool NVPTX = [](const bool nvptx) {
106    #ifndef CUDA_ENABLED
107    if (nvptx) {
108        report_fatal_error("CUDA compiler is not supported.");
109    }
110    #endif
111    return nvptx;
112}(NVPTXOption);
113
114unsigned GroupNum;
115
116const llvm::Reloc::Model RelocModel = ::RelocModel;
117
118const llvm::CodeModel::Model CMModel = ::CMModel;
119
120const std::string MArch = ::MArch;
121
122const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
123
124TargetOptions Options;
125
126const cl::OptionCategory * LLVM_READONLY codegen_flags() {
127    return &CodeGenOptions;
128}
129
130bool LLVM_READONLY DebugOptionIsSet(const DebugFlags flag) {
131    return DebugOptions.isSet(flag);
132}
133
134std::string getCPUStr() {
135    return ::getCPUStr();
136}
137
138std::string getFeaturesStr() {
139    return ::getFeaturesStr();
140}
141
142void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
143    return ::setFunctionAttributes(CPU, Features, M);
144}
145
146std::string ProgramName;
147
148void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
149    AddParabixVersionPrinter();
150    codegen::ProgramName = argv[0];
151#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
152    if (hiding.size() != 0) {
153        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
154    }
155#endif
156    cl::ParseCommandLineOptions(argc, argv);
157    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption) || (ShowASMOption != OmittedOption)) {
158        EnableObjectCache = false;
159    }
160    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
161    Options = InitTargetOptionsFromCodeGenFlags();
162#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
163    Options.MCOptions.AsmVerbose = true;
164#endif
165    switch (OptLevelOption) {
166        case '0': OptLevel = CodeGenOpt::None; break;
167        case '1': OptLevel = CodeGenOpt::Less; break;
168        case '2': OptLevel = CodeGenOpt::Default; break;
169        case '3': OptLevel = CodeGenOpt::Aggressive; break;
170        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
171    }
172#ifndef CUDA_ENABLED
173    if (NVPTX) {
174        report_fatal_error("CUDA compiler is not supported.");
175    }
176#endif
177}
178
179}
180#if LLVM_VERSION_INTEGER < LLVM_6_0_0
181void printParabixVersion () {
182    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
183    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
184}
185#else
186void printParabixVersion (raw_ostream & outs) {
187    outs << "Unicode version " << UCD::UnicodeVersion << "\n";
188    outs << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
189}
190#endif
191
192void AddParabixVersionPrinter() {
193    cl::AddExtraVersionPrinter(&printParabixVersion);
194}
Note: See TracBrowser for help on using the repository browser.