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

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

Bug fixes for IR/ASM writing

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#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<std::string> IROutputFilenameOption("dump-generated-IR-output", cl::init(""),
34                                                       cl::desc("output IR filename"), cl::cat(CodeGenOptions));
35
36#ifndef USE_LLVM_3_6
37static cl::opt<std::string> ASMOutputFilenameOption("asm-output", cl::init(""),
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<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
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, true> ThreadNumOption("thread-num", cl::location(ThreadNum), 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    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
176    IROutputFilename = IROutputFilenameOption.empty() ? nullptr : IROutputFilenameOption.data();
177    ASMOutputFilename = ASMOutputFilenameOption.empty() ? nullptr : ASMOutputFilenameOption.data();
178    Options = InitTargetOptionsFromCodeGenFlags();
179    #ifndef USE_LLVM_3_6
180    Options.MCOptions.AsmVerbose = AsmVerbose;
181    #endif
182    switch (OptLevelOption) {
183        case '0': OptLevel = CodeGenOpt::None; break;
184        case '1': OptLevel = CodeGenOpt::Less; break;
185        case '2': OptLevel = CodeGenOpt::Default; break;
186        case '3': OptLevel = CodeGenOpt::Aggressive; break;
187        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
188    }
189    #ifndef CUDA_ENABLED
190    if (NVPTX) {
191        report_fatal_error("CUDA compiler is not supported.");
192    }
193    #endif
194}
195
196}
197
198void printParabixVersion () {
199    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
200}
201
202void AddParabixVersionPrinter() {
203    cl::AddExtraVersionPrinter(&printParabixVersion);
204}
205
206bool AVX2_available() {
207    StringMap<bool> HostCPUFeatures;
208    if (sys::getHostCPUFeatures(HostCPUFeatures)) {
209        auto f = HostCPUFeatures.find("avx2");
210        return ((f != HostCPUFeatures.end()) && f->second);
211    }
212    return false;
213}
Note: See TracBrowser for help on using the repository browser.