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

Last change on this file since 5734 was 5734, checked in by cameron, 20 months ago

Some changes for LLVM 6.0.0

File size: 8.0 KB
RevLine 
[4801]1/*
[5734]2 *  Copyright (c) 2017 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>
[5656]8#include <UCD/UCD_Config.h>
[5464]9#include <llvm/CodeGen/CommandFlags.h>
10#include <llvm/Support/raw_ostream.h>
[5398]11
[5033]12using namespace llvm;
[4939]13
[5446]14#ifndef NDEBUG
15#define IN_DEBUG_MODE true
16#else
17#define IN_DEBUG_MODE false
18#endif
19
[5033]20namespace codegen {
[4939]21
[5033]22static cl::OptionCategory CodeGenOptions("Code Generation Options", "These options control code generation.");
[5347]23
[5295]24static cl::bits<DebugFlags>
[5454]25DebugOptions(cl::values(clEnumVal(ShowUnoptimizedIR, "Print generated LLVM IR."),
26                        clEnumVal(ShowIR, "Print optimized LLVM IR."),
[5444]27                        clEnumVal(VerifyIR, "Run the IR verification pass."),
[5731]28#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
[5295]29                        clEnumVal(ShowASM, "Print assembly code."),
30#endif
31                        clEnumVal(SerializeThreads, "Force segment threads to run sequentially."),
[5637]32                        clEnumVal(TraceCounts, "Show kernel processed and produced item counts."),
[5618]33                        clEnumVal(TraceDynamicBuffers, "Show dynamic buffer allocations and deallocations."),
[5721]34                        clEnumVal(EnableAsserts, "Enable built-in Parabix framework asserts in generated IR."),
[5732]35                        clEnumVal(EnableCycleCounter, "Count and report CPU cycles per kernel.")
36                        CL_ENUM_VAL_SENTINEL), cl::cat(CodeGenOptions));
[4939]37
[5616]38static cl::opt<std::string> IROutputFilenameOption("dump-generated-IR-output", cl::init(""),
[5464]39                                                       cl::desc("output IR filename"), cl::cat(CodeGenOptions));
40
[5731]41#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
[5616]42static cl::opt<std::string> ASMOutputFilenameOption("asm-output", cl::init(""),
[5464]43                                                    cl::desc("output ASM filename"), cl::cat(CodeGenOptions));
44
45static cl::opt<bool> AsmVerbose("asm-verbose", cl::init(true),
46                                cl::desc("Add comments to directives."), cl::cat(CodeGenOptions));
[5295]47#endif
[4939]48
[5464]49static cl::opt<char> OptLevelOption("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
50                                    cl::cat(CodeGenOptions), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
[4801]51
[4959]52
[5486]53static cl::opt<bool, true> EnableObjectCacheOption("enable-object-cache", cl::location(EnableObjectCache), cl::init(true),
54                                                   cl::desc("Enable object caching"), cl::cat(CodeGenOptions));
[4959]55
[5616]56static cl::opt<std::string> ObjectCacheDirOption("object-cache-dir", cl::init(""),
[5486]57                                                 cl::desc("Path to the object cache diretory"), cl::cat(CodeGenOptions));
[4959]58
[4801]59
[5464]60static cl::opt<int, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0),
61                                          cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
[4962]62
63
[5486]64static cl::opt<int, true> SegmentSizeOption("segment-size", cl::location(SegmentSize), cl::init(1),
65                                            cl::desc("Segment Size"), cl::value_desc("positive integer"));
[4962]66
[5464]67static cl::opt<int, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::init(1),
68                                               cl::desc("Buffer Segments"), cl::value_desc("positive integer"));
[5295]69
[5151]70
[5521]71static cl::opt<int, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::init(2),
[5464]72                                          cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"));
[5458]73
[4801]74
[5486]75static cl::opt<bool, true> pipelineParallelOption("enable-pipeline-parallel", cl::location(PipelineParallel), cl::init(false),
[5464]76                                                  cl::desc("Enable multithreading with pipeline parallelism."), cl::cat(CodeGenOptions));
77   
[5486]78static cl::opt<bool, true> segmentPipelineParallelOption("enable-segment-pipeline-parallel", cl::location(SegmentPipelineParallel),
[5464]79                                                         cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
[5373]80
[5486]81static cl::opt<bool, true> NVPTXOption("NVPTX", cl::location(NVPTX), cl::init(false),
82                                 cl::desc("Run on GPU only."), cl::cat(CodeGenOptions));
[5067]83
[5464]84static cl::opt<int, true> GroupNumOption("group-num", cl::location(GroupNum), cl::init(256),
[5486]85                                         cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::cat(CodeGenOptions));
[5108]86
[5486]87CodeGenOpt::Level OptLevel;
[5425]88
[5486]89bool PipelineParallel;
[5425]90
[5486]91bool SegmentPipelineParallel;
92
93const char * ASMOutputFilename;
94
95const char * IROutputFilename;
96
97const char * ObjectCacheDir;
98
[5464]99int BlockSize;
[5486]100
[5464]101int SegmentSize;
[5486]102
[5464]103int BufferSegments;
[5486]104
[5464]105int ThreadNum;
[5486]106
107bool EnableObjectCache;
108
109bool NVPTX = [](const bool nvptx) {
110    #ifndef CUDA_ENABLED
111    if (nvptx) {
112        report_fatal_error("CUDA compiler is not supported.");
113    }
114    #endif
115    return nvptx;
116}(NVPTXOption);
117
[5464]118int GroupNum;
[5425]119
[5464]120const llvm::Reloc::Model RelocModel = ::RelocModel;
[5486]121
[5464]122const llvm::CodeModel::Model CMModel = ::CMModel;
[5486]123
[5464]124const std::string MArch = ::MArch;
[5486]125
[5464]126const llvm::TargetMachine::CodeGenFileType FileType = ::FileType;
[5486]127
128TargetOptions Options;
129
[5464]130const cl::OptionCategory * codegen_flags() {
131    return &CodeGenOptions;
[5409]132}
133
[5464]134bool DebugOptionIsSet(const DebugFlags flag) {
[5721]135    if (IN_DEBUG_MODE && (flag == EnableAsserts)) return true;
[5464]136    return DebugOptions.isSet(flag);
[5409]137}
138
[5464]139std::string getCPUStr() {
140    return ::getCPUStr();
[5414]141}
[5409]142
[5464]143std::string getFeaturesStr() {
144    return ::getFeaturesStr();
[5391]145}
146
[5464]147void setFunctionAttributes(llvm::StringRef CPU, llvm::StringRef Features, llvm::Module &M) {
148    return ::setFunctionAttributes(CPU, Features, M);
[5414]149}
150
[5486]151std::string ProgramName;
[5391]152
[5486]153void ParseCommandLineOptions(int argc, const char * const *argv, std::initializer_list<const cl::OptionCategory *> hiding) {
154    AddParabixVersionPrinter();
155    codegen::ProgramName = argv[0];
[5731]156#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
[5486]157    if (hiding.size() != 0) {
158        cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *>(hiding));
159    }
[5731]160#endif
[5486]161    cl::ParseCommandLineOptions(argc, argv);
162    if (DebugOptions.getBits()) {
163        EnableObjectCache = false;
164    }
[5616]165    ObjectCacheDir = ObjectCacheDirOption.empty() ? nullptr : ObjectCacheDirOption.data();
166    IROutputFilename = IROutputFilenameOption.empty() ? nullptr : IROutputFilenameOption.data();
167    ASMOutputFilename = ASMOutputFilenameOption.empty() ? nullptr : ASMOutputFilenameOption.data();
[5486]168    Options = InitTargetOptionsFromCodeGenFlags();
[5731]169#if LLVM_VERSION_INTEGER >= LLVM_3_7_0
[5486]170    Options.MCOptions.AsmVerbose = AsmVerbose;
[5731]171#endif
[5486]172    switch (OptLevelOption) {
173        case '0': OptLevel = CodeGenOpt::None; break;
174        case '1': OptLevel = CodeGenOpt::Less; break;
175        case '2': OptLevel = CodeGenOpt::Default; break;
176        case '3': OptLevel = CodeGenOpt::Aggressive; break;
177        default: report_fatal_error(std::string(1, OptLevelOption) + " is an invalid optimization level.");
178    }
179    #ifndef CUDA_ENABLED
180    if (NVPTX) {
[5464]181        report_fatal_error("CUDA compiler is not supported.");
[5454]182    }
[5486]183    #endif
[5454]184}
185
[5486]186}
[5734]187#if LLVM_VERSION_INTEGER < LLVM_6_0_0
[5464]188void printParabixVersion () {
[5656]189    outs() << "Unicode version " << UCD::UnicodeVersion << "\n";
[5486]190    outs() << "Parabix (http://parabix.costar.sfu.ca/):\n  " << "Parabix revision " << PARABIX_VERSION << "\n";
[5436]191}
[5734]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
[5436]198
[5464]199void AddParabixVersionPrinter() {
200    cl::AddExtraVersionPrinter(&printParabixVersion);
[5391]201}
[5402]202
[5464]203bool AVX2_available() {
204    StringMap<bool> HostCPUFeatures;
205    if (sys::getHostCPUFeatures(HostCPUFeatures)) {
206        auto f = HostCPUFeatures.find("avx2");
207        return ((f != HostCPUFeatures.end()) && f->second);
208    }
209    return false;
[5402]210}
Note: See TracBrowser for help on using the repository browser.