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

Last change on this file since 5994 was 5930, checked in by cameron, 18 months ago

Auto RE grouping/threading

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/CodeGen/CommandFlags.h>
11#include <llvm/Support/raw_ostream.h>
12
13using namespace llvm;
14
15#ifndef NDEBUG
16#define IN_DEBUG_MODE true
17#else
18#define IN_DEBUG_MODE false
19#endif
20
21namespace codegen {
22
23const unsigned DEFAULT_SEGMENT_SIZE = 64;
24   
25static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
26
27static cl::bits<DebugFlags>
28DebugOptions(cl::values(clEnumVal(VerifyIR, "Run the IR verification pass."),
29                        clEnumVal(SerializeThreads, "Force segment threads to run sequentially."),
30                        clEnumVal(TraceCounts, "Show kernel processed and produced item counts."),
31                        clEnumVal(TraceDynamicBuffers, "Show dynamic buffer allocations and deallocations."),
32                        clEnumVal(EnableAsserts, "Enable built-in Parabix framework asserts in generated IR."),
33                        clEnumVal(EnableCycleCounter, "Count and report CPU cycles per kernel."),
34                        clEnumVal(DisableIndirectBranch, "Disable use of indirect branches in kernel code.")
35                        CL_ENUM_VAL_SENTINEL), cl::cat(CodeGenOptions));
36
37std::string ShowIROption = OmittedOption;
38static cl::opt<std::string, true> IROutputOption("ShowIR", cl::location(ShowIROption), cl::ValueOptional,
39                                                         cl::desc("Print optimized LLVM IR to stderr (by omitting =<filename>) or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
40
41std::string ShowUnoptimizedIROption = OmittedOption;
42static cl::opt<std::string, true> UnoptimizedIROutputOption("ShowUnoptimizedIR", cl::location(ShowUnoptimizedIROption), cl::ValueOptional,
43                                                         cl::desc("Print generated LLVM IR to stderr (by omitting =<filename> or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
44
45#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
46std::string ShowASMOption = OmittedOption;
47static cl::opt<std::string, true> ASMOutputFilenameOption("ShowASM", cl::location(ShowASMOption), cl::ValueOptional,
48                                                         cl::desc("Print generated assembly code to stderr (by omitting =<filename> or a file"), cl::value_desc("filename"), cl::cat(CodeGenOptions));
49#endif
50
51static cl::opt<char> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
52                                    cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
53
54
55static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
56                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
57
58static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
59                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
60
61
62static cl::opt<unsigned, true> CacheLimitOption("cache-days-limit", cl::location(CacheDaysLimit), cl::init(15),
63                                          cl::desc("number of days a cache entry may be unused before auto deletion may be applied"), cl::cat(CodeGenOptions));
64
65
66static cl::opt<unsigned, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
67                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
68
69
70static cl::opt<unsigned, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(DEFAULT_SEGMENT_SIZE),
71                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
72
73static cl::opt<unsigned, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
74                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
75
76
77static cl::opt<unsigned, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
78                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
79
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<unsigned, 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 SegmentPipelineParallel;
93
94const char * ObjectCacheDir;
95
96unsigned BlockSize;
97
98unsigned SegmentSize;
99
100unsigned BufferSegments;
101
102unsigned ThreadNum;
103
104bool EnableObjectCache;
105
106unsigned CacheDaysLimit;
107
108bool NVPTX = [](const bool nvptx) {
109    #ifndef CUDA_ENABLED
110    if (nvptx) {
111        report_fatal_error("CUDA compiler is not supported.");
112    }
113    #endif
114    return nvptx;
115}(NVPTXOption);
116
117unsigned GroupNum;
118
119const llvm::Reloc::Model RelocModel = ::RelocModel;
120
121const llvm::CodeModel::Model CMModel = ::CMModel;
122
123const std::string MArch = ::MArch;
124
125const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
126
127TargetOptions Options;
128
129const cl::OptionCategory * LLVM_READONLY codegen_flags() {
130    return &CodeGenOptions;
131}
132
133bool LLVM_READONLY DebugOptionIsSet(const DebugFlags flag) {
134    return DebugOptions.isSet(flag);
135}
136
137std::string getCPUStr() {
138    return ::getCPUStr();
139}
140
141std::string getFeaturesStr() {
142    return ::getFeaturesStr();
143}
144
145void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
146    return ::setFunctionAttributes(CPU, Features, M);
147}
148
149std::string ProgramName;
150
151void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
152    AddParabixVersionPrinter();
153    codegen::ProgramName = argv[0];
154#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
155    if (hiding.size() != 0) {
156        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
157    }
158#endif
159    cl::ParseCommandLineOptions(argc, argv);
160    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption) || (ShowASMOption != OmittedOption)
161        || (pablo::ShowPabloOption != OmittedOption) || (pablo::ShowOptimizedPabloOption != OmittedOption)) {
162        EnableObjectCache = false;
163    }
164    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
165    Options = InitTargetOptionsFromCodeGenFlags();
166#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
167    Options.MCOptions.AsmVerbose = true;
168#endif
169    switch (OptLevelOption) {
170        case '0': OptLevel = CodeGenOpt::None; break;
171        case '1': OptLevel = CodeGenOpt::Less; break;
172        case '2': OptLevel = CodeGenOpt::Default; break;
173        case '3': OptLevel = CodeGenOpt::Aggressive; break;
174        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
175    }
176#ifndef CUDA_ENABLED
177    if (NVPTX) {
178        report_fatal_error("CUDA compiler is not supported.");
179    }
180#endif
181}
182
183}
184#if LLVM_VERSION_INTEGER < LLVM_VERSION_CODE(6, 0, 0)
185void printParabixVersion () {
186    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
187    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
188}
189#else
190void printParabixVersion (raw_ostream & outs) {
191    outs << "Unicode version " << UCD::UnicodeVersion << "\n";
192    outs << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
193}
194#endif
195
196void AddParabixVersionPrinter() {
197    cl::AddExtraVersionPrinter(&printParabixVersion);
198}
Note: See TracBrowser for help on using the repository browser.