summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/LTO/LTOCodeGenerator.cpp')
-rw-r--r--contrib/llvm/lib/LTO/LTOCodeGenerator.cpp122
1 files changed, 75 insertions, 47 deletions
diff --git a/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp b/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp
index 1da2d18..6af31e6 100644
--- a/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -19,7 +19,7 @@
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/ParallelCG.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/Config/config.h"
@@ -49,6 +49,7 @@
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
@@ -58,6 +59,7 @@
#include "llvm/Transforms/IPO/Internalize.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <system_error>
using namespace llvm;
@@ -89,6 +91,16 @@ cl::opt<bool> LTOStripInvalidDebugInfo(
cl::init(false),
#endif
cl::Hidden);
+
+cl::opt<std::string>
+ LTORemarksFilename("lto-pass-remarks-output",
+ cl::desc("Output filename for pass remarks"),
+ cl::value_desc("filename"));
+
+cl::opt<bool> LTOPassRemarksWithHotness(
+ "lto-pass-remarks-with-hotness",
+ cl::desc("With PGO, include profile count in optimization remarks"),
+ cl::Hidden);
}
LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
@@ -130,15 +142,18 @@ void LTOCodeGenerator::initializeLTOPasses() {
initializeCFGSimplifyPassPass(R);
}
+void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
+ const std::vector<StringRef> &undefs = Mod->getAsmUndefinedRefs();
+ for (int i = 0, e = undefs.size(); i != e; ++i)
+ AsmUndefinedRefs[undefs[i]] = 1;
+}
+
bool LTOCodeGenerator::addModule(LTOModule *Mod) {
assert(&Mod->getModule().getContext() == &Context &&
"Expected module in same context");
bool ret = TheLinker->linkInModule(Mod->takeModule());
-
- const std::vector<const char *> &undefs = Mod->getAsmUndefinedRefs();
- for (int i = 0, e = undefs.size(); i != e; ++i)
- AsmUndefinedRefs[undefs[i]] = 1;
+ setAsmUndefinedRefs(Mod);
// We've just changed the input, so let's make sure we verify it.
HasVerifiedInput = false;
@@ -154,10 +169,7 @@ void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
MergedModule = Mod->takeModule();
TheLinker = make_unique<Linker>(*MergedModule);
-
- const std::vector<const char*> &Undefs = Mod->getAsmUndefinedRefs();
- for (int I = 0, E = Undefs.size(); I != E; ++I)
- AsmUndefinedRefs[Undefs[I]] = 1;
+ setAsmUndefinedRefs(&*Mod);
// We've just changed the input, so let's make sure we verify it.
HasVerifiedInput = false;
@@ -185,20 +197,21 @@ void LTOCodeGenerator::setOptLevel(unsigned Level) {
switch (OptLevel) {
case 0:
CGOptLevel = CodeGenOpt::None;
- break;
+ return;
case 1:
CGOptLevel = CodeGenOpt::Less;
- break;
+ return;
case 2:
CGOptLevel = CodeGenOpt::Default;
- break;
+ return;
case 3:
CGOptLevel = CodeGenOpt::Aggressive;
- break;
+ return;
}
+ llvm_unreachable("Unknown optimization level!");
}
-bool LTOCodeGenerator::writeMergedModules(const char *Path) {
+bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
if (!determineTarget())
return false;
@@ -239,7 +252,7 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
SmallString<128> Filename;
int FD;
- const char *Extension =
+ StringRef Extension
(FileType == TargetMachine::CGFT_AssemblyFile ? "s" : "o");
std::error_code EC =
@@ -250,11 +263,12 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
}
// generate object file
- tool_output_file objFile(Filename.c_str(), FD);
+ tool_output_file objFile(Filename, FD);
bool genResult = compileOptimized(&objFile.os());
objFile.os().close();
if (objFile.os().has_error()) {
+ emitError((Twine("could not write object file: ") + Filename).str());
objFile.os().clear_error();
sys::fs::remove(Twine(Filename));
return false;
@@ -363,32 +377,19 @@ std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
void LTOCodeGenerator::preserveDiscardableGVs(
Module &TheModule,
llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) {
- SetVector<Constant *> UsedValuesSet;
- if (GlobalVariable *LLVMUsed =
- TheModule.getGlobalVariable("llvm.compiler.used")) {
- ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
- for (auto &V : Inits->operands())
- UsedValuesSet.insert(cast<Constant>(&V));
- LLVMUsed->eraseFromParent();
- }
- llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext());
+ std::vector<GlobalValue *> Used;
auto mayPreserveGlobal = [&](GlobalValue &GV) {
- if (!GV.isDiscardableIfUnused() || GV.isDeclaration())
+ if (!GV.isDiscardableIfUnused() || GV.isDeclaration() ||
+ !mustPreserveGV(GV))
return;
- if (!mustPreserveGV(GV))
- return;
- if (GV.hasAvailableExternallyLinkage()) {
- emitWarning(
+ if (GV.hasAvailableExternallyLinkage())
+ return emitWarning(
(Twine("Linker asked to preserve available_externally global: '") +
GV.getName() + "'").str());
- return;
- }
- if (GV.hasInternalLinkage()) {
- emitWarning((Twine("Linker asked to preserve internal global: '") +
+ if (GV.hasInternalLinkage())
+ return emitWarning((Twine("Linker asked to preserve internal global: '") +
GV.getName() + "'").str());
- return;
- }
- UsedValuesSet.insert(ConstantExpr::getBitCast(&GV, i8PTy));
+ Used.push_back(&GV);
};
for (auto &GV : TheModule)
mayPreserveGlobal(GV);
@@ -397,15 +398,10 @@ void LTOCodeGenerator::preserveDiscardableGVs(
for (auto &GV : TheModule.aliases())
mayPreserveGlobal(GV);
- if (UsedValuesSet.empty())
+ if (Used.empty())
return;
- llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedValuesSet.size());
- auto *LLVMUsed = new llvm::GlobalVariable(
- TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage,
- llvm::ConstantArray::get(ATy, UsedValuesSet.getArrayRef()),
- "llvm.compiler.used");
- LLVMUsed->setSection("llvm.metadata");
+ appendToCompilerUsed(TheModule, Used);
}
void LTOCodeGenerator::applyScopeRestrictions() {
@@ -414,6 +410,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
// Declare a callback for the internalize pass that will ask for every
// candidate GlobalValue if it can be internalized or not.
+ Mangler Mang;
SmallString<64> MangledName;
auto mustPreserveGV = [&](const GlobalValue &GV) -> bool {
// Unnamed globals can't be mangled, but they can't be preserved either.
@@ -425,8 +422,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
// underscore.
MangledName.clear();
MangledName.reserve(GV.getName().size() + 1);
- Mangler::getNameWithPrefix(MangledName, GV.getName(),
- MergedModule->getDataLayout());
+ Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
return MustPreserveSymbols.count(MangledName);
};
@@ -510,6 +506,33 @@ void LTOCodeGenerator::verifyMergedModuleOnce() {
report_fatal_error("Broken module found, compilation aborted!");
}
+bool LTOCodeGenerator::setupOptimizationRemarks() {
+ if (LTORemarksFilename != "") {
+ std::error_code EC;
+ DiagnosticOutputFile = llvm::make_unique<tool_output_file>(
+ LTORemarksFilename, EC, sys::fs::F_None);
+ if (EC) {
+ emitError(EC.message());
+ return false;
+ }
+ Context.setDiagnosticsOutputFile(
+ llvm::make_unique<yaml::Output>(DiagnosticOutputFile->os()));
+ }
+
+ if (LTOPassRemarksWithHotness)
+ Context.setDiagnosticHotnessRequested(true);
+
+ return true;
+}
+
+void LTOCodeGenerator::finishOptimizationRemarks() {
+ if (DiagnosticOutputFile) {
+ DiagnosticOutputFile->keep();
+ // FIXME: LTOCodeGenerator dtor is not invoked on Darwin
+ DiagnosticOutputFile->os().flush();
+ }
+}
+
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
bool DisableGVNLoadPRE,
@@ -517,6 +540,9 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
if (!this->determineTarget())
return false;
+ if (!setupOptimizationRemarks())
+ return false;
+
// We always run the verifier once on the merged module, the `DisableVerify`
// parameter only applies to subsequent verify.
verifyMergedModuleOnce();
@@ -585,12 +611,14 @@ bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) {
if (llvm::AreStatisticsEnabled())
llvm::PrintStatistics();
+ finishOptimizationRemarks();
+
return true;
}
/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
/// LTO problems.
-void LTOCodeGenerator::setCodeGenDebugOptions(const char *Options) {
+void LTOCodeGenerator::setCodeGenDebugOptions(StringRef Options) {
for (std::pair<StringRef, StringRef> o = getToken(Options); !o.first.empty();
o = getToken(o.second))
CodegenOptions.push_back(o.first);
OpenPOWER on IntegriCloud