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

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

Auto RE grouping/threading

File size: 8.2 KB
RevLine 
[4801]1/*
[5930]2 *  Copyright (c) 2018 International Characters.
[4801]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
[5464]7#include <toolchain/toolchain.h>
[5840]8#include <pablo/pablo_toolchain.h>
[5656]9#include <UCD/UCD_Config.h>
[5464]10#include <llvm/CodeGen/CommandFlags.h>
11#include <llvm/Support/raw_ostream.h>
[5398]12
[5033]13using namespace llvm;
[4939]14
[5446]15#ifndef NDEBUG
16#define IN_DEBUG_MODE true
17#else
18#define IN_DEBUG_MODE false
19#endif
20
[5033]21namespace codegen {
[4939]22
[5930]23const unsigned DEFAULT_SEGMENT_SIZE = 64;
24   
[5033]25static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
[5347]26
[5295]27static cl::bits<DebugFlags>
[5745]28DebugOptions(cl::values(clEnumVal(VerifyIR, "Run the IR verification pass."),
[5295]29                        clEnumVal(SerializeThreads, "Force segment threads to run sequentially."),
[5637]30                        clEnumVal(TraceCounts, "Show kernel processed and produced item counts."),
[5618]31                        clEnumVal(TraceDynamicBuffers, "Show dynamic buffer allocations and deallocations."),
[5721]32                        clEnumVal(EnableAsserts, "Enable built-in Parabix framework asserts in generated IR."),
[5746]33                        clEnumVal(EnableCycleCounter, "Count and report CPU cycles per kernel."),
34                        clEnumVal(DisableIndirectBranch, "Disable use of indirect branches in kernel code.")
[5732]35                        CL_ENUM_VAL_SENTINEL), cl::cat(CodeGenOptions));
[4939]36
[5745]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));
[5464]40
[5745]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
[5841]45#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
[5745]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));
[5295]49#endif
[4939]50
[5464]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'));
[4801]53
[4959]54
[5486]55static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
56                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
[4959]57
[5616]58static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
[5486]59                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
[4959]60
[4801]61
[5773]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
[5757]66static cl::opt<unsigned, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
[5464]67                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
[4962]68
69
[5930]70static cl::opt<unsigned, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(DEFAULT_SEGMENT_SIZE),
[5486]71                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
[4962]72
[5757]73static cl::opt<unsigned, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
[5464]74                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
[5295]75
[5151]76
[5757]77static cl::opt<unsigned, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
[5464]78                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
[5458]79
[4801]80
[5486]81static cl::opt<bool, true> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel),
[5464]82                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
[5373]83
[5486]84static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
85                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
[5067]86
[5757]87static cl::opt<unsigned, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
[5486]88                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
[5108]89
[5486]90CodeGenOpt::Level OptLevel;
[5425]91
[5486]92bool SegmentPipelineParallel;
93
94const char * ObjectCacheDir;
95
[5757]96unsigned BlockSize;
[5486]97
[5757]98unsigned SegmentSize;
[5486]99
[5757]100unsigned BufferSegments;
[5486]101
[5757]102unsigned ThreadNum;
[5486]103
104bool EnableObjectCache;
105
[5773]106unsigned CacheDaysLimit;
107
[5486]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
[5757]117unsigned GroupNum;
[5425]118
[5464]119const llvm::Reloc::Model RelocModel = ::RelocModel;
[5486]120
[5464]121const llvm::CodeModel::Model CMModel = ::CMModel;
[5486]122
[5464]123const std::string MArch = ::MArch;
[5486]124
[5464]125const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
[5486]126
127TargetOptions Options;
128
[5771]129const cl::OptionCategory * LLVM_READONLY codegen_flags() {
[5464]130    return &CodeGenOptions;
[5409]131}
132
[5771]133bool LLVM_READONLY DebugOptionIsSet(const DebugFlags flag) {
[5464]134    return DebugOptions.isSet(flag);
[5409]135}
136
[5464]137std::string getCPUStr() {
138    return ::getCPUStr();
[5414]139}
[5409]140
[5464]141std::string getFeaturesStr() {
142    return ::getFeaturesStr();
[5391]143}
144
[5464]145void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
146    return ::setFunctionAttributes(CPU, Features, M);
[5414]147}
148
[5486]149std::string ProgramName;
[5391]150
[5486]151void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
152    AddParabixVersionPrinter();
153    codegen::ProgramName = argv[0];
[5841]154#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
[5486]155    if (hiding.size() != 0) {
156        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
157    }
[5731]158#endif
[5486]159    cl::ParseCommandLineOptions(argc, argv);
[5840]160    if (DebugOptions.getBits() || (ShowIROption != OmittedOption) || (ShowUnoptimizedIROption != OmittedOption) || (ShowASMOption != OmittedOption)
161        || (pablo::ShowPabloOption != OmittedOption) || (pablo::ShowOptimizedPabloOption != OmittedOption)) {
[5486]162        EnableObjectCache = false;
163    }
[5616]164    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
[5486]165    Options = InitTargetOptionsFromCodeGenFlags();
[5841]166#if LLVM_VERSION_INTEGER >= LLVM_VERSION_CODE(3, 7, 0)
[5745]167    Options.MCOptions.AsmVerbose = true;
[5731]168#endif
[5486]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    }
[5735]176#ifndef CUDA_ENABLED
[5486]177    if (NVPTX) {
[5464]178        report_fatal_error("CUDA compiler is not supported.");
[5454]179    }
[5735]180#endif
[5454]181}
182
[5486]183}
[5841]184#if LLVM_VERSION_INTEGER < LLVM_VERSION_CODE(6, 0, 0)
[5464]185void printParabixVersion () {
[5656]186    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
[5486]187    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
[5436]188}
[5734]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
[5436]195
[5464]196void AddParabixVersionPrinter() {
197    cl::AddExtraVersionPrinter(&printParabixVersion);
[5391]198}
Note: See TracBrowser for help on using the repository browser.