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

Last change on this file since 5637 was 5637, checked in by cameron, 21 months ago

Trace option for produced, processed, consumed item counts

File size: 7.9 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                        clEnumVal(TraceCounts, "Show kernel processed and produced item counts."),
32                        clEnumVal(TraceDynamicBuffers, "Show dynamic buffer allocations and deallocations."),
33                        clEnumValEnd), cl::cat(CodeGenOptions));
34
35static cl::opt<std::string> IROutputFilenameOption("dump-generated-IR-output", cl::init(""),
36                                                       cl::desc("output IR filename"), cl::cat(CodeGenOptions));
37
38#ifndef USE_LLVM_3_6
39static cl::opt<std::string> ASMOutputFilenameOption("asm-output", cl::init(""),
40                                                    cl::desc("output ASM filename"), cl::cat(CodeGenOptions));
41
42static cl::opt<bool> AsmVerbose("asm-verbose", cl::init(true),
43                                cl::desc("Add comments to directives."), cl::cat(CodeGenOptions));
44#endif
45
46static cl::opt<char> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
47                                    cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
48
49
50static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
51                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
52
53static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
54                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
55
56
57static cl::opt<int, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
58                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
59
60
61static cl::opt<int, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(1),
62                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
63
64static cl::opt<int, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
65                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
66
67
68static cl::opt<int, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
69                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
70
71
72static cl::opt<bool, true> EnableAssertsOption("ea", cl::location(EnableAsserts), cl::init(IN_DEBUG_MODE),
73                                               cl::desc("Enable Asserts"), cl::cat(CodeGenOptions));
74
75static cl::opt<bool, true> EnableCycleCountOption("ShowKernelCycles", cl::location(EnableCycleCounter), cl::init(false),
76                                             cl::desc("Count and report CPU cycles per kernel"), cl::cat(CodeGenOptions));
77
78static cl::opt<bool, true> pipelineParallelOption("enable-pipeline-parallel", cl::location(PipelineParallel), cl::init(false),
79                                                  cl::desc("Enable multithreading with pipeline parallelism."), cl::cat(CodeGenOptions));
80   
81static cl::opt<bool, true> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel),
82                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
83
84static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
85                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
86
87static cl::opt<int, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
88                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
89
90CodeGenOpt::Level OptLevel;
91
92bool PipelineParallel;
93
94bool SegmentPipelineParallel;
95
96const char * ASMOutputFilename;
97
98const char * IROutputFilename;
99
100const char * ObjectCacheDir;
101
102int BlockSize;
103
104int SegmentSize;
105
106int BufferSegments;
107
108int ThreadNum;
109
110bool EnableAsserts;
111
112bool EnableCycleCounter;
113
114bool EnableObjectCache;
115
116bool NVPTX = [](const bool nvptx) {
117    #ifndef CUDA_ENABLED
118    if (nvptx) {
119        report_fatal_error("CUDA compiler is not supported.");
120    }
121    #endif
122    return nvptx;
123}(NVPTXOption);
124
125int GroupNum;
126
127const llvm::Reloc::Model RelocModel = ::RelocModel;
128
129const llvm::CodeModel::Model CMModel = ::CMModel;
130
131const std::string MArch = ::MArch;
132
133const std::string RunPass = ::RunPass;
134
135const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
136
137const std::string StopAfter = ::StopAfter;
138
139const std::string StartAfter = ::StartAfter;
140
141TargetOptions Options;
142
143const cl::OptionCategory * codegen_flags() {
144    return &CodeGenOptions;
145}
146
147bool DebugOptionIsSet(const DebugFlags flag) {
148    return DebugOptions.isSet(flag);
149}
150
151std::string getCPUStr() {
152    return ::getCPUStr();
153}
154
155std::string getFeaturesStr() {
156    return ::getFeaturesStr();
157}
158
159void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
160    return ::setFunctionAttributes(CPU, Features, M);
161}
162
163std::string ProgramName;
164
165void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
166    AddParabixVersionPrinter();
167    codegen::ProgramName = argv[0];
168    #ifndef USE_LLVM_3_6
169    if (hiding.size() != 0) {
170        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
171    }
172    #endif
173    cl::ParseCommandLineOptions(argc, argv);
174    if (DebugOptions.getBits()) {
175        EnableObjectCache = false;
176    }
177    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
178    IROutputFilename = IROutputFilenameOption.empty() ? nullptr : IROutputFilenameOption.data();
179    ASMOutputFilename = ASMOutputFilenameOption.empty() ? nullptr : ASMOutputFilenameOption.data();
180    Options = InitTargetOptionsFromCodeGenFlags();
181    #ifndef USE_LLVM_3_6
182    Options.MCOptions.AsmVerbose = AsmVerbose;
183    #endif
184    switch (OptLevelOption) {
185        case '0': OptLevel = CodeGenOpt::None; break;
186        case '1': OptLevel = CodeGenOpt::Less; break;
187        case '2': OptLevel = CodeGenOpt::Default; break;
188        case '3': OptLevel = CodeGenOpt::Aggressive; break;
189        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
190    }
191    #ifndef CUDA_ENABLED
192    if (NVPTX) {
193        report_fatal_error("CUDA compiler is not supported.");
194    }
195    #endif
196}
197
198}
199
200void printParabixVersion () {
201    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
202}
203
204void AddParabixVersionPrinter() {
205    cl::AddExtraVersionPrinter(&printParabixVersion);
206}
207
208bool AVX2_available() {
209    StringMap<bool> HostCPUFeatures;
210    if (sys::getHostCPUFeatures(HostCPUFeatures)) {
211        auto f = HostCPUFeatures.find("avx2");
212        return ((f != HostCPUFeatures.end()) && f->second);
213    }
214    return false;
215}
Note: See TracBrowser for help on using the repository browser.