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

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

Initial version of PipelineKernel? + revised StreamSet? model.

File size: 8.2 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
96CodeGenOpt::Level OptLevel;
97
98bool SegmentPipelineParallel;
99
100const char * ObjectCacheDir;
101
102unsigned BlockSize;
103
104unsigned SegmentSize;
105
106unsigned BufferSegments;
107
108unsigned ThreadNum;
109
110bool EnableObjectCache;
111
112unsigned CacheDaysLimit;
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
123unsigned GroupNum;
124
125TargetOptions target_Options;
126
127const cl::OptionCategory * LLVM_READONLY codegen_flags() {
128    return &CodeGenOptions;
129}
130
131bool LLVM_READONLY DebugOptionIsSet(const DebugFlags flag) {
132    return DebugOptions.isSet(flag);
133}
134
135
136std::string ProgramName;
137
138void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
139    AddParabixVersionPrinter();
140    codegen::ProgramName = argv[0];
141#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
142    if (hiding.size() != 0) {
143        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
144    }
145#endif
146    cl::ParseCommandLineOptions(argc, argv);
147    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption) || (ShowASMOption != OmittedOption)
148        || (pablo::ShowPabloOption != OmittedOption) || (pablo::ShowOptimizedPabloOption != OmittedOption)) {
149        EnableObjectCache = false;
150    }
151    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
152#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
153    target_Options.MCOptions.AsmVerbose = true;
154#endif
155    switch (OptLevelOption) {
156        case '0': OptLevel = CodeGenOpt::None; break;
157        case '1': OptLevel = CodeGenOpt::Less; break;
158        case '2': OptLevel = CodeGenOpt::Default; break;
159        case '3': OptLevel = CodeGenOpt::Aggressive; break;
160        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
161    }
162#ifndef CUDA_ENABLED
163    if (NVPTX) {
164        report_fatal_error("CUDA compiler is not supported.");
165    }
166#endif
167}
168
169#if LLVM_VERSION_INTEGER < LLVM_VERSION_CODE(6, 0, 0)
170void printParabixVersion () {
171    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
172    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
173}
174#else
175void printParabixVersion (raw_ostream & outs) {
176    outs << "Unicode version " << UCD::UnicodeVersion << "\n";
177    outs << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
178}
179#endif
180
181void AddParabixVersionPrinter() {
182    cl::AddExtraVersionPrinter(&printParabixVersion);
183}
184
185}
Note: See TracBrowser for help on using the repository browser.