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

Last change on this file since 5757 was 5757, checked in by nmedfort, 20 months ago

Bug fixes + more assertions to prevent similar errors.

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> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
60                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
61
62
63static cl::opt<unsigned, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(8),
64                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
65
66static cl::opt<unsigned, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
67                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
68
69
70static cl::opt<unsigned, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
71                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
72
73
74static cl::opt<bool, true> pipelineParallelOption("enable-pipeline-parallel", cl::location(PipelineParallel), cl::init(false),
75                                                  cl::desc("Enable multithreading with pipeline parallelism."), cl::cat(CodeGenOptions));
76   
77static cl::opt<bool, true> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel),
78                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
79
80static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
81                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
82
83static cl::opt<unsigned, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
84                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
85
86CodeGenOpt::Level OptLevel;
87
88bool PipelineParallel;
89
90bool SegmentPipelineParallel;
91
92const char * ObjectCacheDir;
93
94unsigned BlockSize;
95
96unsigned SegmentSize;
97
98unsigned BufferSegments;
99
100unsigned ThreadNum;
101
102bool EnableObjectCache;
103
104bool NVPTX = [](const bool nvptx) {
105    #ifndef CUDA_ENABLED
106    if (nvptx) {
107        report_fatal_error("CUDA compiler is not supported.");
108    }
109    #endif
110    return nvptx;
111}(NVPTXOption);
112
113unsigned GroupNum;
114
115const llvm::Reloc::Model RelocModel = ::RelocModel;
116
117const llvm::CodeModel::Model CMModel = ::CMModel;
118
119const std::string MArch = ::MArch;
120
121const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
122
123TargetOptions Options;
124
125const cl::OptionCategory * codegen_flags() {
126    return &CodeGenOptions;
127}
128
129bool DebugOptionIsSet(const DebugFlags flag) {
130    if (flag == EnableAsserts) return true;
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.