mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +03:00
Raise min LLVM version to 3.9 (#2872)
This commit is contained in:
parent
18bbaa1895
commit
5c24f60cf9
77 changed files with 83 additions and 4146 deletions
16
.travis.yml
16
.travis.yml
|
@ -10,22 +10,16 @@ matrix:
|
|||
# env: LLVM_VERSION=7.0.0 OPTS="-DBUILD_SHARED_LIBS=ON"
|
||||
- os: linux
|
||||
d: ldc-beta
|
||||
env: LLVM_VERSION=6.0.1 OPTS="-DBUILD_SHARED_LIBS=OFF"
|
||||
env: LLVM_VERSION=6.0.1 OPTS="-DBUILD_SHARED_LIBS=OFF -DLIB_SUFFIX=64"
|
||||
- os: linux
|
||||
d: ldc
|
||||
env: LLVM_VERSION=5.0.2
|
||||
- os: linux
|
||||
d: ldc-beta
|
||||
env: LLVM_VERSION=4.0.1 OPTS="-DBUILD_SHARED_LIBS=ON -DLIB_SUFFIX=64"
|
||||
- os: linux
|
||||
d: ldc
|
||||
env: LLVM_VERSION=3.9.1 OPTS="-DBUILD_SHARED_LIBS=OFF -DLIB_SUFFIX=64"
|
||||
env: LLVM_VERSION=5.0.2 OPTS="-DBUILD_SHARED_LIBS=ON -DLIB_SUFFIX=64"
|
||||
- os: linux
|
||||
d: ldc-0.17.6
|
||||
env: LLVM_VERSION=3.8.1 OPTS="-DLIB_SUFFIX=64"
|
||||
env: LLVM_VERSION=4.0.1 OPTS="-DLIB_SUFFIX=64"
|
||||
- os: linux
|
||||
d: dmd
|
||||
env: LLVM_VERSION=3.7.1 OPTS="-DTEST_COVERAGE=ON"
|
||||
env: LLVM_VERSION=3.9.1 OPTS="-DTEST_COVERAGE=ON"
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
d: dmd
|
||||
|
@ -43,8 +37,6 @@ cache:
|
|||
- llvm-5.0.2
|
||||
- llvm-4.0.1
|
||||
- llvm-3.9.1
|
||||
- llvm-3.8.1
|
||||
- llvm-3.7.1
|
||||
|
||||
addons:
|
||||
apt:
|
||||
|
|
|
@ -450,7 +450,6 @@ endif()
|
|||
# LLD integration (requires LLVM >= 3.9 with LLD headers & libs)
|
||||
#
|
||||
if(NOT DEFINED LDC_WITH_LLD)
|
||||
if(LDC_LLVM_VER GREATER 308)
|
||||
# check for LLD header
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_REQUIRED_FLAGS -std=c++11)
|
||||
|
@ -469,9 +468,6 @@ if(NOT DEFINED LDC_WITH_LLD)
|
|||
else()
|
||||
set(LDC_WITH_LLD OFF)
|
||||
endif()
|
||||
else()
|
||||
set(LDC_WITH_LLD OFF)
|
||||
endif()
|
||||
endif()
|
||||
if(LDC_WITH_LLD)
|
||||
append("-DLDC_WITH_LLD" LDC_CXXFLAGS)
|
||||
|
@ -783,7 +779,7 @@ else()
|
|||
set(LDC_INSTALL_LTOPLUGIN_DEFAULT OFF)
|
||||
endif()
|
||||
set(LDC_INSTALL_LTOPLUGIN ${LDC_INSTALL_LTOPLUGIN_DEFAULT} CACHE BOOL "Copy/install the LTO plugin from the LLVM package when available (LLVM >= 3.9).")
|
||||
if (NOT (LDC_LLVM_VER LESS 309) AND LDC_INSTALL_LTOPLUGIN)
|
||||
if (LDC_INSTALL_LTOPLUGIN)
|
||||
if(APPLE)
|
||||
set(LLVM_LTO_BINARY ${LLVM_LIBRARY_DIRS}/libLTO.dylib)
|
||||
set(LDC_LTO_BINARY_NAME libLTO-ldc.dylib)
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include "gen/logger.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/ArchiveWriter.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
|
@ -257,8 +255,6 @@ int internalLib(ArrayRef<const char *> args) {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
#endif // LDC_LLVM_VER >= 309
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static llvm::cl::opt<std::string> ar("ar", llvm::cl::desc("Archiver"),
|
||||
|
@ -270,11 +266,7 @@ int createStaticLibrary() {
|
|||
const bool isTargetMSVC =
|
||||
global.params.targetTriple->isWindowsMSVCEnvironment();
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
const bool useInternalArchiver = ar.empty();
|
||||
#else
|
||||
const bool useInternalArchiver = false;
|
||||
#endif
|
||||
|
||||
// find archiver
|
||||
std::string tool;
|
||||
|
@ -347,7 +339,6 @@ int createStaticLibrary() {
|
|||
// create path to the library
|
||||
createDirectoryForFileOrFail(libName);
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (useInternalArchiver) {
|
||||
const auto fullArgs =
|
||||
getFullArgs(tool.c_str(), args, global.params.verbose);
|
||||
|
@ -359,7 +350,6 @@ int createStaticLibrary() {
|
|||
|
||||
return exitCode;
|
||||
}
|
||||
#endif
|
||||
|
||||
// invoke external archiver
|
||||
return executeToolAndWait(tool, args, global.params.verbose);
|
||||
|
|
|
@ -305,13 +305,9 @@ void outputIR2ObjRelevantCmdlineArgs(llvm::raw_ostream &hash_os) {
|
|||
hash_os << opts::getCPUStr();
|
||||
hash_os << opts::getFeaturesStr();
|
||||
hash_os << opts::floatABI;
|
||||
#if LDC_LLVM_VER >= 309
|
||||
const auto relocModel = opts::getRelocModel();
|
||||
if (relocModel.hasValue())
|
||||
hash_os << relocModel.getValue();
|
||||
#else
|
||||
hash_os << opts::getRelocModel();
|
||||
#endif
|
||||
#if LDC_LLVM_VER >= 600
|
||||
const auto codeModel = opts::getCodeModel();
|
||||
if (codeModel.hasValue())
|
||||
|
|
|
@ -29,11 +29,7 @@ namespace opts {
|
|||
|
||||
std::string getArchStr() { return ::MArch; }
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
Optional<Reloc::Model> getRelocModel() { return ::getRelocModel(); }
|
||||
#else
|
||||
Reloc::Model getRelocModel() { return ::RelocModel; }
|
||||
#endif
|
||||
|
||||
#if LDC_LLVM_VER >= 600
|
||||
Optional<CodeModel::Model> getCodeModel() { return ::getCodeModel(); }
|
||||
|
|
|
@ -18,11 +18,7 @@
|
|||
namespace opts {
|
||||
|
||||
std::string getArchStr();
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::Optional<llvm::Reloc::Model> getRelocModel();
|
||||
#else
|
||||
llvm::Reloc::Model getRelocModel();
|
||||
#endif
|
||||
#if LDC_LLVM_VER >= 600
|
||||
llvm::Optional<llvm::CodeModel::Model> getCodeModel();
|
||||
#else
|
||||
|
|
|
@ -419,7 +419,6 @@ cl::opt<unsigned char, true, CoverageParser> coverageAnalysis(
|
|||
"minimum required coverage)"),
|
||||
cl::ValueOptional, cl::init(127));
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
cl::opt<LTOKind> ltoMode(
|
||||
"flto", cl::ZeroOrMore, cl::desc("Set LTO mode, requires linker support"),
|
||||
cl::init(LTO_None),
|
||||
|
@ -427,7 +426,6 @@ cl::opt<LTOKind> ltoMode(
|
|||
clEnumValN(LTO_Full, "full", "Merges all input into a single module"),
|
||||
clEnumValN(LTO_Thin, "thin",
|
||||
"Parallel importing and codegen (faster than 'full')")));
|
||||
#endif
|
||||
|
||||
#if LDC_LLVM_VER >= 400
|
||||
cl::opt<std::string>
|
||||
|
|
|
@ -93,7 +93,6 @@ extern std::vector<std::string> debugArgs;
|
|||
void createClashingOptions();
|
||||
void hideLLVMOptions();
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
// LTO options
|
||||
enum LTOKind {
|
||||
LTO_None,
|
||||
|
@ -103,10 +102,6 @@ enum LTOKind {
|
|||
extern cl::opt<LTOKind> ltoMode;
|
||||
inline bool isUsingLTO() { return ltoMode != LTO_None; }
|
||||
inline bool isUsingThinLTO() { return ltoMode == LTO_Thin; }
|
||||
#else
|
||||
inline bool isUsingLTO() { return false; }
|
||||
inline bool isUsingThinLTO() { return false; }
|
||||
#endif
|
||||
|
||||
#if LDC_LLVM_VER >= 400
|
||||
extern cl::opt<std::string> saveOptimizationRecord;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
namespace {
|
||||
namespace cl = llvm::cl;
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
/// Option for generating IR-based PGO instrumentation (LLVM pass)
|
||||
cl::opt<std::string> IRPGOInstrGenFile(
|
||||
"fprofile-generate", cl::value_desc("filename"),
|
||||
|
@ -37,7 +36,6 @@ cl::opt<std::string> IRPGOInstrUseFile(
|
|||
"fprofile-use", cl::ZeroOrMore, cl::value_desc("filename"),
|
||||
cl::desc("Use instrumentation data for profile-guided optimization"),
|
||||
cl::ValueRequired);
|
||||
#endif
|
||||
|
||||
/// Option for generating frontend-based PGO instrumentation
|
||||
cl::opt<std::string> ASTPGOInstrGenFile(
|
||||
|
@ -96,21 +94,15 @@ void initializeInstrumentationOptionsFromCmdline(const llvm::Triple &triple) {
|
|||
if (ASTPGOInstrGenFile.getNumOccurrences() > 0) {
|
||||
pgoMode = PGO_ASTBasedInstr;
|
||||
if (ASTPGOInstrGenFile.empty()) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
// profile-rt provides a default filename by itself
|
||||
global.params.datafileInstrProf = nullptr;
|
||||
#else
|
||||
global.params.datafileInstrProf = "default.profraw";
|
||||
#endif
|
||||
} else {
|
||||
initFromPathString(global.params.datafileInstrProf, ASTPGOInstrGenFile);
|
||||
}
|
||||
} else if (!ASTPGOInstrUseFile.empty()) {
|
||||
pgoMode = PGO_ASTBasedUse;
|
||||
initFromPathString(global.params.datafileInstrProf, ASTPGOInstrUseFile);
|
||||
}
|
||||
#if LDC_LLVM_VER >= 309
|
||||
else if (IRPGOInstrGenFile.getNumOccurrences() > 0) {
|
||||
} else if (IRPGOInstrGenFile.getNumOccurrences() > 0) {
|
||||
pgoMode = PGO_IRBasedInstr;
|
||||
if (IRPGOInstrGenFile.empty()) {
|
||||
global.params.datafileInstrProf = "default_%m.profraw";
|
||||
|
@ -121,7 +113,6 @@ void initializeInstrumentationOptionsFromCmdline(const llvm::Triple &triple) {
|
|||
pgoMode = PGO_IRBasedUse;
|
||||
initFromPathString(global.params.datafileInstrProf, IRPGOInstrUseFile);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dmdFunctionTrace)
|
||||
global.params.trace = true;
|
||||
|
|
|
@ -177,12 +177,10 @@ void emitLLVMUsedArray(IRState &irs) {
|
|||
namespace ldc {
|
||||
CodeGenerator::CodeGenerator(llvm::LLVMContext &context, bool singleObj)
|
||||
: context_(context), moduleCount_(0), singleObj_(singleObj), ir_(nullptr) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
// Set the context to discard value names when not generating textual IR.
|
||||
if (!global.params.output_ll) {
|
||||
context_.setDiscardValueNames(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CodeGenerator::~CodeGenerator() {
|
||||
|
@ -213,11 +211,7 @@ void CodeGenerator::prepareLLModule(Module *m) {
|
|||
// module.
|
||||
ir_ = new IRState(m->srcfile->toChars(), context_);
|
||||
ir_->module.setTargetTriple(global.params.targetTriple->str());
|
||||
#if LDC_LLVM_VER >= 308
|
||||
ir_->module.setDataLayout(*gDataLayout);
|
||||
#else
|
||||
ir_->module.setDataLayout(gDataLayout->getStringRepresentation());
|
||||
#endif
|
||||
|
||||
// TODO: Make ldc::DIBuilder per-Module to be able to emit several CUs for
|
||||
// single-object compilations?
|
||||
|
|
|
@ -67,11 +67,9 @@ private:
|
|||
void addDefaultPlatformLibs();
|
||||
virtual void addTargetFlags();
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
void addLTOGoldPluginFlags();
|
||||
void addDarwinLTOFlags();
|
||||
void addLTOLinkFlags();
|
||||
#endif
|
||||
|
||||
virtual void addLdFlag(const llvm::Twine &flag) {
|
||||
args.push_back(("-Wl," + flag).str());
|
||||
|
@ -85,8 +83,6 @@ private:
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// LTO functionality
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
|
||||
std::string getLTOGoldPluginPath() {
|
||||
if (!ltoLibrary.empty()) {
|
||||
if (llvm::sys::fs::exists(ltoLibrary))
|
||||
|
@ -188,8 +184,6 @@ void ArgsBuilder::addLTOLinkFlags() {
|
|||
}
|
||||
}
|
||||
|
||||
#endif // LDC_LLVM_VER >= 309
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Returns the arch name as used in the compiler_rt libs.
|
||||
|
@ -395,13 +389,11 @@ void ArgsBuilder::addProfileRuntimeLinkFlags(const llvm::Triple &triple) {
|
|||
const auto searchPaths =
|
||||
getFullCompilerRTLibPathCandidates("profile", triple);
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (global.params.targetTriple->isOSLinux()) {
|
||||
// For Linux, explicitly define __llvm_profile_runtime as undefined
|
||||
// symbol, so that the initialization part of profile-rt is linked in.
|
||||
addLdFlag("-u", llvm::getInstrProfRuntimeHookVarName());
|
||||
}
|
||||
#endif
|
||||
|
||||
for (const auto &filepath : searchPaths) {
|
||||
IF_LOG Logger::println("Searching profile runtime: %s", filepath.c_str());
|
||||
|
@ -480,12 +472,10 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
|
|||
addXRayLinkFlags(*global.params.targetTriple);
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
// Add LTO link flags before adding the user link switches, such that the user
|
||||
// can pass additional options to the LTO plugin.
|
||||
if (opts::isUsingLTO())
|
||||
addLTOLinkFlags();
|
||||
#endif
|
||||
|
||||
addLinker();
|
||||
addUserSwitches();
|
||||
|
|
|
@ -187,11 +187,7 @@ static void insertBitcodeIntoModule(const char *bcFile, llvm::Module &M,
|
|||
error(Loc(), "Error when loading LLVM bitcode file: %s", bcFile);
|
||||
fatal();
|
||||
}
|
||||
#if LDC_LLVM_VER >= 308
|
||||
llvm::Linker(M).linkInModule(std::move(loadedModule));
|
||||
#else
|
||||
llvm::Linker(&M).linkInModule(loadedModule.release());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Insert LLVM bitcode files into the module
|
||||
|
|
|
@ -52,9 +52,7 @@
|
|||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#if LDC_LLVM_VER >= 308
|
||||
#include "llvm/Support/StringSaver.h"
|
||||
#endif
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
@ -272,7 +270,6 @@ tryGetExplicitTriple(const llvm::SmallVectorImpl<const char *> &args) {
|
|||
|
||||
void expandResponseFiles(llvm::BumpPtrAllocator &A,
|
||||
llvm::SmallVectorImpl<const char *> &args) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
llvm::StringSaver Saver(A);
|
||||
cl::ExpandResponseFiles(Saver,
|
||||
#ifdef _WIN32
|
||||
|
@ -282,7 +279,6 @@ void expandResponseFiles(llvm::BumpPtrAllocator &A,
|
|||
#endif
|
||||
,
|
||||
args);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Parses switches from the command line, any response files and the global
|
||||
|
@ -571,15 +567,10 @@ void initializePasses() {
|
|||
initializeInstrumentation(Registry);
|
||||
initializeAnalysis(Registry);
|
||||
initializeCodeGen(Registry);
|
||||
#if LDC_LLVM_VER >= 309
|
||||
initializeGlobalISel(Registry);
|
||||
#endif
|
||||
initializeTarget(Registry);
|
||||
|
||||
// Initialize passes not included above
|
||||
#if LDC_LLVM_VER < 308
|
||||
initializeIPA(Registry);
|
||||
#endif
|
||||
#if LDC_LLVM_VER >= 400
|
||||
initializeRewriteSymbolsLegacyPassPass(Registry);
|
||||
#else
|
||||
|
@ -937,11 +928,7 @@ void registerPredefinedVersions() {
|
|||
} // anonymous namespace
|
||||
|
||||
int cppmain(int argc, char **argv) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
|
||||
#else
|
||||
llvm::sys::PrintStackTraceOnErrorSignal();
|
||||
#endif
|
||||
|
||||
exe_path::initialize(argv[0]);
|
||||
|
||||
|
@ -1000,11 +987,7 @@ int cppmain(int argc, char **argv) {
|
|||
}
|
||||
|
||||
auto relocModel = getRelocModel();
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (global.params.dll && !relocModel.hasValue()) {
|
||||
#else
|
||||
if (global.params.dll && relocModel == llvm::Reloc::Default) {
|
||||
#endif
|
||||
relocModel = llvm::Reloc::PIC_;
|
||||
}
|
||||
|
||||
|
@ -1019,12 +1002,8 @@ int cppmain(int argc, char **argv) {
|
|||
|
||||
opts::setDefaultMathOptions(gTargetMachine->Options);
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
static llvm::DataLayout DL = gTargetMachine->createDataLayout();
|
||||
gDataLayout = &DL;
|
||||
#else
|
||||
gDataLayout = gTargetMachine->getDataLayout();
|
||||
#endif
|
||||
|
||||
{
|
||||
llvm::Triple *triple = new llvm::Triple(gTargetMachine->getTargetTriple());
|
||||
|
|
|
@ -107,20 +107,12 @@ MipsABI::Type getMipsABI() {
|
|||
if (strncmp(opts::mABI.c_str(), "eabi", 4) == 0)
|
||||
return MipsABI::EABI;
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
const llvm::DataLayout dl = gTargetMachine->createDataLayout();
|
||||
#else
|
||||
const llvm::DataLayout &dl = *gTargetMachine->getDataLayout();
|
||||
#endif
|
||||
|
||||
if (dl.getPointerSizeInBits() == 64)
|
||||
return MipsABI::N64;
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
const auto largestInt = dl.getLargestLegalIntTypeSizeInBits();
|
||||
#else
|
||||
const auto largestInt = dl.getLargestLegalIntTypeSize();
|
||||
#endif
|
||||
return (largestInt == 64) ? MipsABI::N32 : MipsABI::O32;
|
||||
}
|
||||
|
||||
|
@ -167,40 +159,9 @@ static std::string getX86TargetCPU(const llvm::Triple &triple) {
|
|||
}
|
||||
|
||||
static std::string getARMTargetCPU(const llvm::Triple &triple) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
auto defaultCPU = llvm::ARM::getDefaultCPU(triple.getArchName());
|
||||
if (!defaultCPU.empty())
|
||||
return defaultCPU;
|
||||
#else
|
||||
auto defaultCPU = llvm::StringSwitch<const char *>(triple.getArchName())
|
||||
.Cases("armv2", "armv2a", "arm2")
|
||||
.Case("armv3", "arm6")
|
||||
.Case("armv3m", "arm7m")
|
||||
.Case("armv4", "strongarm")
|
||||
.Case("armv4t", "arm7tdmi")
|
||||
.Cases("armv5", "armv5t", "arm10tdmi")
|
||||
.Cases("armv5e", "armv5te", "arm1026ejs")
|
||||
.Case("armv5tej", "arm926ej-s")
|
||||
.Cases("armv6", "armv6k", "arm1136jf-s")
|
||||
.Case("armv6j", "arm1136j-s")
|
||||
.Cases("armv6z", "armv6zk", "arm1176jzf-s")
|
||||
.Case("armv6t2", "arm1156t2-s")
|
||||
.Cases("armv6m", "armv6-m", "cortex-m0")
|
||||
.Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
|
||||
.Cases("armv7l", "armv7-l", "cortex-a8")
|
||||
.Cases("armv7f", "armv7-f", "cortex-a9-mp")
|
||||
.Cases("armv7s", "armv7-s", "swift")
|
||||
.Cases("armv7r", "armv7-r", "cortex-r4")
|
||||
.Cases("armv7m", "armv7-m", "cortex-m3")
|
||||
.Cases("armv7em", "armv7e-m", "cortex-m4")
|
||||
.Cases("armv8", "armv8a", "armv8-a", "cortex-a53")
|
||||
.Case("ep9312", "ep9312")
|
||||
.Case("iwmmxt", "iwmmxt")
|
||||
.Case("xscale", "xscale")
|
||||
.Default(nullptr);
|
||||
if (defaultCPU)
|
||||
return defaultCPU;
|
||||
#endif
|
||||
|
||||
// Return the most base CPU with thumb interworking supported by LLVM.
|
||||
return (triple.getEnvironment() == llvm::Triple::GNUEABIHF) ? "arm1176jzf-s"
|
||||
|
@ -208,11 +169,9 @@ static std::string getARMTargetCPU(const llvm::Triple &triple) {
|
|||
}
|
||||
|
||||
static std::string getAArch64TargetCPU(const llvm::Triple &triple) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
auto defaultCPU = llvm::AArch64::getDefaultCPU(triple.getArchName());
|
||||
if (!defaultCPU.empty())
|
||||
return defaultCPU;
|
||||
#endif
|
||||
|
||||
return "generic";
|
||||
}
|
||||
|
@ -364,11 +323,7 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
|
|||
std::string cpu, const std::string featuresString,
|
||||
const ExplicitBitness::Type bitness,
|
||||
FloatABI::Type &floatABI,
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::Optional<llvm::Reloc::Model> relocModel,
|
||||
#else
|
||||
llvm::Reloc::Model relocModel,
|
||||
#endif
|
||||
#if LDC_LLVM_VER >= 600
|
||||
llvm::Optional<llvm::CodeModel::Model> codeModel,
|
||||
#else
|
||||
|
@ -455,11 +410,7 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
|
|||
#endif
|
||||
|
||||
// Handle cases where LLVM picks wrong default relocModel
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (!relocModel.hasValue()) {
|
||||
#else
|
||||
if (relocModel == llvm::Reloc::Default) {
|
||||
#endif
|
||||
if (triple.isOSDarwin()) {
|
||||
// Darwin defaults to PIC (and as of 10.7.5/LLVM 3.1-3.3, TLS use leads
|
||||
// to crashes for non-PIC code). LLVM doesn't handle this.
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
#ifndef LDC_DRIVER_TARGET_H
|
||||
#define LDC_DRIVER_TARGET_H
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#endif
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -58,11 +56,7 @@ llvm::TargetMachine *
|
|||
createTargetMachine(std::string targetTriple, std::string arch, std::string cpu,
|
||||
std::string featuresString, ExplicitBitness::Type bitness,
|
||||
FloatABI::Type &floatABI,
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::Optional<llvm::Reloc::Model> relocModel,
|
||||
#else
|
||||
llvm::Reloc::Model relocModel,
|
||||
#endif
|
||||
#if LDC_LLVM_VER >= 600
|
||||
llvm::Optional<llvm::CodeModel::Model> codeModel,
|
||||
#else
|
||||
|
|
|
@ -18,9 +18,7 @@
|
|||
#include "gen/optimizer.h"
|
||||
#include "llvm/IR/AssemblyAnnotationWriter.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#if LDC_LLVM_VER >= 309
|
||||
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
|
||||
#endif
|
||||
#if LDC_LLVM_VER >= 400
|
||||
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||
#include "llvm/Bitcode/BitcodeWriter.h"
|
||||
|
@ -295,9 +293,6 @@ bool shouldOutputObjectFile() {
|
|||
}
|
||||
|
||||
bool shouldDoLTO(llvm::Module *m) {
|
||||
#if LDC_LLVM_VER < 309
|
||||
return false;
|
||||
#else
|
||||
#if LDC_LLVM_VER == 309
|
||||
// LLVM 3.9 bug: can't do ThinLTO with modules that have module-scope inline
|
||||
// assembly blocks (duplicate definitions upon importing from such a module).
|
||||
|
@ -306,7 +301,6 @@ bool shouldDoLTO(llvm::Module *m) {
|
|||
return false;
|
||||
#endif
|
||||
return opts::isUsingLTO();
|
||||
#endif
|
||||
}
|
||||
} // end of anonymous namespace
|
||||
|
||||
|
@ -387,7 +381,6 @@ void writeModule(llvm::Module *m, const char *filename) {
|
|||
#endif
|
||||
|
||||
if (opts::isUsingThinLTO()) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
Logger::println("Creating module summary for ThinLTO");
|
||||
#if LDC_LLVM_VER == 309
|
||||
// When the function freq info callback is set to nullptr, LLVM will
|
||||
|
@ -406,7 +399,6 @@ void writeModule(llvm::Module *m, const char *filename) {
|
|||
|
||||
llvm::WriteBitcodeToFile(M, bos, true, &moduleSummaryIndex,
|
||||
/* generate ThinLTO hash */ true);
|
||||
#endif
|
||||
} else {
|
||||
llvm::WriteBitcodeToFile(M, bos);
|
||||
}
|
||||
|
|
|
@ -620,11 +620,7 @@ void initializeArrayLiteral(IRState *p, ArrayLiteralExp *ale, LLValue *dstMem) {
|
|||
auto gvar = new llvm::GlobalVariable(gIR->module, constarr->getType(),
|
||||
true, LLGlobalValue::InternalLinkage,
|
||||
constarr, ".arrayliteral");
|
||||
#if LDC_LLVM_VER >= 309
|
||||
gvar->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
#else
|
||||
gvar->setUnnamedAddr(true);
|
||||
#endif
|
||||
DtoMemCpy(dstMem, gvar,
|
||||
DtoConstSize_t(getTypeAllocSize(constarr->getType())));
|
||||
}
|
||||
|
|
|
@ -33,13 +33,7 @@ void initFromPathString(const char *&dest, const cl::opt<std::string> &src) {
|
|||
dest = nullptr;
|
||||
if (src.getNumOccurrences() != 0) {
|
||||
if (src.empty()) {
|
||||
error(Loc(), "Expected argument to '-%s'",
|
||||
#if LDC_LLVM_VER >= 308
|
||||
src.ArgStr.str().c_str()
|
||||
#else
|
||||
src.ArgStr
|
||||
#endif
|
||||
);
|
||||
error(Loc(), "Expected argument to '-%s'", src.ArgStr.str().c_str());
|
||||
}
|
||||
dest = dupPathString(src);
|
||||
}
|
||||
|
|
|
@ -137,11 +137,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
void getExtraOptionNames(llvm::SmallVectorImpl<llvm::StringRef> &Names) {
|
||||
#else
|
||||
void getExtraOptionNames(llvm::SmallVectorImpl<const char *> &Names) {
|
||||
#endif
|
||||
for (auto I = switches.begin() + 1, E = switches.end(); I != E; ++I) {
|
||||
Names.push_back(I->first.data());
|
||||
}
|
||||
|
|
|
@ -39,12 +39,7 @@ void emitCoverageLinecountInc(Loc &loc) {
|
|||
|
||||
// Do an atomic increment, so this works when multiple threads are executed.
|
||||
gIR->ir->CreateAtomicRMW(llvm::AtomicRMWInst::Add, ptr, DtoConstUint(1),
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::AtomicOrdering::Monotonic
|
||||
#else
|
||||
llvm::Monotonic
|
||||
#endif
|
||||
);
|
||||
llvm::AtomicOrdering::Monotonic);
|
||||
|
||||
unsigned num_sizet_bits = gDataLayout->getTypeSizeInBits(DtoSize_t());
|
||||
unsigned idx = line / num_sizet_bits;
|
||||
|
|
|
@ -48,10 +48,8 @@ llvm::DINodeArray getEmptyDINodeArray() {
|
|||
}
|
||||
|
||||
llvm::StringRef uniqueIdent(Type* t) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (t->deco)
|
||||
return t->deco;
|
||||
#endif
|
||||
return llvm::StringRef();
|
||||
}
|
||||
|
||||
|
@ -609,20 +607,12 @@ ldc::DISubroutineType ldc::DIBuilder::CreateFunctionType(Type *type) {
|
|||
LLMetadata *params = {CreateTypeDescription(retType)};
|
||||
auto paramsArray = DBuilder.getOrCreateTypeArray(params);
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
return DBuilder.createSubroutineType(paramsArray);
|
||||
#else
|
||||
return DBuilder.createSubroutineType(CreateFile(), paramsArray);
|
||||
#endif
|
||||
}
|
||||
|
||||
ldc::DISubroutineType ldc::DIBuilder::CreateEmptyFunctionType() {
|
||||
auto paramsArray = DBuilder.getOrCreateTypeArray(llvm::None);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
return DBuilder.createSubroutineType(paramsArray);
|
||||
#else
|
||||
return DBuilder.createSubroutineType(CreateFile(), paramsArray);
|
||||
#endif
|
||||
}
|
||||
|
||||
ldc::DIType ldc::DIBuilder::CreateDelegateType(Type *type) {
|
||||
|
@ -673,11 +663,7 @@ ldc::DIType ldc::DIBuilder::CreateTypeDescription(Type *type) {
|
|||
Type *t = type->toBasetype();
|
||||
|
||||
if (t->ty == Tvoid)
|
||||
#if LDC_LLVM_VER >= 309
|
||||
return nullptr;
|
||||
#else
|
||||
return DBuilder.createUnspecifiedType(type->toPrettyChars(true));
|
||||
#endif
|
||||
if (t->ty == Tnull) // display null as void*
|
||||
return DBuilder.createPointerType(CreateTypeDescription(Type::tvoid),
|
||||
8, 8,
|
||||
|
@ -725,15 +711,8 @@ ldc::DIType ldc::DIBuilder::CreateTypeDescription(Type *type) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
using DebugEmissionKind = llvm::DICompileUnit::DebugEmissionKind;
|
||||
#else
|
||||
using DebugEmissionKind = llvm::DIBuilder::DebugEmissionKind;
|
||||
#endif
|
||||
|
||||
DebugEmissionKind getDebugEmissionKind()
|
||||
llvm::DICompileUnit::DebugEmissionKind getDebugEmissionKind()
|
||||
{
|
||||
#if LDC_LLVM_VER >= 309
|
||||
switch (global.params.symdebug)
|
||||
{
|
||||
case 0:
|
||||
|
@ -746,12 +725,6 @@ DebugEmissionKind getDebugEmissionKind()
|
|||
default:
|
||||
llvm_unreachable("unknown DebugEmissionKind");
|
||||
}
|
||||
#else
|
||||
assert(global.params.symdebug != 0);
|
||||
return global.params.symdebug == 3 ?
|
||||
llvm::DIBuilder::LineTablesOnly :
|
||||
llvm::DIBuilder::FullDebug;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -774,13 +747,11 @@ void ldc::DIBuilder::EmitCompileUnit(Module *m) {
|
|||
auto producerName = std::string("LDC ") + ldc::ldc_version + " (LLVM " +
|
||||
ldc::llvm_version + ")";
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (global.params.targetTriple->isWindowsMSVCEnvironment())
|
||||
IR->module.addModuleFlag(llvm::Module::Warning, "CodeView", 1);
|
||||
else if (global.params.dwarfVersion > 0)
|
||||
IR->module.addModuleFlag(llvm::Module::Warning, "Dwarf Version",
|
||||
global.params.dwarfVersion);
|
||||
#endif
|
||||
// Metadata without a correct version will be stripped by UpgradeDebugInfo.
|
||||
IR->module.addModuleFlag(llvm::Module::Warning, "Debug Info Version",
|
||||
llvm::DEBUG_METADATA_VERSION);
|
||||
|
@ -801,9 +772,6 @@ void ldc::DIBuilder::EmitCompileUnit(Module *m) {
|
|||
llvm::StringRef(), // SplitName
|
||||
getDebugEmissionKind(), // DebugEmissionKind
|
||||
0 // DWOId
|
||||
#if LDC_LLVM_VER < 309
|
||||
, mustEmitFullDebugInfo() // EmitDebugInfo
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -839,14 +807,8 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
|||
fd->loc.linnum, // FIXME: scope line
|
||||
DIFlags::FlagPrototyped, // Flags
|
||||
isOptimizationEnabled() // isOptimized
|
||||
#if LDC_LLVM_VER < 308
|
||||
,
|
||||
DtoFunction(fd)
|
||||
#endif
|
||||
);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
DtoFunction(fd)->setSubprogram(SP);
|
||||
#endif
|
||||
return SP;
|
||||
}
|
||||
|
||||
|
@ -883,15 +845,9 @@ ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk,
|
|||
fd->loc.linnum, // FIXME: scope line
|
||||
DIFlags::FlagPrototyped, // Flags
|
||||
isOptimizationEnabled() // isOptimized
|
||||
#if LDC_LLVM_VER < 308
|
||||
,
|
||||
DtoFunction(fd)
|
||||
#endif
|
||||
);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (fd->fbody)
|
||||
DtoFunction(fd)->setSubprogram(SP);
|
||||
#endif
|
||||
return SP;
|
||||
}
|
||||
|
||||
|
@ -912,11 +868,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
|
|||
// Create "dummy" subroutine type for the return type
|
||||
LLMetadata *params = {CreateTypeDescription(Type::tvoid)};
|
||||
auto paramsArray = DBuilder.getOrCreateTypeArray(params);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
auto DIFnType = DBuilder.createSubroutineType(paramsArray);
|
||||
#else
|
||||
auto DIFnType = DBuilder.createSubroutineType(file, paramsArray);
|
||||
#endif
|
||||
|
||||
// FIXME: duplicates?
|
||||
auto SP =
|
||||
|
@ -931,14 +883,8 @@ ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
|
|||
0, // FIXME: scope line
|
||||
DIFlags::FlagPrototyped | DIFlags::FlagArtificial,
|
||||
isOptimizationEnabled() // isOptimized
|
||||
#if LDC_LLVM_VER < 308
|
||||
,
|
||||
Fn
|
||||
#endif
|
||||
);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
Fn->setSubprogram(SP);
|
||||
#endif
|
||||
return SP;
|
||||
}
|
||||
|
||||
|
@ -1079,16 +1025,12 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
|||
// for the DI reference.
|
||||
useDbgValueIntrinsic =
|
||||
isPassedExplicitlyByval || (!isSpecialRefVar(vd) && isRefRVal);
|
||||
#if LDC_LLVM_VER >= 308
|
||||
// Note: createReferenceType expects the size to be the size of a pointer,
|
||||
// not the size of the type the reference refers to.
|
||||
TD = DBuilder.createReferenceType(
|
||||
llvm::dwarf::DW_TAG_reference_type, TD,
|
||||
gDataLayout->getPointerSizeInBits(), // size (bits)
|
||||
DtoAlignment(type) * 8); // align (bits)
|
||||
#else
|
||||
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD);
|
||||
#endif
|
||||
} else {
|
||||
// FIXME: For MSVC x64 targets, declare dynamic array and vector parameters
|
||||
// as DI locals to work around garbage for both cdb and VS debuggers.
|
||||
|
@ -1102,31 +1044,11 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
|||
// get variable description
|
||||
assert(!vd->isDataseg() && "static variable");
|
||||
|
||||
#if LDC_LLVM_VER < 308
|
||||
unsigned tag;
|
||||
if (!forceAsLocal && vd->isParameter()) {
|
||||
tag = llvm::dwarf::DW_TAG_arg_variable;
|
||||
} else {
|
||||
tag = llvm::dwarf::DW_TAG_auto_variable;
|
||||
}
|
||||
#endif
|
||||
|
||||
ldc::DILocalVariable debugVariable;
|
||||
auto Flags = !isThisPtr
|
||||
? DIFlagZero
|
||||
: DIFlags::FlagArtificial | DIFlags::FlagObjectPointer;
|
||||
|
||||
#if LDC_LLVM_VER < 308
|
||||
debugVariable = DBuilder.createLocalVariable(tag, // tag
|
||||
GetCurrentScope(), // scope
|
||||
vd->toChars(), // name
|
||||
CreateFile(vd), // file
|
||||
vd->loc.linnum, // line num
|
||||
TD, // type
|
||||
true, // preserve
|
||||
Flags // flags
|
||||
);
|
||||
#else
|
||||
if (!forceAsLocal && vd->isParameter()) {
|
||||
FuncDeclaration *fd = vd->parent->isFuncDeclaration();
|
||||
assert(fd);
|
||||
|
@ -1159,7 +1081,6 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
|||
Flags // flags
|
||||
);
|
||||
}
|
||||
#endif
|
||||
variableMap[vd] = debugVariable;
|
||||
|
||||
if (useDbgValueIntrinsic) {
|
||||
|
|
|
@ -226,17 +226,11 @@ llvm::CallSite FuncGenState::callOrInvoke(llvm::Value *callee, const T &args,
|
|||
isNothrow ||
|
||||
(calleeFn && (calleeFn->isIntrinsic() || calleeFn->doesNotThrow()));
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
// calls inside a funclet must be annotated with its value
|
||||
llvm::SmallVector<llvm::OperandBundleDef, 2> BundleList;
|
||||
#endif
|
||||
|
||||
if (doesNotThrow || scopes.empty()) {
|
||||
llvm::CallInst *call = irs.ir->CreateCall(callee, args,
|
||||
#if LDC_LLVM_VER >= 308
|
||||
BundleList,
|
||||
#endif
|
||||
name);
|
||||
llvm::CallInst *call = irs.ir->CreateCall(callee, args, BundleList, name);
|
||||
if (calleeFn) {
|
||||
call->setAttributes(calleeFn->getAttributes());
|
||||
}
|
||||
|
@ -246,12 +240,8 @@ llvm::CallSite FuncGenState::callOrInvoke(llvm::Value *callee, const T &args,
|
|||
llvm::BasicBlock *landingPad = scopes.getLandingPad();
|
||||
|
||||
llvm::BasicBlock *postinvoke = irs.insertBB("postinvoke");
|
||||
llvm::InvokeInst *invoke =
|
||||
irs.ir->CreateInvoke(callee, postinvoke, landingPad, args,
|
||||
#if LDC_LLVM_VER >= 308
|
||||
BundleList,
|
||||
#endif
|
||||
name);
|
||||
llvm::InvokeInst *invoke = irs.ir->CreateInvoke(
|
||||
callee, postinvoke, landingPad, args, BundleList, name);
|
||||
if (calleeFn) {
|
||||
invoke->setAttributes(calleeFn->getAttributes());
|
||||
}
|
||||
|
|
|
@ -1057,11 +1057,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
};
|
||||
|
||||
// Set the FastMath options for this function scope.
|
||||
#if LDC_LLVM_VER >= 308
|
||||
gIR->scopes.back().builder.setFastMathFlags(irFunc->FMF);
|
||||
#else
|
||||
gIR->scopes.back().builder.SetFastMathFlags(irFunc->FMF);
|
||||
#endif
|
||||
|
||||
// @naked: emit body and return, no prologue/epilogue
|
||||
if (func->hasFnAttribute(llvm::Attribute::Naked)) {
|
||||
|
@ -1097,18 +1093,12 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
|
|||
// disable frame-pointer-elimination for functions with inline asm
|
||||
if (fd->hasReturnExp & 8) // has inline asm
|
||||
{
|
||||
#if LDC_LLVM_VER >= 309
|
||||
func->addAttribute(
|
||||
LLAttributeSet::FunctionIndex,
|
||||
llvm::Attribute::get(gIR->context(), "no-frame-pointer-elim", "true"));
|
||||
func->addAttribute(
|
||||
LLAttributeSet::FunctionIndex,
|
||||
llvm::Attribute::get(gIR->context(), "no-frame-pointer-elim-non-leaf"));
|
||||
#else
|
||||
// hack: emit a call to llvm_eh_unwind_init
|
||||
LLFunction *hack = GET_INTRINSIC_DECL(eh_unwind_init);
|
||||
gIR->ir->CreateCall(hack, {});
|
||||
#endif
|
||||
}
|
||||
|
||||
// give the 'this' parameter (an lvalue) storage and debug info
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace {
|
|||
/// Sets LLVMContext::setDiscardValueNames(false) upon construction and restores
|
||||
/// the previous value upon destruction.
|
||||
struct TempDisableDiscardValueNames {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::LLVMContext &ctx;
|
||||
bool previousValue;
|
||||
|
||||
|
@ -30,9 +29,6 @@ struct TempDisableDiscardValueNames {
|
|||
}
|
||||
|
||||
~TempDisableDiscardValueNames() { ctx.setDiscardValueNames(previousValue); }
|
||||
#else
|
||||
TempDisableDiscardValueNames(llvm::LLVMContext &context) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Adds the idol's function attributes to the wannabe
|
||||
|
@ -213,11 +209,7 @@ DValue *DtoInlineIRExpr(Loc &loc, FuncDeclaration *fdecl,
|
|||
|
||||
m->setDataLayout(gIR->module.getDataLayout());
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
llvm::Linker(gIR->module).linkInModule(std::move(m));
|
||||
#else
|
||||
llvm::Linker(&gIR->module).linkInModule(m.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
// 2. Call the function that was just defined and return the returnvalue
|
||||
|
|
|
@ -192,9 +192,5 @@ IRBuilder<> *IRBuilderHelper::operator->() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool useMSVCEH() {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
return global.params.targetTriple->isWindowsMSVCEnvironment();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -240,11 +240,9 @@ public:
|
|||
llvm::SmallVector<llvm::Metadata *, 5> LinkerMetadataArgs;
|
||||
#endif
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
// MS C++ compatible type descriptors
|
||||
llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
|
||||
llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> TypeDescriptorMap;
|
||||
#endif
|
||||
|
||||
// Target for dcompute. If not nullptr, it owns this.
|
||||
DComputeTarget *dcomputetarget = nullptr;
|
||||
|
|
|
@ -71,11 +71,7 @@ bool isTargetWindowsMSVC() {
|
|||
}
|
||||
|
||||
bool isMusl() {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
return global.params.targetTriple->isMusl();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -612,7 +612,6 @@ void loadInstrProfileData(IRState *irs) {
|
|||
|
||||
auto readerOrErr =
|
||||
llvm::IndexedInstrProfReader::create(global.params.datafileInstrProf);
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (auto E = readerOrErr.takeError()) {
|
||||
handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
|
||||
irs->dmodule->error("Could not read profile file '%s': %s",
|
||||
|
@ -621,18 +620,8 @@ void loadInstrProfileData(IRState *irs) {
|
|||
});
|
||||
fatal();
|
||||
}
|
||||
#else
|
||||
std::error_code EC = readerOrErr.getError();
|
||||
if (EC) {
|
||||
irs->dmodule->error("Could not read profile file '%s': %s",
|
||||
global.params.datafileInstrProf,
|
||||
EC.message().c_str());
|
||||
fatal();
|
||||
}
|
||||
#endif
|
||||
irs->PGOReader = std::move(readerOrErr.get());
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (!irs->module.getProfileSummary()) {
|
||||
// Don't reset the summary. There is only one profile data file per LDC
|
||||
// invocation so the summary must be the same as the one that is already
|
||||
|
@ -640,15 +629,6 @@ void loadInstrProfileData(IRState *irs) {
|
|||
irs->module.setProfileSummary(
|
||||
irs->PGOReader->getSummary().getMD(irs->context()));
|
||||
}
|
||||
#elif LDC_LLVM_VER == 308
|
||||
auto maxCount = irs->PGOReader->getMaximumFunctionCount();
|
||||
if (!irs->module.getMaximumFunctionCount()) {
|
||||
// Don't reset the max function count. There is only one profile data file
|
||||
// per LDC invocation so the information must be the same as the one that
|
||||
// is already set.
|
||||
irs->module.setMaximumFunctionCount(maxCount);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
|
||||
#include "target.h"
|
||||
#include "gen/ms-cxx-helper.h"
|
||||
#include "gen/llvm.h"
|
||||
|
@ -63,12 +61,8 @@ void remapBlocks(std::vector<llvm::BasicBlock *> &blocks,
|
|||
for (llvm::BasicBlock *bb : blocks)
|
||||
for (auto &I : *bb) {
|
||||
llvm::RemapInstruction(&I, VMap,
|
||||
#if LDC_LLVM_VER == 308
|
||||
llvm::RF_IgnoreMissingEntries
|
||||
#else
|
||||
llvm::RF_IgnoreMissingLocals
|
||||
#endif
|
||||
| llvm::RF_NoModuleLevelChanges);
|
||||
llvm::RF_IgnoreMissingLocals |
|
||||
llvm::RF_NoModuleLevelChanges);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,5 +190,3 @@ llvm::GlobalVariable *getTypeDescriptor(IRState &irs, ClassDeclaration *cd) {
|
|||
|
||||
return Var;
|
||||
}
|
||||
|
||||
#endif // LDC_LLVM_VER >= 308
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#ifndef LDC_GEN_MS_CXX_HELPER_H
|
||||
#define LDC_GEN_MS_CXX_HELPER_H
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
#include "gen/irstate.h"
|
||||
|
||||
llvm::StructType *getTypeDescriptorType(IRState &irs,
|
||||
|
@ -31,5 +30,4 @@ void cloneBlocks(const std::vector<llvm::BasicBlock *> &srcblocks,
|
|||
|
||||
bool isCatchSwitchBlock(llvm::BasicBlock* bb);
|
||||
|
||||
#endif // LDC_LLVM_VER >= 308
|
||||
#endif // LDC_GEN_MS_CXX_HELPER_H
|
||||
|
|
|
@ -214,11 +214,7 @@ static void addPGOPasses(PassManagerBuilder &builder,
|
|||
options.NoRedZone = global.params.disableRedZone;
|
||||
if (global.params.datafileInstrProf)
|
||||
options.InstrProfileOutput = global.params.datafileInstrProf;
|
||||
#if LDC_LLVM_VER >= 309
|
||||
mpm.add(createInstrProfilingLegacyPass(options));
|
||||
#else
|
||||
mpm.add(createInstrProfilingPass(options));
|
||||
#endif
|
||||
} else if (opts::isUsingASTBasedPGOProfile()) {
|
||||
// We are generating code with PGO profile information available.
|
||||
#if LDC_LLVM_VER >= 500
|
||||
|
@ -228,7 +224,6 @@ static void addPGOPasses(PassManagerBuilder &builder,
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#if LDC_LLVM_VER >= 309
|
||||
else if (opts::isInstrumentingForIRBasedPGO()) {
|
||||
#if LDC_LLVM_VER >= 400
|
||||
builder.EnablePGOInstrGen = true;
|
||||
|
@ -237,7 +232,6 @@ static void addPGOPasses(PassManagerBuilder &builder,
|
|||
} else if (opts::isUsingIRBasedPGOProfile()) {
|
||||
builder.PGOInstrUse = global.params.datafileInstrProf;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,10 +251,8 @@ static void addOptimizationPasses(legacy::PassManagerBase &mpm,
|
|||
PassManagerBuilder builder;
|
||||
builder.OptLevel = optLevel;
|
||||
builder.SizeLevel = sizeLevel;
|
||||
#if LDC_LLVM_VER >= 309
|
||||
builder.PrepareForLTO = opts::isUsingLTO();
|
||||
builder.PrepareForThinLTO = opts::isUsingThinLTO();
|
||||
#endif
|
||||
|
||||
if (willInline()) {
|
||||
#if LDC_LLVM_VER >= 400
|
||||
|
|
|
@ -37,12 +37,6 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
typedef AAResultsWrapperPass AliasAnalysisPass;
|
||||
#else
|
||||
typedef AliasAnalysis AliasAnalysisPass;
|
||||
#endif
|
||||
|
||||
STATISTIC(NumSimplified, "Number of runtime calls simplified");
|
||||
STATISTIC(NumDeleted, "Number of runtime calls deleted");
|
||||
|
||||
|
@ -330,10 +324,10 @@ public:
|
|||
void InitOptimizations();
|
||||
bool runOnFunction(Function &F) override;
|
||||
|
||||
bool runOnce(Function &F, const DataLayout *DL, AliasAnalysisPass &AA);
|
||||
bool runOnce(Function &F, const DataLayout *DL, AAResultsWrapperPass &AA);
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AliasAnalysisPass>();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
}
|
||||
};
|
||||
char SimplifyDRuntimeCalls::ID = 0;
|
||||
|
@ -384,7 +378,7 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
|
|||
}
|
||||
|
||||
const DataLayout *DL = &F.getParent()->getDataLayout();
|
||||
AliasAnalysisPass &AA = getAnalysis<AliasAnalysisPass>();
|
||||
AAResultsWrapperPass &AA = getAnalysis<AAResultsWrapperPass>();
|
||||
|
||||
// Iterate to catch opportunities opened up by other optimizations,
|
||||
// such as calls that are only used as arguments to unused calls:
|
||||
|
@ -402,7 +396,7 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
|
|||
}
|
||||
|
||||
bool SimplifyDRuntimeCalls::runOnce(Function &F, const DataLayout *DL,
|
||||
AliasAnalysisPass &AAP) {
|
||||
AAResultsWrapperPass &AAP) {
|
||||
IRBuilder<> Builder(F.getContext());
|
||||
|
||||
bool Changed = false;
|
||||
|
@ -435,11 +429,7 @@ bool SimplifyDRuntimeCalls::runOnce(Function &F, const DataLayout *DL,
|
|||
--ciIt;
|
||||
Builder.SetInsertPoint(&BB, I);
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
AliasAnalysis &AA = AAP.getAAResults();
|
||||
#else
|
||||
AliasAnalysis &AA = AAP;
|
||||
#endif
|
||||
// Try to optimize this call.
|
||||
Value *Result = OMI->second->OptimizeCall(CI, Changed, DL, AA, Builder);
|
||||
if (Result == nullptr) {
|
||||
|
@ -455,14 +445,8 @@ bool SimplifyDRuntimeCalls::runOnce(Function &F, const DataLayout *DL,
|
|||
if (Result == CI) {
|
||||
assert(CI->use_empty());
|
||||
++NumDeleted;
|
||||
#if LDC_LLVM_VER < 308
|
||||
AA.deleteValue(CI);
|
||||
#endif
|
||||
} else {
|
||||
++NumSimplified;
|
||||
#if LDC_LLVM_VER < 308
|
||||
AA.replaceWithNewValue(CI, Result);
|
||||
#endif
|
||||
|
||||
if (!CI->use_empty()) {
|
||||
CI->replaceAllUsesWith(Result);
|
||||
|
|
|
@ -33,14 +33,12 @@
|
|||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
namespace {
|
||||
llvm::cl::opt<bool, false, opts::FlagParser<bool>> enablePGOIndirectCalls(
|
||||
"pgo-indirect-calls", llvm::cl::ZeroOrMore, llvm::cl::Hidden,
|
||||
llvm::cl::desc("(*) Enable PGO of indirect calls (LLVM >= 3.9)"),
|
||||
llvm::cl::init(true));
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \brief Stable hasher for PGO region counters.
|
||||
///
|
||||
|
@ -762,7 +760,6 @@ RootObject *CodeGenPGO::getCounterPtr(const RootObject *ptr,
|
|||
|
||||
void CodeGenPGO::setFuncName(llvm::StringRef Name,
|
||||
llvm::GlobalValue::LinkageTypes Linkage) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
llvm::IndexedInstrProfReader *PGOReader = gIR->getPGOReader();
|
||||
FuncName = llvm::getPGOFuncName(Name, Linkage, "",
|
||||
PGOReader ? PGOReader->getVersion()
|
||||
|
@ -780,50 +777,12 @@ void CodeGenPGO::setFuncName(llvm::StringRef Name,
|
|||
FuncNameVar->setLinkage(llvm::GlobalValue::InternalLinkage);
|
||||
}
|
||||
}
|
||||
#else
|
||||
llvm::StringRef RawFuncName = Name;
|
||||
// Function names may be prefixed with a binary '1' to indicate
|
||||
// that the backend should not modify the symbols due to any platform
|
||||
// naming convention. Do not include that '1' in the PGO profile name.
|
||||
if (RawFuncName[0] == '\1')
|
||||
RawFuncName = RawFuncName.substr(1);
|
||||
FuncName = RawFuncName;
|
||||
|
||||
// If we're generating a profile, create a variable for the name.
|
||||
if (opts::isInstrumentingForASTBasedPGO() && emitInstrumentation)
|
||||
createFuncNameVar(Linkage);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CodeGenPGO::setFuncName(llvm::Function *fn) {
|
||||
setFuncName(fn->getName(), fn->getLinkage());
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER < 308
|
||||
void CodeGenPGO::createFuncNameVar(llvm::GlobalValue::LinkageTypes Linkage) {
|
||||
// We generally want to match the function's linkage, but available_externally
|
||||
// and extern_weak both have the wrong semantics, and anything that doesn't
|
||||
// need to link across compilation units doesn't need to be visible at all.
|
||||
if (Linkage == llvm::GlobalValue::ExternalWeakLinkage)
|
||||
Linkage = llvm::GlobalValue::LinkOnceAnyLinkage;
|
||||
else if (Linkage == llvm::GlobalValue::AvailableExternallyLinkage)
|
||||
Linkage = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||
else if (Linkage == llvm::GlobalValue::InternalLinkage ||
|
||||
Linkage == llvm::GlobalValue::ExternalLinkage)
|
||||
Linkage = llvm::GlobalValue::PrivateLinkage;
|
||||
|
||||
auto *value =
|
||||
llvm::ConstantDataArray::getString(gIR->context(), FuncName, false);
|
||||
FuncNameVar =
|
||||
new llvm::GlobalVariable(gIR->module, value->getType(), true, Linkage,
|
||||
value, "__llvm_profile_name_" + FuncName);
|
||||
|
||||
// Hide the symbol so that we correctly get a copy for each executable.
|
||||
if (!llvm::GlobalValue::isLocalLinkage(FuncNameVar->getLinkage()))
|
||||
FuncNameVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CodeGenPGO::assignRegionCounters(const FuncDeclaration *D,
|
||||
llvm::Function *fn) {
|
||||
llvm::IndexedInstrProfReader *PGOReader = gIR->getPGOReader();
|
||||
|
@ -889,20 +848,12 @@ void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
|
|||
const FuncDeclaration *fd) {
|
||||
RegionCounts.clear();
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::Expected<llvm::InstrProfRecord> RecordExpected =
|
||||
PGOReader->getInstrProfRecord(FuncName, FunctionHash);
|
||||
auto EC = RecordExpected.takeError();
|
||||
#else
|
||||
auto EC = PGOReader->getFunctionCounts(FuncName, FunctionHash, RegionCounts);
|
||||
#endif
|
||||
|
||||
if (EC) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
auto IPE = llvm::InstrProfError::take(std::move(EC));
|
||||
#else
|
||||
auto IPE = EC;
|
||||
#endif
|
||||
if (IPE == llvm::instrprof_error::unknown_function) {
|
||||
IF_LOG Logger::println("No profile data for function: %s",
|
||||
FuncName.c_str());
|
||||
|
@ -936,11 +887,9 @@ void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
|
|||
return;
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
ProfRecord =
|
||||
llvm::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
|
||||
RegionCounts = ProfRecord->Counts;
|
||||
#endif
|
||||
|
||||
IF_LOG Logger::println("Loaded profile data for function: %s",
|
||||
FuncName.c_str());
|
||||
|
@ -1071,15 +1020,12 @@ llvm::MDNode *CodeGenPGO::createProfileWeightsForeachRange(
|
|||
|
||||
void CodeGenPGO::emitIndirectCallPGO(llvm::Instruction *callSite,
|
||||
llvm::Value *funcPtr) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (enablePGOIndirectCalls)
|
||||
valueProfile(llvm::IPVK_IndirectCallTarget, callSite, funcPtr, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CodeGenPGO::valueProfile(uint32_t valueKind, llvm::Instruction *valueSite,
|
||||
llvm::Value *value, bool ptrCastNeeded) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
if (!value || !valueSite)
|
||||
return;
|
||||
|
||||
|
@ -1117,5 +1063,4 @@ void CodeGenPGO::valueProfile(uint32_t valueKind, llvm::Instruction *valueSite,
|
|||
|
||||
NumValueSites[valueKind]++;
|
||||
}
|
||||
#endif // LLVM >= 3.9
|
||||
}
|
||||
|
|
|
@ -41,13 +41,8 @@ class ForeachRangeStatement;
|
|||
class CodeGenPGO {
|
||||
public:
|
||||
CodeGenPGO()
|
||||
: NumRegionCounters(0), FunctionHash(0), CurrentRegionCount(0)
|
||||
#if LDC_LLVM_VER >= 309
|
||||
,
|
||||
NumValueSites({{0}})
|
||||
#endif
|
||||
{
|
||||
}
|
||||
: NumRegionCounters(0), FunctionHash(0), CurrentRegionCount(0),
|
||||
NumValueSites({{0}}) {}
|
||||
|
||||
/// Whether or not we emit PGO instrumentation for the current function.
|
||||
bool emitsInstrumentation() const { return emitInstrumentation; }
|
||||
|
@ -150,10 +145,8 @@ private:
|
|||
std::vector<uint64_t> RegionCounts;
|
||||
uint64_t CurrentRegionCount;
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
std::array<unsigned, llvm::IPVK_Last + 1> NumValueSites;
|
||||
std::unique_ptr<llvm::InstrProfRecord> ProfRecord;
|
||||
#endif
|
||||
|
||||
/// \brief A flag that is set to false when instrumentation code should not be
|
||||
/// emitted for this function.
|
||||
|
@ -173,9 +166,6 @@ private:
|
|||
void setFuncName(llvm::Function *Fn);
|
||||
void setFuncName(llvm::StringRef Name,
|
||||
llvm::GlobalValue::LinkageTypes Linkage);
|
||||
#if LDC_LLVM_VER < 308
|
||||
void createFuncNameVar(llvm::GlobalValue::LinkageTypes Linkage);
|
||||
#endif
|
||||
void mapRegionCounters(const FuncDeclaration *D);
|
||||
void computeRegionCounts(const FuncDeclaration *D);
|
||||
void applyFunctionAttributes(llvm::Function *Fn);
|
||||
|
|
|
@ -40,13 +40,8 @@ RTTIBuilder::RTTIBuilder(Type *baseType) {
|
|||
void RTTIBuilder::push(llvm::Constant *C) {
|
||||
// We need to explicitly zero any padding bytes as per TDPL §7.1.1 (and
|
||||
// also match the struct type lowering code here).
|
||||
const uint64_t fieldStart =
|
||||
#if LDC_LLVM_VER >= 309
|
||||
llvm::alignTo
|
||||
#else
|
||||
llvm::RoundUpToAlignment
|
||||
#endif
|
||||
(prevFieldEnd, gDataLayout->getABITypeAlignment(C->getType()));
|
||||
const uint64_t fieldStart = llvm::alignTo(
|
||||
prevFieldEnd, gDataLayout->getABITypeAlignment(C->getType()));
|
||||
|
||||
const uint64_t paddingBytes = fieldStart - prevFieldEnd;
|
||||
if (paddingBytes) {
|
||||
|
|
|
@ -887,14 +887,12 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
|
|||
LLCallSite call =
|
||||
gIR->funcGen().callOrInvoke(callable, args, "", tf->isnothrow);
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
// PGO: Insert instrumentation or attach profile metadata at indirect call
|
||||
// sites.
|
||||
if (!call.getCalledFunction()) {
|
||||
auto &PGO = gIR->funcGen().pgo;
|
||||
PGO.emitIndirectCallPGO(call.getInstruction(), callable);
|
||||
}
|
||||
#endif
|
||||
|
||||
// get return value
|
||||
const int sretArgIndex =
|
||||
|
|
|
@ -189,11 +189,7 @@ public:
|
|||
llvm::GlobalValue::PrivateLinkage;
|
||||
gvar = new llvm::GlobalVariable(gIR->module, _init->getType(), true,
|
||||
_linkage, _init, ".str");
|
||||
#if LDC_LLVM_VER >= 309
|
||||
gvar->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
#else
|
||||
gvar->setUnnamedAddr(true);
|
||||
#endif
|
||||
(*stringLiteralCache)[key] = gvar;
|
||||
}
|
||||
|
||||
|
@ -523,12 +519,8 @@ public:
|
|||
auto gvar = new llvm::GlobalVariable(
|
||||
gIR->module, initval->getType(), canBeConst,
|
||||
llvm::GlobalValue::InternalLinkage, initval, ".dynarrayStorage");
|
||||
#if LDC_LLVM_VER >= 309
|
||||
gvar->setUnnamedAddr(canBeConst ? llvm::GlobalValue::UnnamedAddr::Global
|
||||
: llvm::GlobalValue::UnnamedAddr::None);
|
||||
#else
|
||||
gvar->setUnnamedAddr(canBeConst);
|
||||
#endif
|
||||
llvm::Constant *store = DtoBitCast(gvar, getPtrToType(arrtype));
|
||||
|
||||
if (bt->ty == Tpointer) {
|
||||
|
|
|
@ -398,11 +398,7 @@ public:
|
|||
}
|
||||
gvar = new llvm::GlobalVariable(gIR->module, at, true, _linkage, _init,
|
||||
".str");
|
||||
#if LDC_LLVM_VER >= 309
|
||||
gvar->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
#else
|
||||
gvar->setUnnamedAddr(true);
|
||||
#endif
|
||||
(*stringLiteralCache)[key] = gvar;
|
||||
}
|
||||
|
||||
|
|
|
@ -433,11 +433,7 @@ LLConstant *DtoConstCString(const char *str) {
|
|||
gvar = new llvm::GlobalVariable(gIR->module, init->getType(), true,
|
||||
llvm::GlobalValue::PrivateLinkage, init,
|
||||
".str");
|
||||
#if LDC_LLVM_VER >= 309
|
||||
gvar->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
#else
|
||||
gvar->setUnnamedAddr(true);
|
||||
#endif
|
||||
gIR->stringLiteral1ByteCache[s] = gvar;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,12 +40,10 @@ TryCatchScope::TryCatchScope(IRState &irs, llvm::Value *ehPtrSlot,
|
|||
return true;
|
||||
});
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (useMSVCEH()) {
|
||||
emitCatchBodiesMSVC(irs, ehPtrSlot);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
emitCatchBodies(irs, ehPtrSlot);
|
||||
}
|
||||
|
||||
|
@ -199,8 +197,6 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
|
|||
}
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
|
||||
namespace {
|
||||
void emitBeginCatchMSVC(IRState &irs, Catch *ctch,
|
||||
llvm::CatchSwitchInst *catchSwitchInst) {
|
||||
|
@ -331,18 +327,14 @@ void TryCatchScope::emitCatchBodiesMSVC(IRState &irs, llvm::Value *) {
|
|||
}
|
||||
}
|
||||
|
||||
#endif // LDC_LLVM_VER >= 308
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CleanupScope::CleanupScope(llvm::BasicBlock *beginBlock,
|
||||
llvm::BasicBlock *endBlock) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (useMSVCEH()) {
|
||||
findSuccessors(blocks, beginBlock, endBlock);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
blocks.push_back(beginBlock);
|
||||
if (endBlock != beginBlock)
|
||||
blocks.push_back(endBlock);
|
||||
|
@ -350,10 +342,8 @@ CleanupScope::CleanupScope(llvm::BasicBlock *beginBlock,
|
|||
|
||||
llvm::BasicBlock *CleanupScope::run(IRState &irs, llvm::BasicBlock *sourceBlock,
|
||||
llvm::BasicBlock *continueWith) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (useMSVCEH())
|
||||
return runCopying(irs, sourceBlock, continueWith);
|
||||
#endif
|
||||
|
||||
if (exitTargets.empty() || (exitTargets.size() == 1 &&
|
||||
exitTargets[0].branchTarget == continueWith)) {
|
||||
|
@ -434,7 +424,6 @@ llvm::BasicBlock *CleanupScope::run(IRState &irs, llvm::BasicBlock *sourceBlock,
|
|||
return beginBlock();
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
llvm::BasicBlock *CleanupScope::runCopying(IRState &irs,
|
||||
llvm::BasicBlock *sourceBlock,
|
||||
llvm::BasicBlock *continueWith,
|
||||
|
@ -485,7 +474,6 @@ llvm::BasicBlock *CleanupScope::runCopying(IRState &irs,
|
|||
}
|
||||
return exitTarget.cleanupBlocks.front();
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -523,9 +511,7 @@ void TryCatchFinallyScopes::pushTryCatch(TryCatchStatement *stmt,
|
|||
void TryCatchFinallyScopes::popTryCatch() {
|
||||
tryCatchScopes.pop_back();
|
||||
if (useMSVCEH()) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
assert(isCatchSwitchBlock(cleanupScopes.back().beginBlock()));
|
||||
#endif
|
||||
popCleanups(currentCleanupScope() - 1);
|
||||
} else {
|
||||
landingPadsPerCleanupScope[currentCleanupScope()].pop_back();
|
||||
|
@ -593,12 +579,10 @@ void TryCatchFinallyScopes::runCleanups(CleanupCursor targetScope,
|
|||
void TryCatchFinallyScopes::runCleanups(CleanupCursor sourceScope,
|
||||
CleanupCursor targetScope,
|
||||
llvm::BasicBlock *continueWith) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (useMSVCEH()) {
|
||||
runCleanupCopies(sourceScope, targetScope, continueWith);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(targetScope <= sourceScope);
|
||||
|
||||
|
@ -620,7 +604,6 @@ void TryCatchFinallyScopes::runCleanups(CleanupCursor sourceScope,
|
|||
}
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
void TryCatchFinallyScopes::runCleanupCopies(CleanupCursor sourceScope,
|
||||
CleanupCursor targetScope,
|
||||
llvm::BasicBlock *continueWith) {
|
||||
|
@ -635,7 +618,6 @@ void TryCatchFinallyScopes::runCleanupCopies(CleanupCursor sourceScope,
|
|||
// Insert the unconditional branch to the first cleanup block.
|
||||
irs.ir->CreateBr(continueWith);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -705,12 +687,10 @@ namespace {
|
|||
}
|
||||
|
||||
llvm::BasicBlock *TryCatchFinallyScopes::emitLandingPad() {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (useMSVCEH()) {
|
||||
assert(currentCleanupScope() > 0);
|
||||
return emitLandingPadMSVC(currentCleanupScope() - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// save and rewrite scope
|
||||
IRScope savedIRScope = irs.scope();
|
||||
|
@ -815,7 +795,6 @@ llvm::BasicBlock *TryCatchFinallyScopes::getOrCreateResumeUnwindBlock() {
|
|||
return resumeUnwindBlock;
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 308
|
||||
llvm::BasicBlock *
|
||||
TryCatchFinallyScopes::emitLandingPadMSVC(CleanupCursor cleanupScope) {
|
||||
if (!irs.func()->hasLLVMPersonalityFn()) {
|
||||
|
@ -895,4 +874,3 @@ TryCatchFinallyScopes::runCleanupPad(CleanupCursor scope,
|
|||
|
||||
return cleanupbb;
|
||||
}
|
||||
#endif
|
||||
|
|
15
gen/uda.cpp
15
gen/uda.cpp
|
@ -15,7 +15,6 @@
|
|||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
namespace llvm {
|
||||
// Auto-generate:
|
||||
// Attribute::AttrKind getAttrKindFromName(StringRef AttrName) { ... }
|
||||
|
@ -26,7 +25,6 @@ namespace llvm {
|
|||
#include "llvm/IR/Attributes.inc"
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -172,8 +170,6 @@ void applyAttrAllocSize(StructLiteralExp *sle, IrFunction *irFunc) {
|
|||
if (error)
|
||||
return;
|
||||
|
||||
// The allocSize attribute is only effective for LLVM >= 3.9.
|
||||
#if LDC_LLVM_VER >= 309
|
||||
// Get the number of parameters of the function in LLVM IR. This includes
|
||||
// the `this` and sret parameters.
|
||||
const auto llvmNumParams = irFunc->irFty.funcType->getNumParams();
|
||||
|
@ -208,7 +204,6 @@ void applyAttrAllocSize(StructLiteralExp *sle, IrFunction *irFunc) {
|
|||
LLAttributeSet::FunctionIndex,
|
||||
builder));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// @llvmAttr("key", "value")
|
||||
|
@ -218,18 +213,10 @@ void applyAttrLLVMAttr(StructLiteralExp *sle, llvm::Function *func) {
|
|||
llvm::StringRef key = getStringElem(sle, 0);
|
||||
llvm::StringRef value = getStringElem(sle, 1);
|
||||
if (value.empty()) {
|
||||
#if LDC_LLVM_VER >= 309
|
||||
const auto kind = llvm::getAttrKindFromName(key);
|
||||
if (kind != llvm::Attribute::None) {
|
||||
func->addFnAttr(kind);
|
||||
}
|
||||
#else
|
||||
// no getAttrKindFromName(); just detect `naked` for now
|
||||
if (key == "naked") {
|
||||
func->addFnAttr(llvm::Attribute::Naked);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
func->addFnAttr(key);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -386,13 +386,8 @@ void IrAggr::defineInterfaceVtbl(BaseClass *b, bool new_instance,
|
|||
setLinkage(lwc, thunk);
|
||||
thunk->copyAttributesFrom(callee);
|
||||
|
||||
// Thunks themselves don't have an identity, only the target
|
||||
// function has.
|
||||
#if LDC_LLVM_VER >= 309
|
||||
// Thunks themselves don't have an identity, only the target function has.
|
||||
thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
||||
#else
|
||||
thunk->setUnnamedAddr(true);
|
||||
#endif
|
||||
|
||||
// thunks don't need exception handling themselves
|
||||
thunk->setPersonalityFn(nullptr);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 7f0e6cfe7b333430180deb16e7e28b0c7db12ac1
|
||||
Subproject commit aa5c90eb86c8228fa70a6b6ab4ac1b092054b3be
|
|
@ -13,7 +13,6 @@ else()
|
|||
endif()
|
||||
|
||||
function(get_host_arch var_name)
|
||||
if(LDC_LLVM_VER GREATER 308)
|
||||
# HACK!
|
||||
# LLVMConfig provide useful LLVM_NATIVE_ARCH variable which is not
|
||||
# provided from our FindLLVM nor from llvm-config.
|
||||
|
@ -23,9 +22,6 @@ function(get_host_arch var_name)
|
|||
include("${LLVM_CMAKEDIR}/LLVMConfig.cmake")
|
||||
include("${LLVM_CMAKEDIR}/LLVM-Config.cmake")
|
||||
set(${var_name} ${LLVM_NATIVE_ARCH} PARENT_SCOPE)
|
||||
else()
|
||||
set(${var_name} "" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
get_host_arch(LDC_HOST_ARCH)
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
// REQUIRES: PGO_RT
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// RUN: %ldc -c -output-ll -fprofile-instr-generate -of=%t.ll %s && FileCheck %s --check-prefix=PROFGEN < %t.ll
|
||||
|
||||
// RUN: %ldc -fprofile-instr-generate=%t.profraw -run %s \
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
// REQUIRES: PGO_RT
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// RUN: %ldc -O3 -fprofile-generate=%t.profraw -run %s \
|
||||
// RUN: && %profdata merge %t.profraw -o %t.profdata \
|
||||
// RUN: && %ldc -O3 -c -output-ll -of=%t.use.ll -fprofile-use=%t.profdata %s \
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Test that maximum function counts are set correctly (LLVM >= 3.8)
|
||||
// Test that maximum function counts are set correctly
|
||||
|
||||
// REQUIRES: PGO_RT
|
||||
// REQUIRES: atleast_llvm308
|
||||
// For LLVM > 3.8, a summary is emitted, see summary.d
|
||||
|
||||
// RUN: %ldc -fprofile-instr-generate=%t.profraw -run %s \
|
||||
// RUN: && %profdata merge %t.profraw -o %t.profdata \
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// Test that maximum function counts are set correctly (LLVM >= 3.8)
|
||||
// REQUIRES: atleast_llvm309
|
||||
// Test that maximum function counts are set correctly
|
||||
// REQUIRES: PGO_RT
|
||||
|
||||
// RUN: %ldc -fprofile-instr-generate=%t.profraw -run %s \
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Test ldc.attributes.allocSize
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// RUN: %ldc -O3 -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
import ldc.attributes;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// REQUIRES: atleast_llvm309
|
||||
// REQUIRES: target_NVPTX
|
||||
// RUN: %ldc -c -mdcompute-targets=cuda-350 -m64 -mdcompute-file-prefix=addrspace -output-ll -output-o %s && FileCheck %s --check-prefix=LL < addrspace_cuda350_64.ll && FileCheck %s --check-prefix=PTX < addrspace_cuda350_64.ptx
|
||||
@compute(CompileFor.deviceOnly) module dcompute_cu_addrspaces;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// Check that we can generate code for both the host and device in one compiler invocation
|
||||
// REQUIRES: atleast_llvm309
|
||||
// REQUIRES: target_NVPTX
|
||||
// RUN: %ldc -mdcompute-targets=cuda-350 -mdcompute-file-prefix=host_and_device -Iinputs %s %S/inputs/kernel.d
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Test value name discarding when creating non-textual IR.
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// RUN: %ldc %S/inputs/input_discard_valuename.d -c -output-ll -of=%t.bar.ll && FileCheck %S/inputs/input_discard_valuename.d < %t.bar.ll
|
||||
|
||||
// Output a bitcode file (i.e. with discarded names) and input it into a second LDC command that outputs textual IR.
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Test value name discarding in conjunction with the compile cache: local variable name changes should still give a cache hit.
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// Create and then empty the cache for correct testing when running the test multiple times.
|
||||
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir
|
||||
// RUN: %prunecache -f %t-dir --max-bytes=1
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
// test that at -O3, LLVM was able to analyse the function correctly and
|
||||
// optimize-out the va_start and va_end calls and remove the call to
|
||||
// return_two (Github #1744).
|
||||
// The optimization (removing back-to-back calls to va_start and va_end) only
|
||||
// happens from LLVM >= 3.9.
|
||||
// REQUIRES: atleast_llvm309
|
||||
// RUN: %ldc %s -c -output-ll -O3 -of=%t.O3.ll \
|
||||
// RUN: && FileCheck %s --check-prefix OPT3 < %t.O3.ll
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ elseif(${ptr_size} MATCHES "^8$")
|
|||
endif()
|
||||
|
||||
set(gdb_dflags "")
|
||||
if((${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND (${LDC_LLVM_VER} GREATER 307))
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
execute_process(COMMAND gdb --version
|
||||
COMMAND head -n 1
|
||||
OUTPUT_VARIABLE GDB_VERSION
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// REQUIRES: Windows
|
||||
// REQUIRES: cdb
|
||||
// RUN: %ldc -g -of=%t.exe %s
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// REQUIRES: Windows
|
||||
// REQUIRES: cdb
|
||||
// RUN: %ldc -g -of=%t.exe %s
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// REQUIRES: Windows
|
||||
// REQUIRES: cdb
|
||||
// RUN: %ldc -g -of=%t.exe %s
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// REQUIRES: atleast_llvm308
|
||||
|
||||
// REQUIRES: gdb
|
||||
// RUN: %ldc %_gdb_dflags -g -of=%t %s
|
||||
// RUN: sed -e "/^\\/\\/ GDB:/!d" -e "s,// GDB:,," %s >%t.gdb
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
// RUN: %ldc -gline-tables-only --output-ll -of%t.ll %s && FileCheck %s < %t.ll
|
||||
// checks that ldc with -gline-tables-only do not emit debug info
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
// reason: different llvm version emits far different metadata in IR code
|
||||
|
||||
int main()
|
||||
{
|
||||
immutable int fact=6;
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
// compile unit, subprogram and file.
|
||||
// Also checks that no type attributes are emitted
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
// reason: different llvm version emits far different metadata in IR code
|
||||
|
||||
int main() {
|
||||
// CHECK: ret i32 0, !dbg
|
||||
return 0;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// Checks that !dbg is being attached to MSVC EH/cleanup runtime calls.
|
||||
// REQUIRES: atleast_llvm308
|
||||
// REQUIRES: Windows
|
||||
// RUN: %ldc -g -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// Tests debug info generation for nested functions
|
||||
// REQUIRES: atleast_llvm308
|
||||
// RUN: %ldc -g -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
// CHECK: define {{.*}} @{{.*}}_D6nested8encloserFiiZv
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
// Tests debug info generation for nested functions
|
||||
// REQUIRES: llvm307
|
||||
// RUN: %ldc -g -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @{{.*}}_D14nested_llvm3078encloserFiiZv
|
||||
void encloser(int arg0, int arg1)
|
||||
{
|
||||
// CHECK: @llvm.dbg.declare{{.*}}%enc_n{{.*}}enc_n
|
||||
int enc_n;
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @{{.*}}_D14nested_llvm3078encloserFiiZ6nestedMFNaNbNiNfiZv
|
||||
void nested(int nes_i)
|
||||
{
|
||||
// CHECK: %arg0 = getelementptr inbounds %nest.encloser
|
||||
// CHECK: @llvm.dbg.declare{{.*}}%arg0
|
||||
// CHECK: %arg1 = getelementptr inbounds %nest.encloser
|
||||
// CHECK: @llvm.dbg.declare{{.*}}%arg1
|
||||
// CHECK: %enc_n = getelementptr inbounds %nest.encloser
|
||||
// CHECK: @llvm.dbg.declare{{.*}}%enc_n
|
||||
arg0 = arg1 = enc_n = nes_i; // accessing arg0, arg1 and enc_n from a nested function turns them into closure variables
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: !DISubprogram(name:{{.*}}"{{.*}}.encloser"
|
||||
// CHECK-SAME: function: void {{.*}} @_D{{.*}}8encloserFiiZv
|
||||
// CHECK-LABEL: !DISubprogram(name:{{.*}}"{{.*}}.encloser.nested"
|
||||
// CHECK: !DILocalVariable{{.*}}DW_TAG_arg_variable{{.*}}nes_i
|
||||
// CHECK: !DILocalVariable{{.*}}DW_TAG_auto_variable{{.*}}arg1
|
|
@ -1,4 +1,4 @@
|
|||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// REQUIRES: Windows
|
||||
// REQUIRES: cdb
|
||||
// RUN: %ldc -g -of=%t.exe %s
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// REQUIRES: atleast_llvm309
|
||||
|
||||
// REQUIRES: Windows
|
||||
// REQUIRES: cdb
|
||||
// RUN: %ldc -g -of=%t.exe %s
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// REQUIRES: atleast_llvm308
|
||||
// RUN: %ldc -c %s @%S/gh1941.rsp 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: 'foo.conf' not found
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Test full LTO commandline flag
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
// REQUIRES: LTO
|
||||
|
||||
// RUN: %ldc %s -of=%t%obj -c -flto=full -vv | FileCheck %s
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Test ThinLTO commandline flag
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
// REQUIRES: LTO
|
||||
|
||||
// RUN: %ldc %s -of=%t%obj -c -flto=thin -vv | FileCheck %s
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// ThinLTO: Test inline assembly functions with thinlto
|
||||
|
||||
// REQUIRES: atleast_llvm309
|
||||
// REQUIRES: LTO
|
||||
// REQUIRES: host_X86
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// REQUIRES: atleast_llvm309
|
||||
// REQUIRES: LTO
|
||||
|
||||
// RUN: %ldc -flto=thin -O3 %S/inputs/thinlto_ctor.d -run %s | FileCheck --check-prefix=EXECUTE %s
|
||||
|
|
|
@ -65,11 +65,11 @@ if env_cxx:
|
|||
|
||||
# Define available features so that we can disable tests depending on LLVM version
|
||||
config.available_features.add("llvm%d" % config.llvm_version)
|
||||
# LLVM version history: 3.8, 3.9, 4.0, 5.0, ...
|
||||
# config.llvm_version: 308, 309, 400, 500, ...
|
||||
# plusoneable_llvmversion: 38, 39, 40, 50, ...
|
||||
# LLVM version history: 3.9, 4.0, 5.0, ...
|
||||
# config.llvm_version: 309, 400, 500, ...
|
||||
# plusoneable_llvmversion: 39, 40, 50, ...
|
||||
plusoneable_llvmversion = config.llvm_version // 10 + config.llvm_version%10
|
||||
for version in range(37, plusoneable_llvmversion+1):
|
||||
for version in range(39, plusoneable_llvmversion+1):
|
||||
config.available_features.add("atleast_llvm%d0%d" % (version//10, version%10))
|
||||
for version in range(plusoneable_llvmversion, 91):
|
||||
config.available_features.add("atmost_llvm%d0%d" % (version//10, version%10))
|
||||
|
@ -96,7 +96,6 @@ if (config.ldc_host_arch != ''):
|
|||
# Add "LTO" feature if linker support and LTO plugin are available
|
||||
# (LTO is supported from LLVM 3.9)
|
||||
canDoLTO = False
|
||||
if (config.llvm_version >= 309):
|
||||
if (platform.system() == 'Darwin'):
|
||||
command = ['ld', '-v']
|
||||
p = subprocess.Popen(command, stdout=subprocess.PIPE,
|
||||
|
|
|
@ -1,288 +0,0 @@
|
|||
//===- llvm-profdata.cpp - LLVM profile data tool -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// llvm-profdata merges .profdata files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/ProfileData/InstrProfReader.h"
|
||||
#include "llvm/ProfileData/InstrProfWriter.h"
|
||||
#include "llvm/ProfileData/SampleProfReader.h"
|
||||
#include "llvm/ProfileData/SampleProfWriter.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static void exitWithError(const Twine &Message, StringRef Whence = "") {
|
||||
errs() << "error: ";
|
||||
if (!Whence.empty())
|
||||
errs() << Whence << ": ";
|
||||
errs() << Message << "\n";
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
namespace {
|
||||
enum ProfileKinds { instr, sample };
|
||||
}
|
||||
|
||||
static void mergeInstrProfile(const cl::list<std::string> &Inputs,
|
||||
StringRef OutputFilename) {
|
||||
if (OutputFilename.compare("-") == 0)
|
||||
exitWithError("Cannot write indexed profdata format to stdout.");
|
||||
|
||||
std::error_code EC;
|
||||
raw_fd_ostream Output(OutputFilename.data(), EC, sys::fs::F_None);
|
||||
if (EC)
|
||||
exitWithError(EC.message(), OutputFilename);
|
||||
|
||||
InstrProfWriter Writer;
|
||||
for (const auto &Filename : Inputs) {
|
||||
auto ReaderOrErr = InstrProfReader::create(Filename);
|
||||
if (std::error_code ec = ReaderOrErr.getError())
|
||||
exitWithError(ec.message(), Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
for (const auto &I : *Reader)
|
||||
if (std::error_code EC =
|
||||
Writer.addFunctionCounts(I.Name, I.Hash, I.Counts))
|
||||
errs() << Filename << ": " << I.Name << ": " << EC.message() << "\n";
|
||||
if (Reader->hasError())
|
||||
exitWithError(Reader->getError().message(), Filename);
|
||||
}
|
||||
Writer.write(Output);
|
||||
}
|
||||
|
||||
static void mergeSampleProfile(const cl::list<std::string> &Inputs,
|
||||
StringRef OutputFilename,
|
||||
sampleprof::SampleProfileFormat OutputFormat) {
|
||||
using namespace sampleprof;
|
||||
auto WriterOrErr = SampleProfileWriter::create(OutputFilename, OutputFormat);
|
||||
if (std::error_code EC = WriterOrErr.getError())
|
||||
exitWithError(EC.message(), OutputFilename);
|
||||
|
||||
auto Writer = std::move(WriterOrErr.get());
|
||||
StringMap<FunctionSamples> ProfileMap;
|
||||
for (const auto &Filename : Inputs) {
|
||||
auto ReaderOrErr =
|
||||
SampleProfileReader::create(Filename, getGlobalContext());
|
||||
if (std::error_code EC = ReaderOrErr.getError())
|
||||
exitWithError(EC.message(), Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
if (std::error_code EC = Reader->read())
|
||||
exitWithError(EC.message(), Filename);
|
||||
|
||||
StringMap<FunctionSamples> &Profiles = Reader->getProfiles();
|
||||
for (StringMap<FunctionSamples>::iterator I = Profiles.begin(),
|
||||
E = Profiles.end();
|
||||
I != E; ++I) {
|
||||
StringRef FName = I->first();
|
||||
FunctionSamples &Samples = I->second;
|
||||
ProfileMap[FName].merge(Samples);
|
||||
}
|
||||
}
|
||||
Writer->write(ProfileMap);
|
||||
}
|
||||
|
||||
static int merge_main(int argc, const char *argv[]) {
|
||||
cl::list<std::string> Inputs(cl::Positional, cl::Required, cl::OneOrMore,
|
||||
cl::desc("<filenames...>"));
|
||||
|
||||
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
|
||||
cl::init("-"), cl::Required,
|
||||
cl::desc("Output file"));
|
||||
cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
|
||||
cl::aliasopt(OutputFilename));
|
||||
cl::opt<ProfileKinds> ProfileKind(
|
||||
cl::desc("Profile kind:"), cl::init(instr),
|
||||
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
|
||||
clEnumVal(sample, "Sample profile"), clEnumValEnd));
|
||||
|
||||
cl::opt<sampleprof::SampleProfileFormat> OutputFormat(
|
||||
cl::desc("Format of output profile (only meaningful with --sample)"),
|
||||
cl::init(sampleprof::SPF_Binary),
|
||||
cl::values(clEnumValN(sampleprof::SPF_Binary, "binary",
|
||||
"Binary encoding (default)"),
|
||||
clEnumValN(sampleprof::SPF_Text, "text", "Text encoding"),
|
||||
clEnumValN(sampleprof::SPF_GCC, "gcc", "GCC encoding"),
|
||||
clEnumValEnd));
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n");
|
||||
|
||||
if (ProfileKind == instr)
|
||||
mergeInstrProfile(Inputs, OutputFilename);
|
||||
else
|
||||
mergeSampleProfile(Inputs, OutputFilename, OutputFormat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int showInstrProfile(std::string Filename, bool ShowCounts,
|
||||
bool ShowAllFunctions, std::string ShowFunction,
|
||||
raw_fd_ostream &OS) {
|
||||
auto ReaderOrErr = InstrProfReader::create(Filename);
|
||||
if (std::error_code EC = ReaderOrErr.getError())
|
||||
exitWithError(EC.message(), Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
uint64_t MaxFunctionCount = 0, MaxBlockCount = 0;
|
||||
size_t ShownFunctions = 0, TotalFunctions = 0;
|
||||
for (const auto &Func : *Reader) {
|
||||
bool Show =
|
||||
ShowAllFunctions || (!ShowFunction.empty() &&
|
||||
Func.Name.find(ShowFunction) != Func.Name.npos);
|
||||
|
||||
++TotalFunctions;
|
||||
assert(Func.Counts.size() > 0 && "function missing entry counter");
|
||||
if (Func.Counts[0] > MaxFunctionCount)
|
||||
MaxFunctionCount = Func.Counts[0];
|
||||
|
||||
if (Show) {
|
||||
if (!ShownFunctions)
|
||||
OS << "Counters:\n";
|
||||
++ShownFunctions;
|
||||
|
||||
OS << " " << Func.Name << ":\n"
|
||||
<< " Hash: " << format("0x%016" PRIx64, Func.Hash) << "\n"
|
||||
<< " Counters: " << Func.Counts.size() << "\n"
|
||||
<< " Function count: " << Func.Counts[0] << "\n";
|
||||
}
|
||||
|
||||
if (Show && ShowCounts)
|
||||
OS << " Block counts: [";
|
||||
for (size_t I = 1, E = Func.Counts.size(); I < E; ++I) {
|
||||
if (Func.Counts[I] > MaxBlockCount)
|
||||
MaxBlockCount = Func.Counts[I];
|
||||
if (Show && ShowCounts)
|
||||
OS << (I == 1 ? "" : ", ") << Func.Counts[I];
|
||||
}
|
||||
if (Show && ShowCounts)
|
||||
OS << "]\n";
|
||||
}
|
||||
if (Reader->hasError())
|
||||
exitWithError(Reader->getError().message(), Filename);
|
||||
|
||||
if (ShowAllFunctions || !ShowFunction.empty())
|
||||
OS << "Functions shown: " << ShownFunctions << "\n";
|
||||
OS << "Total functions: " << TotalFunctions << "\n";
|
||||
OS << "Maximum function count: " << MaxFunctionCount << "\n";
|
||||
OS << "Maximum internal block count: " << MaxBlockCount << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int showSampleProfile(std::string Filename, bool ShowCounts,
|
||||
bool ShowAllFunctions, std::string ShowFunction,
|
||||
raw_fd_ostream &OS) {
|
||||
using namespace sampleprof;
|
||||
auto ReaderOrErr = SampleProfileReader::create(Filename, getGlobalContext());
|
||||
if (std::error_code EC = ReaderOrErr.getError())
|
||||
exitWithError(EC.message(), Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
Reader->read();
|
||||
if (ShowAllFunctions || ShowFunction.empty())
|
||||
Reader->dump(OS);
|
||||
else
|
||||
Reader->dumpFunctionProfile(ShowFunction, OS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_main(int argc, const char *argv[]) {
|
||||
cl::opt<std::string> Filename(cl::Positional, cl::Required,
|
||||
cl::desc("<profdata-file>"));
|
||||
|
||||
cl::opt<bool> ShowCounts("counts", cl::init(false),
|
||||
cl::desc("Show counter values for shown functions"));
|
||||
cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
|
||||
cl::desc("Details for every function"));
|
||||
cl::opt<std::string> ShowFunction("function",
|
||||
cl::desc("Details for matching functions"));
|
||||
|
||||
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
|
||||
cl::init("-"), cl::desc("Output file"));
|
||||
cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
|
||||
cl::aliasopt(OutputFilename));
|
||||
cl::opt<ProfileKinds> ProfileKind(
|
||||
cl::desc("Profile kind:"), cl::init(instr),
|
||||
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
|
||||
clEnumVal(sample, "Sample profile"), clEnumValEnd));
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n");
|
||||
|
||||
if (OutputFilename.empty())
|
||||
OutputFilename = "-";
|
||||
|
||||
std::error_code EC;
|
||||
raw_fd_ostream OS(OutputFilename.data(), EC, sys::fs::F_Text);
|
||||
if (EC)
|
||||
exitWithError(EC.message(), OutputFilename);
|
||||
|
||||
if (ShowAllFunctions && !ShowFunction.empty())
|
||||
errs() << "warning: -function argument ignored: showing all functions\n";
|
||||
|
||||
if (ProfileKind == instr)
|
||||
return showInstrProfile(Filename, ShowCounts, ShowAllFunctions,
|
||||
ShowFunction, OS);
|
||||
else
|
||||
return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
|
||||
ShowFunction, OS);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
// Print a stack trace if we signal out.
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
PrettyStackTraceProgram X(argc, argv);
|
||||
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
|
||||
|
||||
StringRef ProgName(sys::path::filename(argv[0]));
|
||||
if (argc > 1) {
|
||||
int (*func)(int, const char *[]) = nullptr;
|
||||
|
||||
if (strcmp(argv[1], "merge") == 0)
|
||||
func = merge_main;
|
||||
else if (strcmp(argv[1], "show") == 0)
|
||||
func = show_main;
|
||||
|
||||
if (func) {
|
||||
std::string Invocation(ProgName.str() + " " + argv[1]);
|
||||
argv[1] = Invocation.c_str();
|
||||
return func(argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "-h") == 0 ||
|
||||
strcmp(argv[1], "-help") == 0 ||
|
||||
strcmp(argv[1], "--help") == 0) {
|
||||
|
||||
errs() << "OVERVIEW: LLVM profile data tools\n\n"
|
||||
<< "USAGE: " << ProgName << " <command> [args...]\n"
|
||||
<< "USAGE: " << ProgName << " <command> -help\n\n"
|
||||
<< "Available commands: merge, show\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
errs() << ProgName << ": No command specified!\n";
|
||||
else
|
||||
errs() << ProgName << ": Unknown command!\n";
|
||||
|
||||
errs() << "USAGE: " << ProgName << " <merge|show> [args...]\n";
|
||||
return 1;
|
||||
}
|
|
@ -1,447 +0,0 @@
|
|||
//===- llvm-profdata.cpp - LLVM profile data tool -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// llvm-profdata merges .profdata files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/ProfileData/InstrProfReader.h"
|
||||
#include "llvm/ProfileData/InstrProfWriter.h"
|
||||
#include "llvm/ProfileData/SampleProfReader.h"
|
||||
#include "llvm/ProfileData/SampleProfWriter.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
enum ProfileFormat { PF_None = 0, PF_Text, PF_Binary, PF_GCC };
|
||||
|
||||
static void exitWithError(const Twine &Message, StringRef Whence = "",
|
||||
StringRef Hint = "") {
|
||||
errs() << "error: ";
|
||||
if (!Whence.empty())
|
||||
errs() << Whence << ": ";
|
||||
errs() << Message << "\n";
|
||||
if (!Hint.empty())
|
||||
errs() << Hint << "\n";
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
static void exitWithErrorCode(const std::error_code &Error,
|
||||
StringRef Whence = "") {
|
||||
if (Error.category() == instrprof_category()) {
|
||||
instrprof_error instrError = static_cast<instrprof_error>(Error.value());
|
||||
if (instrError == instrprof_error::unrecognized_format) {
|
||||
// Hint for common error of forgetting -sample for sample profiles.
|
||||
exitWithError(Error.message(), Whence,
|
||||
"Perhaps you forgot to use the -sample option?");
|
||||
}
|
||||
}
|
||||
exitWithError(Error.message(), Whence);
|
||||
}
|
||||
|
||||
namespace {
|
||||
enum ProfileKinds { instr, sample };
|
||||
}
|
||||
|
||||
static void handleMergeWriterError(std::error_code &Error,
|
||||
StringRef WhenceFile = "",
|
||||
StringRef WhenceFunction = "",
|
||||
bool ShowHint = true) {
|
||||
if (!WhenceFile.empty())
|
||||
errs() << WhenceFile << ": ";
|
||||
if (!WhenceFunction.empty())
|
||||
errs() << WhenceFunction << ": ";
|
||||
errs() << Error.message() << "\n";
|
||||
|
||||
if (ShowHint) {
|
||||
StringRef Hint = "";
|
||||
if (Error.category() == instrprof_category()) {
|
||||
instrprof_error instrError = static_cast<instrprof_error>(Error.value());
|
||||
switch (instrError) {
|
||||
case instrprof_error::hash_mismatch:
|
||||
case instrprof_error::count_mismatch:
|
||||
case instrprof_error::value_site_count_mismatch:
|
||||
Hint = "Make sure that all profile data to be merged is generated "
|
||||
"from the same binary.";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Hint.empty())
|
||||
errs() << Hint << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
struct WeightedFile {
|
||||
StringRef Filename;
|
||||
uint64_t Weight;
|
||||
|
||||
WeightedFile() {}
|
||||
|
||||
WeightedFile(StringRef F, uint64_t W) : Filename{F}, Weight{W} {}
|
||||
};
|
||||
typedef SmallVector<WeightedFile, 5> WeightedFileVector;
|
||||
|
||||
static void mergeInstrProfile(const WeightedFileVector &Inputs,
|
||||
StringRef OutputFilename,
|
||||
ProfileFormat OutputFormat) {
|
||||
if (OutputFilename.compare("-") == 0)
|
||||
exitWithError("Cannot write indexed profdata format to stdout.");
|
||||
|
||||
if (OutputFormat != PF_Binary && OutputFormat != PF_Text)
|
||||
exitWithError("Unknown format is specified.");
|
||||
|
||||
std::error_code EC;
|
||||
raw_fd_ostream Output(OutputFilename.data(), EC, sys::fs::F_None);
|
||||
if (EC)
|
||||
exitWithErrorCode(EC, OutputFilename);
|
||||
|
||||
InstrProfWriter Writer;
|
||||
SmallSet<std::error_code, 4> WriterErrorCodes;
|
||||
for (const auto &Input : Inputs) {
|
||||
auto ReaderOrErr = InstrProfReader::create(Input.Filename);
|
||||
if (std::error_code ec = ReaderOrErr.getError())
|
||||
exitWithErrorCode(ec, Input.Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
for (auto &I : *Reader) {
|
||||
if (std::error_code EC = Writer.addRecord(std::move(I), Input.Weight)) {
|
||||
// Only show hint the first time an error occurs.
|
||||
bool firstTime = WriterErrorCodes.insert(EC).second;
|
||||
handleMergeWriterError(EC, Input.Filename, I.Name, firstTime);
|
||||
}
|
||||
}
|
||||
if (Reader->hasError())
|
||||
exitWithErrorCode(Reader->getError(), Input.Filename);
|
||||
}
|
||||
if (OutputFormat == PF_Text)
|
||||
Writer.writeText(Output);
|
||||
else
|
||||
Writer.write(Output);
|
||||
}
|
||||
|
||||
static sampleprof::SampleProfileFormat FormatMap[] = {
|
||||
sampleprof::SPF_None, sampleprof::SPF_Text, sampleprof::SPF_Binary,
|
||||
sampleprof::SPF_GCC};
|
||||
|
||||
static void mergeSampleProfile(const WeightedFileVector &Inputs,
|
||||
StringRef OutputFilename,
|
||||
ProfileFormat OutputFormat) {
|
||||
using namespace sampleprof;
|
||||
auto WriterOrErr =
|
||||
SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]);
|
||||
if (std::error_code EC = WriterOrErr.getError())
|
||||
exitWithErrorCode(EC, OutputFilename);
|
||||
|
||||
auto Writer = std::move(WriterOrErr.get());
|
||||
StringMap<FunctionSamples> ProfileMap;
|
||||
SmallVector<std::unique_ptr<sampleprof::SampleProfileReader>, 5> Readers;
|
||||
for (const auto &Input : Inputs) {
|
||||
auto ReaderOrErr =
|
||||
SampleProfileReader::create(Input.Filename, getGlobalContext());
|
||||
if (std::error_code EC = ReaderOrErr.getError())
|
||||
exitWithErrorCode(EC, Input.Filename);
|
||||
|
||||
// We need to keep the readers around until after all the files are
|
||||
// read so that we do not lose the function names stored in each
|
||||
// reader's memory. The function names are needed to write out the
|
||||
// merged profile map.
|
||||
Readers.push_back(std::move(ReaderOrErr.get()));
|
||||
const auto Reader = Readers.back().get();
|
||||
if (std::error_code EC = Reader->read())
|
||||
exitWithErrorCode(EC, Input.Filename);
|
||||
|
||||
StringMap<FunctionSamples> &Profiles = Reader->getProfiles();
|
||||
for (StringMap<FunctionSamples>::iterator I = Profiles.begin(),
|
||||
E = Profiles.end();
|
||||
I != E; ++I) {
|
||||
StringRef FName = I->first();
|
||||
FunctionSamples &Samples = I->second;
|
||||
sampleprof_error Result = ProfileMap[FName].merge(Samples, Input.Weight);
|
||||
if (Result != sampleprof_error::success) {
|
||||
std::error_code EC = make_error_code(Result);
|
||||
handleMergeWriterError(EC, Input.Filename, FName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Writer->write(ProfileMap);
|
||||
}
|
||||
|
||||
static WeightedFile parseWeightedFile(const StringRef &WeightedFilename) {
|
||||
StringRef WeightStr, FileName;
|
||||
std::tie(WeightStr, FileName) = WeightedFilename.split(',');
|
||||
|
||||
uint64_t Weight;
|
||||
if (WeightStr.getAsInteger(10, Weight) || Weight < 1)
|
||||
exitWithError("Input weight must be a positive integer.");
|
||||
|
||||
if (!sys::fs::exists(FileName))
|
||||
exitWithErrorCode(make_error_code(errc::no_such_file_or_directory),
|
||||
FileName);
|
||||
|
||||
return WeightedFile(FileName, Weight);
|
||||
}
|
||||
|
||||
static int merge_main(int argc, const char *argv[]) {
|
||||
cl::list<std::string> InputFilenames(cl::Positional,
|
||||
cl::desc("<filename...>"));
|
||||
cl::list<std::string> WeightedInputFilenames("weighted-input",
|
||||
cl::desc("<weight>,<filename>"));
|
||||
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
|
||||
cl::init("-"), cl::Required,
|
||||
cl::desc("Output file"));
|
||||
cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
|
||||
cl::aliasopt(OutputFilename));
|
||||
cl::opt<ProfileKinds> ProfileKind(
|
||||
cl::desc("Profile kind:"), cl::init(instr),
|
||||
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
|
||||
clEnumVal(sample, "Sample profile"), clEnumValEnd));
|
||||
|
||||
cl::opt<ProfileFormat> OutputFormat(
|
||||
cl::desc("Format of output profile"), cl::init(PF_Binary),
|
||||
cl::values(clEnumValN(PF_Binary, "binary", "Binary encoding (default)"),
|
||||
clEnumValN(PF_Text, "text", "Text encoding"),
|
||||
clEnumValN(PF_GCC, "gcc",
|
||||
"GCC encoding (only meaningful for -sample)"),
|
||||
clEnumValEnd));
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n");
|
||||
|
||||
if (InputFilenames.empty() && WeightedInputFilenames.empty())
|
||||
exitWithError("No input files specified. See " +
|
||||
sys::path::filename(argv[0]) + " -help");
|
||||
|
||||
WeightedFileVector WeightedInputs;
|
||||
for (StringRef Filename : InputFilenames)
|
||||
WeightedInputs.push_back(WeightedFile(Filename, 1));
|
||||
for (StringRef WeightedFilename : WeightedInputFilenames)
|
||||
WeightedInputs.push_back(parseWeightedFile(WeightedFilename));
|
||||
|
||||
if (ProfileKind == instr)
|
||||
mergeInstrProfile(WeightedInputs, OutputFilename, OutputFormat);
|
||||
else
|
||||
mergeSampleProfile(WeightedInputs, OutputFilename, OutputFormat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int showInstrProfile(std::string Filename, bool ShowCounts,
|
||||
bool ShowIndirectCallTargets, bool ShowAllFunctions,
|
||||
std::string ShowFunction, bool TextFormat,
|
||||
raw_fd_ostream &OS) {
|
||||
auto ReaderOrErr = InstrProfReader::create(Filename);
|
||||
if (std::error_code EC = ReaderOrErr.getError())
|
||||
exitWithErrorCode(EC, Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
uint64_t MaxFunctionCount = 0, MaxBlockCount = 0;
|
||||
size_t ShownFunctions = 0, TotalFunctions = 0;
|
||||
for (const auto &Func : *Reader) {
|
||||
bool Show =
|
||||
ShowAllFunctions || (!ShowFunction.empty() &&
|
||||
Func.Name.find(ShowFunction) != Func.Name.npos);
|
||||
|
||||
bool doTextFormatDump = (Show && ShowCounts && TextFormat);
|
||||
|
||||
if (doTextFormatDump) {
|
||||
InstrProfSymtab &Symtab = Reader->getSymtab();
|
||||
InstrProfWriter::writeRecordInText(Func, Symtab, OS);
|
||||
continue;
|
||||
}
|
||||
|
||||
++TotalFunctions;
|
||||
assert(Func.Counts.size() > 0 && "function missing entry counter");
|
||||
if (Func.Counts[0] > MaxFunctionCount)
|
||||
MaxFunctionCount = Func.Counts[0];
|
||||
|
||||
for (size_t I = 1, E = Func.Counts.size(); I < E; ++I) {
|
||||
if (Func.Counts[I] > MaxBlockCount)
|
||||
MaxBlockCount = Func.Counts[I];
|
||||
}
|
||||
|
||||
if (Show) {
|
||||
|
||||
if (!ShownFunctions)
|
||||
OS << "Counters:\n";
|
||||
|
||||
++ShownFunctions;
|
||||
|
||||
OS << " " << Func.Name << ":\n"
|
||||
<< " Hash: " << format("0x%016" PRIx64, Func.Hash) << "\n"
|
||||
<< " Counters: " << Func.Counts.size() << "\n"
|
||||
<< " Function count: " << Func.Counts[0] << "\n";
|
||||
|
||||
if (ShowIndirectCallTargets)
|
||||
OS << " Indirect Call Site Count: "
|
||||
<< Func.getNumValueSites(IPVK_IndirectCallTarget) << "\n";
|
||||
|
||||
if (ShowCounts) {
|
||||
OS << " Block counts: [";
|
||||
for (size_t I = 1, E = Func.Counts.size(); I < E; ++I) {
|
||||
OS << (I == 1 ? "" : ", ") << Func.Counts[I];
|
||||
}
|
||||
OS << "]\n";
|
||||
}
|
||||
|
||||
if (ShowIndirectCallTargets) {
|
||||
InstrProfSymtab &Symtab = Reader->getSymtab();
|
||||
uint32_t NS = Func.getNumValueSites(IPVK_IndirectCallTarget);
|
||||
OS << " Indirect Target Results: \n";
|
||||
for (size_t I = 0; I < NS; ++I) {
|
||||
uint32_t NV = Func.getNumValueDataForSite(IPVK_IndirectCallTarget, I);
|
||||
std::unique_ptr<InstrProfValueData[]> VD =
|
||||
Func.getValueForSite(IPVK_IndirectCallTarget, I);
|
||||
for (uint32_t V = 0; V < NV; V++) {
|
||||
OS << "\t[ " << I << ", ";
|
||||
OS << Symtab.getFuncName(VD[V].Value) << ", " << VD[V].Count
|
||||
<< " ]\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Reader->hasError())
|
||||
exitWithErrorCode(Reader->getError(), Filename);
|
||||
|
||||
if (ShowCounts && TextFormat)
|
||||
return 0;
|
||||
|
||||
if (ShowAllFunctions || !ShowFunction.empty())
|
||||
OS << "Functions shown: " << ShownFunctions << "\n";
|
||||
OS << "Total functions: " << TotalFunctions << "\n";
|
||||
OS << "Maximum function count: " << MaxFunctionCount << "\n";
|
||||
OS << "Maximum internal block count: " << MaxBlockCount << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int showSampleProfile(std::string Filename, bool ShowCounts,
|
||||
bool ShowAllFunctions, std::string ShowFunction,
|
||||
raw_fd_ostream &OS) {
|
||||
using namespace sampleprof;
|
||||
auto ReaderOrErr = SampleProfileReader::create(Filename, getGlobalContext());
|
||||
if (std::error_code EC = ReaderOrErr.getError())
|
||||
exitWithErrorCode(EC, Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
if (std::error_code EC = Reader->read())
|
||||
exitWithErrorCode(EC, Filename);
|
||||
|
||||
if (ShowAllFunctions || ShowFunction.empty())
|
||||
Reader->dump(OS);
|
||||
else
|
||||
Reader->dumpFunctionProfile(ShowFunction, OS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_main(int argc, const char *argv[]) {
|
||||
cl::opt<std::string> Filename(cl::Positional, cl::Required,
|
||||
cl::desc("<profdata-file>"));
|
||||
|
||||
cl::opt<bool> ShowCounts("counts", cl::init(false),
|
||||
cl::desc("Show counter values for shown functions"));
|
||||
cl::opt<bool> TextFormat(
|
||||
"text", cl::init(false),
|
||||
cl::desc("Show instr profile data in text dump format"));
|
||||
cl::opt<bool> ShowIndirectCallTargets(
|
||||
"ic-targets", cl::init(false),
|
||||
cl::desc("Show indirect call site target values for shown functions"));
|
||||
cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
|
||||
cl::desc("Details for every function"));
|
||||
cl::opt<std::string> ShowFunction("function",
|
||||
cl::desc("Details for matching functions"));
|
||||
|
||||
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
|
||||
cl::init("-"), cl::desc("Output file"));
|
||||
cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
|
||||
cl::aliasopt(OutputFilename));
|
||||
cl::opt<ProfileKinds> ProfileKind(
|
||||
cl::desc("Profile kind:"), cl::init(instr),
|
||||
cl::values(clEnumVal(instr, "Instrumentation profile (default)"),
|
||||
clEnumVal(sample, "Sample profile"), clEnumValEnd));
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n");
|
||||
|
||||
if (OutputFilename.empty())
|
||||
OutputFilename = "-";
|
||||
|
||||
std::error_code EC;
|
||||
raw_fd_ostream OS(OutputFilename.data(), EC, sys::fs::F_Text);
|
||||
if (EC)
|
||||
exitWithErrorCode(EC, OutputFilename);
|
||||
|
||||
if (ShowAllFunctions && !ShowFunction.empty())
|
||||
errs() << "warning: -function argument ignored: showing all functions\n";
|
||||
|
||||
if (ProfileKind == instr)
|
||||
return showInstrProfile(Filename, ShowCounts, ShowIndirectCallTargets,
|
||||
ShowAllFunctions, ShowFunction, TextFormat, OS);
|
||||
else
|
||||
return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
|
||||
ShowFunction, OS);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
// Print a stack trace if we signal out.
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
PrettyStackTraceProgram X(argc, argv);
|
||||
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
|
||||
|
||||
StringRef ProgName(sys::path::filename(argv[0]));
|
||||
if (argc > 1) {
|
||||
int (*func)(int, const char *[]) = nullptr;
|
||||
|
||||
if (strcmp(argv[1], "merge") == 0)
|
||||
func = merge_main;
|
||||
else if (strcmp(argv[1], "show") == 0)
|
||||
func = show_main;
|
||||
|
||||
if (func) {
|
||||
std::string Invocation(ProgName.str() + " " + argv[1]);
|
||||
argv[1] = Invocation.c_str();
|
||||
return func(argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-help") == 0 ||
|
||||
strcmp(argv[1], "--help") == 0) {
|
||||
|
||||
errs() << "OVERVIEW: LLVM profile data tools\n\n"
|
||||
<< "USAGE: " << ProgName << " <command> [args...]\n"
|
||||
<< "USAGE: " << ProgName << " <command> -help\n\n"
|
||||
<< "Available commands: merge, show\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
errs() << ProgName << ": No command specified!\n";
|
||||
else
|
||||
errs() << ProgName << ": Unknown command!\n";
|
||||
|
||||
errs() << "USAGE: " << ProgName << " <merge|show> [args...]\n";
|
||||
return 1;
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -107,11 +107,7 @@ void processRecord(raw_ostream& os, Record& rec, string arch)
|
|||
replace(name.begin(), name.end(), '_', '.');
|
||||
name = string("llvm.") + name;
|
||||
|
||||
#if LDC_LLVM_VER >= 309
|
||||
ListInit* propsList = rec.getValueAsListInit("IntrProperties");
|
||||
#else
|
||||
ListInit* propsList = rec.getValueAsListInit("Properties");
|
||||
#endif
|
||||
string prop =
|
||||
propsList->size()
|
||||
? propsList->getElementAsRecord(0)->getName() : "";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue