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

Last change on this file since 5486 was 5486, checked in by nmedfort, 2 years ago

Initial attempt to improve debugging capabilities with compilation stack traces on error.

File size: 7.6 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#include <llvm/CodeGen/CommandFlags.h>
9#include <llvm/Support/raw_ostream.h>
10
11using namespace llvm;
12
13#ifndef NDEBUG
14#define IN_DEBUG_MODE true
15#else
16#define IN_DEBUG_MODE false
17#endif
18
19namespace codegen {
20
21static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
22
23static cl::bits<DebugFlags>
24DebugOptions(cl::values(clEnumVal(ShowUnoptimizedIR, "Print generated LLVM IR."),
25                        clEnumVal(ShowIR, "Print optimized LLVM IR."),
26                        clEnumVal(VerifyIR, "Run the IR verification pass."),
27#ifndef USE_LLVM_3_6
28                        clEnumVal(ShowASM, "Print assembly code."),
29#endif
30                        clEnumVal(SerializeThreads, "Force segment threads to run sequentially."),
31                        clEnumValEnd), cl::cat(CodeGenOptions));
32
33static cl::opt<const char *> IROutputFilenameOption("dump-generated-IR-output", cl::init(nullptr),
34                                                       cl::desc("output IR filename"), cl::cat(CodeGenOptions));
35
36#ifndef USE_LLVM_3_6
37static cl::opt<const char *> ASMOutputFilenameOption("asm-output", cl::init(nullptr),
38                                                    cl::desc("output ASM filename"), cl::cat(CodeGenOptions));
39
40static cl::opt<bool> AsmVerbose("asm-verbose", cl::init(true),
41                                cl::desc("Add comments to directives."), cl::cat(CodeGenOptions));
42#endif
43
44static cl::opt<char> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
45                                    cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
46
47
48static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
49                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
50
51static cl::opt<const char *> ObjectCacheDirOption("object-cache-dir", cl::init(nullptr),
52                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
53
54
55static cl::opt<int, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
56                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
57
58
59static cl::opt<int, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(1),
60                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
61
62static cl::opt<int, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
63                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
64
65
66static cl::opt<int> ThreadNumOption("thread-num", cl::init(2),
67                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
68
69
70static cl::opt<bool, true> EnableAssertsOption("ea", cl::location(EnableAsserts), cl::init(IN_DEBUG_MODE),
71                                               cl::desc("Enable Asserts"), cl::cat(CodeGenOptions));
72
73static cl::opt<bool, true> EnableCycleCountOption("ShowKernelCycles", cl::location(EnableCycleCounter), cl::init(false),
74                                             cl::desc("Count and report CPU cycles per kernel"), cl::cat(CodeGenOptions));
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 EnableAsserts;
109
110bool EnableCycleCounter;
111
112bool EnableObjectCache;
113
114bool NVPTX = [](const bool nvptx) {
115    #ifndef CUDA_ENABLED
116    if (nvptx) {
117        report_fatal_error("CUDA compiler is not supported.");
118    }
119    #endif
120    return nvptx;
121}(NVPTXOption);
122
123int GroupNum;
124
125const llvm::Reloc::Model RelocModel = ::RelocModel;
126
127const llvm::CodeModel::Model CMModel = ::CMModel;
128
129const std::string MArch = ::MArch;
130
131const std::string RunPass = ::RunPass;
132
133const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
134
135const std::string StopAfter = ::StopAfter;
136
137const std::string StartAfter = ::StartAfter;
138
139TargetOptions Options;
140
141const cl::OptionCategory * codegen_flags() {
142    return &CodeGenOptions;
143}
144
145bool DebugOptionIsSet(const DebugFlags flag) {
146    return DebugOptions.isSet(flag);
147}
148
149std::string getCPUStr() {
150    return ::getCPUStr();
151}
152
153std::string getFeaturesStr() {
154    return ::getFeaturesStr();
155}
156
157void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
158    return ::setFunctionAttributes(CPU, Features, M);
159}
160
161std::string ProgramName;
162
163void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
164    AddParabixVersionPrinter();
165    codegen::ProgramName = argv[0];
166    #ifndef USE_LLVM_3_6
167    if (hiding.size() != 0) {
168        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
169    }
170    #endif
171    cl::ParseCommandLineOptions(argc, argv);
172    if (DebugOptions.getBits()) {
173        EnableObjectCache = false;
174    }
175
176    ThreadNum = (PipelineParallel || SegmentPipelineParallel) ? 2 : 1;
177
178    ObjectCacheDir = ObjectCacheDirOption;
179    IROutputFilename = IROutputFilenameOption;
180    ObjectCacheDir = ObjectCacheDirOption;
181    Options = InitTargetOptionsFromCodeGenFlags();
182    #ifndef USE_LLVM_3_6
183    Options.MCOptions.AsmVerbose = AsmVerbose;
184    #endif
185    switch (OptLevelOption) {
186        case '0': OptLevel = CodeGenOpt::None; break;
187        case '1': OptLevel = CodeGenOpt::Less; break;
188        case '2': OptLevel = CodeGenOpt::Default; break;
189        case '3': OptLevel = CodeGenOpt::Aggressive; break;
190        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
191    }
192    #ifndef CUDA_ENABLED
193    if (NVPTX) {
194        report_fatal_error("CUDA compiler is not supported.");
195    }
196    #endif
197}
198
199}
200
201void printParabixVersion () {
202    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
203}
204
205void AddParabixVersionPrinter() {
206    cl::AddExtraVersionPrinter(&printParabixVersion);
207}
208
209bool AVX2_available() {
210    StringMap<bool> HostCPUFeatures;
211    if (sys::getHostCPUFeatures(HostCPUFeatures)) {
212        auto f = HostCPUFeatures.find("avx2");
213        return ((f != HostCPUFeatures.end()) && f->second);
214    }
215    return false;
216}
Note: See TracBrowser for help on using the repository browser.