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

Last change on this file since 6285 was 6285, checked in by cameron, 4 months ago

-enable-cache-trace flag; base64 encoding for property kernels.

File size: 9.1 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<bool, true> TraceObjectCacheOption("trace-object-cache", cl::location(TraceObjectCache), cl::init(false),
64                                                   cl::desc("Trace object cache retrieval."), cl::cat(CodeGenOptions));
65
66static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
67                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
68
69
70static cl::opt<unsigned, true> CacheLimitOption("cache-days-limit", cl::location(CacheDaysLimit), cl::init(15),
71                                          cl::desc("number of days a cache entry may be unused before auto deletion may be applied"), cl::cat(CodeGenOptions));
72
73
74static cl::opt<unsigned, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
75                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
76
77
78static cl::opt<unsigned, true> SegmentSizeOption("segment-size", cl::location(SegmentSize),
79                                               cl::init(getPageSize()),
80                                               cl::desc("Expected amount of input data to process per segment"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
81
82static cl::opt<unsigned, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
83                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
84
85
86static cl::opt<unsigned, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
87                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
88
89
90static cl::opt<bool, true> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel), cl::init(false),
91                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
92
93static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
94                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
95
96static cl::opt<unsigned, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
97                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
98
99std::string TraceOption = "";
100static cl::opt<std::string, true> TraceValueOption("trace", cl::location(TraceOption),
101                                            cl::desc("Instrument programs to trace values beginning prefix"), cl::value_desc("prefix"), cl::cat(CodeGenOptions));
102
103CodeGenOpt::Level OptLevel;
104
105bool SegmentPipelineParallel;
106
107const char * ObjectCacheDir;
108
109unsigned BlockSize;
110
111unsigned SegmentSize;
112
113unsigned BufferSegments;
114
115unsigned ThreadNum;
116
117bool EnableObjectCache;
118bool TraceObjectCache;
119
120unsigned CacheDaysLimit;
121
122bool NVPTX = [](const bool nvptx) {
123    #ifndef CUDA_ENABLED
124    if (nvptx) {
125        report_fatal_error("CUDA compiler is not supported.");
126    }
127    #endif
128    return nvptx;
129}(NVPTXOption);
130
131unsigned GroupNum;
132
133TargetOptions target_Options;
134
135const cl::OptionCategory * LLVM_READONLY codegen_flags() {
136    return &CodeGenOptions;
137}
138
139bool LLVM_READONLY DebugOptionIsSet(const DebugFlags flag) {
140    return DebugOptions.isSet(flag);
141}
142
143
144std::string ProgramName;
145
146void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
147    AddParabixVersionPrinter();
148    codegen::ProgramName = argv[0];
149#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
150    if (hiding.size() != 0) {
151        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
152    }
153#endif
154    cl::ParseCommandLineOptions(argc, argv);
155    if (!TraceOption.empty()) {
156        EnableObjectCache = false;
157        // Maybe we need to force generation of names.
158        //if (ShowIROption == OmittedOption) {
159            // ShowIROption = "/dev/null";
160        //}
161    }
162    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption)
163        #if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
164        || (ShowASMOption != OmittedOption)
165        #endif
166        || (pablo::ShowPabloOption != OmittedOption) || (pablo::ShowOptimizedPabloOption != OmittedOption)) {
167        EnableObjectCache = false;
168    }
169    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
170#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
171    target_Options.MCOptions.AsmVerbose = true;
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#if LLVM_VERSION_INTEGER < LLVM_VERSION_CODE(6, 0, 0)
188void printParabixVersion () {
189    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
190    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
191}
192#else
193void printParabixVersion (raw_ostream & outs) {
194    outs << "Unicode version " << UCD::UnicodeVersion << "\n";
195    outs << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
196}
197#endif
198
199void AddParabixVersionPrinter() {
200    cl::AddExtraVersionPrinter(&printParabixVersion);
201}
202
203}
Note: See TracBrowser for help on using the repository browser.