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

Last change on this file since 5761 was 5759, checked in by cameron, 23 months ago

Small fixes

File size: 7.9 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    return DebugOptions.isSet(flag);
131}
132
133std::string getCPUStr() {
134    return ::getCPUStr();
135}
136
137std::string getFeaturesStr() {
138    return ::getFeaturesStr();
139}
140
141void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
142    return ::setFunctionAttributes(CPU, Features, M);
143}
144
145std::string ProgramName;
146
147void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
148    AddParabixVersionPrinter();
149    codegen::ProgramName = argv[0];
150#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
151    if (hiding.size() != 0) {
152        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
153    }
154#endif
155    cl::ParseCommandLineOptions(argc, argv);
156    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption) || (ShowASMOption != OmittedOption)) {
157        EnableObjectCache = false;
158    }
159    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
160    Options = InitTargetOptionsFromCodeGenFlags();
161#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
162    Options.MCOptions.AsmVerbose = true;
163#endif
164    switch (OptLevelOption) {
165        case '0': OptLevel = CodeGenOpt::None; break;
166        case '1': OptLevel = CodeGenOpt::Less; break;
167        case '2': OptLevel = CodeGenOpt::Default; break;
168        case '3': OptLevel = CodeGenOpt::Aggressive; break;
169        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
170    }
171#ifndef CUDA_ENABLED
172    if (NVPTX) {
173        report_fatal_error("CUDA compiler is not supported.");
174    }
175#endif
176}
177
178}
179#if LLVM_VERSION_INTEGER < LLVM_6_0_0
180void printParabixVersion () {
181    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
182    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
183}
184#else
185void printParabixVersion (raw_ostream & outs) {
186    outs << "Unicode version " << UCD::UnicodeVersion << "\n";
187    outs << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
188}
189#endif
190
191void AddParabixVersionPrinter() {
192    cl::AddExtraVersionPrinter(&printParabixVersion);
193}
Note: See TracBrowser for help on using the repository browser.