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

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

LLVM_VERSION_INTEGER allows ordered comparisons, initial preparation for LLVM 3.9.0

File size: 7.7 KB
Line 
1/*
2 *  Copyright (c) 2016 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
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(ShowUnoptimizedIR, "Print generated LLVM IR."),
27                        clEnumVal(ShowIR, "Print optimized LLVM IR."),
28                        clEnumVal(VerifyIR, "Run the IR verification pass."),
29#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
30                        clEnumVal(ShowASM, "Print assembly code."),
31#endif
32                        clEnumVal(SerializeThreads, "Force segment threads to run sequentially."),
33                        clEnumVal(TraceCounts, "Show kernel processed and produced item counts."),
34                        clEnumVal(TraceDynamicBuffers, "Show dynamic buffer allocations and deallocations."),
35                        clEnumVal(EnableAsserts, "Enable built-in Parabix framework asserts in generated IR."),
36                        clEnumVal(EnableCycleCounter, "Count and report CPU cycles per kernel."),
37                        clEnumValEnd), cl::cat(CodeGenOptions));
38
39static cl::opt<std::string> IROutputFilenameOption("dump-generated-IR-output", cl::init(""),
40                                                       cl::desc("output IR filename"), cl::cat(CodeGenOptions));
41
42#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
43static cl::opt<std::string> ASMOutputFilenameOption("asm-output", cl::init(""),
44                                                    cl::desc("output ASM filename"), cl::cat(CodeGenOptions));
45
46static cl::opt<bool> AsmVerbose("asm-verbose", cl::init(true),
47                                cl::desc("Add comments to directives."), cl::cat(CodeGenOptions));
48#endif
49
50static cl::opt<char> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
51                                    cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
52
53
54static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
55                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
56
57static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
58                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
59
60
61static cl::opt<int, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
62                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
63
64
65static cl::opt<int, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(1),
66                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
67
68static cl::opt<int, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
69                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
70
71
72static cl::opt<int, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
73                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
74
75
76static cl::opt<bool, true> pipelineParallelOption("enable-pipeline-parallel", cl::location(PipelineParallel), cl::init(false),
77                                                  cl::desc("Enable multithreading with pipeline parallelism."), cl::cat(CodeGenOptions));
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<int, 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 PipelineParallel;
91
92bool SegmentPipelineParallel;
93
94const char * ASMOutputFilename;
95
96const char * IROutputFilename;
97
98const char * ObjectCacheDir;
99
100int BlockSize;
101
102int SegmentSize;
103
104int BufferSegments;
105
106int ThreadNum;
107
108bool EnableObjectCache;
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
119int 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 * codegen_flags() {
132    return &CodeGenOptions;
133}
134
135bool DebugOptionIsSet(const DebugFlags flag) {
136    if (IN_DEBUG_MODE && (flag == EnableAsserts)) return true;
137    return DebugOptions.isSet(flag);
138}
139
140std::string getCPUStr() {
141    return ::getCPUStr();
142}
143
144std::string getFeaturesStr() {
145    return ::getFeaturesStr();
146}
147
148void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
149    return ::setFunctionAttributes(CPU, Features, M);
150}
151
152std::string ProgramName;
153
154void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
155    AddParabixVersionPrinter();
156    codegen::ProgramName = argv[0];
157#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
158    if (hiding.size() != 0) {
159        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
160    }
161#endif
162    cl::ParseCommandLineOptions(argc, argv);
163    if (DebugOptions.getBits()) {
164        EnableObjectCache = false;
165    }
166    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
167    IROutputFilename = IROutputFilenameOption.empty() ? nullptr : IROutputFilenameOption.data();
168    ASMOutputFilename = ASMOutputFilenameOption.empty() ? nullptr : ASMOutputFilenameOption.data();
169    Options = InitTargetOptionsFromCodeGenFlags();
170#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
171    Options.MCOptions.AsmVerbose = AsmVerbose;
172#endif
173    switch (OptLevelOption) {
174        case '0': OptLevel = CodeGenOpt::None; break;
175        case '1': OptLevel = CodeGenOpt::Less; break;
176        case '2': OptLevel = CodeGenOpt::Default; break;
177        case '3': OptLevel = CodeGenOpt::Aggressive; break;
178        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
179    }
180    #ifndef CUDA_ENABLED
181    if (NVPTX) {
182        report_fatal_error("CUDA compiler is not supported.");
183    }
184    #endif
185}
186
187}
188
189void printParabixVersion () {
190    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
191    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
192}
193
194void AddParabixVersionPrinter() {
195    cl::AddExtraVersionPrinter(&printParabixVersion);
196}
197
198bool AVX2_available() {
199    StringMap<bool> HostCPUFeatures;
200    if (sys::getHostCPUFeatures(HostCPUFeatures)) {
201        auto f = HostCPUFeatures.find("avx2");
202        return ((f != HostCPUFeatures.end()) && f->second);
203    }
204    return false;
205}
Note: See TracBrowser for help on using the repository browser.