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

Last change on this file since 6237 was 6228, checked in by nmedfort, 7 months ago

redesign of PopCount? calculation + mem leak fix

File size: 8.6 KB
Line 
1/*
2 *  Copyright (c) 2018 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 <pablo/pablo_toolchain.h>
9#include <UCD/UCD_Config.h>
10#include <llvm/Support/CommandLine.h>
11#include <llvm/Support/raw_ostream.h>
12#include <boost/interprocess/mapped_region.hpp>
13
14using namespace llvm;
15
16#ifndef NDEBUG
17#define IN_DEBUG_MODE true
18#else
19#define IN_DEBUG_MODE false
20#endif
21
22namespace codegen {
23   
24inline unsigned getPageSize() {
25    return boost::interprocess::mapped_region::get_page_size();
26}
27
28static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
29
30static cl::bits<DebugFlags>
31DebugOptions(cl::values(clEnumVal(VerifyIR, "Run the IR verification pass."),
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(EnableMProtect, "Use mprotect to cause a write fault when erroneously overwriting kernel state / stream space.\n"
37                                                  "NOTE: this requires memory to be page-aligned, which may still hide errors."),
38                        clEnumVal(EnableCycleCounter, "Count and report CPU cycles per kernel."),
39                        clEnumVal(DisableIndirectBranch, "Disable use of indirect branches in kernel code.")
40                        CL_ENUM_VAL_SENTINEL), cl::cat(CodeGenOptions));
41
42std::string ShowIROption = OmittedOption;
43static cl::opt<std::string, true> IROutputOption("ShowIR", cl::location(ShowIROption), cl::ValueOptional,
44                                                         cl::desc("Print optimized LLVM IR to stderr (by omitting =<filename>) or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
45
46std::string ShowUnoptimizedIROption = OmittedOption;
47static cl::opt<std::string, true> UnoptimizedIROutputOption("ShowUnoptimizedIR", cl::location(ShowUnoptimizedIROption), cl::ValueOptional,
48                                                         cl::desc("Print generated LLVM IR to stderr (by omitting =<filename> or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
49
50#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
51std::string ShowASMOption = OmittedOption;
52static cl::opt<std::string, true> ASMOutputFilenameOption("ShowASM", cl::location(ShowASMOption), cl::ValueOptional,
53                                                         cl::desc("Print generated assembly code to stderr (by omitting =<filename> or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
54#endif
55
56static cl::opt<char> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
57                                    cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
58
59
60static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
61                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
62
63static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
64                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
65
66
67static cl::opt<unsigned, true> CacheLimitOption("cache-days-limit", cl::location(CacheDaysLimit), cl::init(15),
68                                          cl::desc("number of days a cache entry may be unused before auto deletion may be applied"), cl::cat(CodeGenOptions));
69
70
71static cl::opt<unsigned, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
72                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
73
74
75static cl::opt<unsigned, true> SegmentSizeOption("segment-size", cl::location(SegmentSize),
76                                               cl::init(getPageSize()),
77                                               cl::desc("Expected amount of input data to process per segment"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
78
79static cl::opt<unsigned, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
80                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
81
82
83static cl::opt<unsigned, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
84                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
85
86
87static cl::opt<bool, true> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel), cl::init(false),
88                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
89
90static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
91                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
92
93static cl::opt<unsigned, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
94                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
95
96std::string TraceOption = "";
97static cl::opt<std::string, true> TraceValueOption("trace", cl::location(TraceOption),
98                                            cl::desc("Instrument programs to trace values beginning prefix"), cl::value_desc("prefix"), cl::cat(CodeGenOptions));
99
100CodeGenOpt::Level OptLevel;
101
102bool SegmentPipelineParallel;
103
104const char * ObjectCacheDir;
105
106unsigned BlockSize;
107
108unsigned SegmentSize;
109
110unsigned BufferSegments;
111
112unsigned ThreadNum;
113
114bool EnableObjectCache;
115
116unsigned CacheDaysLimit;
117
118bool NVPTX = [](const bool nvptx) {
119    #ifndef CUDA_ENABLED
120    if (nvptx) {
121        report_fatal_error("CUDA compiler is not supported.");
122    }
123    #endif
124    return nvptx;
125}(NVPTXOption);
126
127unsigned GroupNum;
128
129TargetOptions target_Options;
130
131const cl::OptionCategory * LLVM_READONLY codegen_flags() {
132    return &CodeGenOptions;
133}
134
135bool LLVM_READONLY DebugOptionIsSet(const DebugFlags flag) {
136    return DebugOptions.isSet(flag);
137}
138
139
140std::string ProgramName;
141
142void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
143    AddParabixVersionPrinter();
144    codegen::ProgramName = argv[0];
145#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
146    if (hiding.size() != 0) {
147        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
148    }
149#endif
150    cl::ParseCommandLineOptions(argc, argv);
151    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption)
152        #if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
153        || (ShowASMOption != OmittedOption)
154        #endif
155        || (pablo::ShowPabloOption != OmittedOption) || (pablo::ShowOptimizedPabloOption != OmittedOption)) {
156        EnableObjectCache = false;
157    }
158    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
159#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
160    target_Options.MCOptions.AsmVerbose = true;
161#endif
162    switch (OptLevelOption) {
163        case '0': OptLevel = CodeGenOpt::None; break;
164        case '1': OptLevel = CodeGenOpt::Less; break;
165        case '2': OptLevel = CodeGenOpt::Default; break;
166        case '3': OptLevel = CodeGenOpt::Aggressive; break;
167        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
168    }
169#ifndef CUDA_ENABLED
170    if (NVPTX) {
171        report_fatal_error("CUDA compiler is not supported.");
172    }
173#endif
174}
175
176#if LLVM_VERSION_INTEGER < LLVM_VERSION_CODE(6, 0, 0)
177void printParabixVersion () {
178    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
179    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
180}
181#else
182void printParabixVersion (raw_ostream & outs) {
183    outs << "Unicode version " << UCD::UnicodeVersion << "\n";
184    outs << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
185}
186#endif
187
188void AddParabixVersionPrinter() {
189    cl::AddExtraVersionPrinter(&printParabixVersion);
190}
191
192}
Note: See TracBrowser for help on using the repository browser.