2016-03-09 02:37:22 +01:00
|
|
|
//===-ThinLTOCodeGenerator.cpp - LLVM Link Time Optimizer -----------------===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-03-09 02:37:22 +01:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the Thin Link Time Optimization library. This library is
|
|
|
|
// intended to be used by linker to optimize code at link time.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-07-14 23:21:16 +02:00
|
|
|
#include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
|
2019-11-15 00:15:48 +01:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
|
2016-03-14 22:18:10 +01:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
2016-03-15 01:04:37 +01:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2020-04-14 02:27:08 +02:00
|
|
|
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
|
[thinlto] Basic thinlto fdo heuristic
Summary:
This patch improves thinlto importer
by importing 3x larger functions that are called from hot block.
I compared performance with the trunk on spec, and there
were about 2% on povray and 3.33% on milc. These results seems
to be consistant and match the results Teresa got with her simple
heuristic. Some benchmarks got slower but I think they are just
noisy (mcf, xalancbmki, omnetpp)- running the benchmarks again with
more iterations to confirm. Geomean of all benchmarks including the noisy ones
were about +0.02%.
I see much better improvement on google branch with Easwaran patch
for pgo callsite inlining (the inliner actually inline those big functions)
Over all I see +0.5% improvement, and I get +8.65% on povray.
So I guess we will see much bigger change when Easwaran patch will land
(it depends on new pass manager), but it is still worth putting this to trunk
before it.
Implementation details changes:
- Removed CallsiteCount.
- ProfileCount got replaced by Hotness
- hot-import-multiplier is set to 3.0 for now,
didn't have time to tune it up, but I see that we get most of the interesting
functions with 3, so there is no much performance difference with higher, and
binary size doesn't grow as much as with 10.0.
Reviewers: eraman, mehdi_amini, tejohnson
Subscribers: mehdi_amini, llvm-commits
Differential Revision: https://reviews.llvm.org/D24638
llvm-svn: 282437
2016-09-26 22:37:32 +02:00
|
|
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
|
|
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
2016-11-11 06:34:58 +01:00
|
|
|
#include "llvm/Bitcode/BitcodeReader.h"
|
|
|
|
#include "llvm/Bitcode/BitcodeWriter.h"
|
2016-03-14 22:18:10 +01:00
|
|
|
#include "llvm/Bitcode/BitcodeWriterPass.h"
|
2018-04-30 16:59:11 +02:00
|
|
|
#include "llvm/Config/llvm-config.h"
|
2017-05-20 02:00:08 +02:00
|
|
|
#include "llvm/IR/DebugInfo.h"
|
2017-06-06 13:49:48 +02:00
|
|
|
#include "llvm/IR/DiagnosticPrinter.h"
|
2016-03-15 01:04:37 +01:00
|
|
|
#include "llvm/IR/LLVMContext.h"
|
2019-10-28 22:53:31 +01:00
|
|
|
#include "llvm/IR/LLVMRemarkStreamer.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/IR/LegacyPassManager.h"
|
|
|
|
#include "llvm/IR/Mangler.h"
|
2018-09-26 15:01:43 +02:00
|
|
|
#include "llvm/IR/PassTimingInfo.h"
|
2017-05-20 02:00:08 +02:00
|
|
|
#include "llvm/IR/Verifier.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/IRReader/IRReader.h"
|
2016-05-24 00:54:06 +02:00
|
|
|
#include "llvm/LTO/LTO.h"
|
2018-12-13 20:54:27 +01:00
|
|
|
#include "llvm/LTO/SummaryBasedOptimizations.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/MC/SubtargetFeature.h"
|
2016-04-24 05:18:01 +02:00
|
|
|
#include "llvm/Object/IRObjectFile.h"
|
2016-04-21 07:54:23 +02:00
|
|
|
#include "llvm/Support/CachePruning.h"
|
|
|
|
#include "llvm/Support/Debug.h"
|
2016-11-19 19:20:05 +01:00
|
|
|
#include "llvm/Support/Error.h"
|
2019-09-13 22:08:27 +02:00
|
|
|
#include "llvm/Support/FileUtilities.h"
|
2016-04-21 07:54:23 +02:00
|
|
|
#include "llvm/Support/Path.h"
|
|
|
|
#include "llvm/Support/SHA1.h"
|
2018-04-16 05:44:03 +02:00
|
|
|
#include "llvm/Support/SmallVectorMemoryBuffer.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/Support/TargetRegistry.h"
|
|
|
|
#include "llvm/Support/ThreadPool.h"
|
2016-10-19 19:35:01 +02:00
|
|
|
#include "llvm/Support/Threading.h"
|
2016-11-19 19:20:05 +01:00
|
|
|
#include "llvm/Support/ToolOutputFile.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
#include "llvm/Transforms/IPO.h"
|
|
|
|
#include "llvm/Transforms/IPO/FunctionImport.h"
|
2016-04-24 05:18:01 +02:00
|
|
|
#include "llvm/Transforms/IPO/Internalize.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
2019-10-18 12:54:14 +02:00
|
|
|
#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
|
2016-03-09 02:37:22 +01:00
|
|
|
#include "llvm/Transforms/ObjCARC.h"
|
|
|
|
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
|
|
|
|
|
2016-05-16 21:33:07 +02:00
|
|
|
#include <numeric>
|
|
|
|
|
2018-07-04 16:17:10 +02:00
|
|
|
#if !defined(_MSC_VER) && !defined(__MINGW32__)
|
|
|
|
#include <unistd.h>
|
|
|
|
#else
|
|
|
|
#include <io.h>
|
|
|
|
#endif
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
using namespace llvm;
|
|
|
|
|
2016-04-16 09:02:16 +02:00
|
|
|
#define DEBUG_TYPE "thinlto"
|
|
|
|
|
Add a flag to the LLVMContext to disable name for Value other than GlobalValue
Summary:
This is intended to be a performance flag, on the same level as clang
cc1 option "--disable-free". LLVM will never initialize it by default,
it will be up to the client creating the LLVMContext to request this
behavior. Clang will do it by default in Release build (just like
--disable-free).
"opt" and "llc" can opt-in using -disable-named-value command line
option.
When performing LTO on llvm-tblgen, the initial merging of IR peaks
at 92MB without this patch, and 86MB after this patch,setNameImpl()
drops from 6.5MB to 0.5MB.
The total link time goes from ~29.5s to ~27.8s.
Compared to a compile-time flag (like the IRBuilder one), it performs
very close. I profiled on SROA and obtain these results:
420ms with IRBuilder that preserve name
372ms with IRBuilder that strip name
375ms with IRBuilder that preserve name, and a runtime flag to strip
Reviewers: chandlerc, dexonsmith, bogner
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17946
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 263086
2016-03-10 02:28:54 +01:00
|
|
|
namespace llvm {
|
|
|
|
// Flags -discard-value-names, defined in LTOCodeGenerator.cpp
|
|
|
|
extern cl::opt<bool> LTODiscardValueNames;
|
2019-06-14 18:20:51 +02:00
|
|
|
extern cl::opt<std::string> RemarksFilename;
|
|
|
|
extern cl::opt<std::string> RemarksPasses;
|
|
|
|
extern cl::opt<bool> RemarksWithHotness;
|
2019-06-17 18:06:00 +02:00
|
|
|
extern cl::opt<std::string> RemarksFormat;
|
Add a flag to the LLVMContext to disable name for Value other than GlobalValue
Summary:
This is intended to be a performance flag, on the same level as clang
cc1 option "--disable-free". LLVM will never initialize it by default,
it will be up to the client creating the LLVMContext to request this
behavior. Clang will do it by default in Release build (just like
--disable-free).
"opt" and "llc" can opt-in using -disable-named-value command line
option.
When performing LTO on llvm-tblgen, the initial merging of IR peaks
at 92MB without this patch, and 86MB after this patch,setNameImpl()
drops from 6.5MB to 0.5MB.
The total link time goes from ~29.5s to ~27.8s.
Compared to a compile-time flag (like the IRBuilder one), it performs
very close. I profiled on SROA and obtain these results:
420ms with IRBuilder that preserve name
372ms with IRBuilder that strip name
375ms with IRBuilder that preserve name, and a runtime flag to strip
Reviewers: chandlerc, dexonsmith, bogner
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17946
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 263086
2016-03-10 02:28:54 +01:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
namespace {
|
|
|
|
|
2020-02-18 20:25:08 +01:00
|
|
|
// Default to using all available threads in the system, but using only one
|
|
|
|
// thred per core, as indicated by the usage of
|
|
|
|
// heavyweight_hardware_concurrency() below.
|
[Support] On Windows, ensure hardware_concurrency() extends to all CPU sockets and all NUMA groups
The goal of this patch is to maximize CPU utilization on multi-socket or high core count systems, so that parallel computations such as LLD/ThinLTO can use all hardware threads in the system. Before this patch, on Windows, a maximum of 64 hardware threads could be used at most, in some cases dispatched only on one CPU socket.
== Background ==
Windows doesn't have a flat cpu_set_t like Linux. Instead, it projects hardware CPUs (or NUMA nodes) to applications through a concept of "processor groups". A "processor" is the smallest unit of execution on a CPU, that is, an hyper-thread if SMT is active; a core otherwise. There's a limit of 32-bit processors on older 32-bit versions of Windows, which later was raised to 64-processors with 64-bit versions of Windows. This limit comes from the affinity mask, which historically is represented by the sizeof(void*). Consequently, the concept of "processor groups" was introduced for dealing with systems with more than 64 hyper-threads.
By default, the Windows OS assigns only one "processor group" to each starting application, in a round-robin manner. If the application wants to use more processors, it needs to programmatically enable it, by assigning threads to other "processor groups". This also means that affinity cannot cross "processor group" boundaries; one can only specify a "preferred" group on start-up, but the application is free to allocate more groups if it wants to.
This creates a peculiar situation, where newer CPUs like the AMD EPYC 7702P (64-cores, 128-hyperthreads) are projected by the OS as two (2) "processor groups". This means that by default, an application can only use half of the cores. This situation could only get worse in the years to come, as dies with more cores will appear on the market.
== The problem ==
The heavyweight_hardware_concurrency() API was introduced so that only *one hardware thread per core* was used. Once that API returns, that original intention is lost, only the number of threads is retained. Consider a situation, on Windows, where the system has 2 CPU sockets, 18 cores each, each core having 2 hyper-threads, for a total of 72 hyper-threads. Both heavyweight_hardware_concurrency() and hardware_concurrency() currently return 36, because on Windows they are simply wrappers over std::thread::hardware_concurrency() -- which can only return processors from the current "processor group".
== The changes in this patch ==
To solve this situation, we capture (and retain) the initial intention until the point of usage, through a new ThreadPoolStrategy class. The number of threads to use is deferred as late as possible, until the moment where the std::threads are created (ThreadPool in the case of ThinLTO).
When using hardware_concurrency(), setting ThreadCount to 0 now means to use all the possible hardware CPU (SMT) threads. Providing a ThreadCount above to the maximum number of threads will have no effect, the maximum will be used instead.
The heavyweight_hardware_concurrency() is similar to hardware_concurrency(), except that only one thread per hardware *core* will be used.
When LLVM_ENABLE_THREADS is OFF, the threading APIs will always return 1, to ensure any caller loops will be exercised at least once.
Differential Revision: https://reviews.llvm.org/D71775
2020-02-14 04:49:57 +01:00
|
|
|
static cl::opt<int> ThreadCount("threads", cl::init(0));
|
2016-03-09 02:37:22 +01:00
|
|
|
|
|
|
|
// Simple helper to save temporary files for debug.
|
|
|
|
static void saveTempBitcode(const Module &TheModule, StringRef TempDir,
|
|
|
|
unsigned count, StringRef Suffix) {
|
|
|
|
if (TempDir.empty())
|
|
|
|
return;
|
|
|
|
// User asked to save temps, let dump the bitcode file after import.
|
2017-12-28 17:58:54 +01:00
|
|
|
std::string SaveTempPath = (TempDir + llvm::Twine(count) + Suffix).str();
|
2016-03-09 02:37:22 +01:00
|
|
|
std::error_code EC;
|
2019-08-05 07:43:48 +02:00
|
|
|
raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
|
2016-03-09 02:37:22 +01:00
|
|
|
if (EC)
|
|
|
|
report_fatal_error(Twine("Failed to open ") + SaveTempPath +
|
|
|
|
" to save optimized bitcode\n");
|
2018-02-14 20:11:32 +01:00
|
|
|
WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
2016-05-24 19:24:25 +02:00
|
|
|
static const GlobalValueSummary *
|
|
|
|
getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
|
|
|
|
// If there is any strong definition anywhere, get it.
|
|
|
|
auto StrongDefForLinker = llvm::find_if(
|
|
|
|
GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
|
|
|
|
auto Linkage = Summary->linkage();
|
|
|
|
return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
|
|
|
|
!GlobalValue::isWeakForLinker(Linkage);
|
|
|
|
});
|
|
|
|
if (StrongDefForLinker != GVSummaryList.end())
|
|
|
|
return StrongDefForLinker->get();
|
2016-04-01 23:53:50 +02:00
|
|
|
// Get the first *linker visible* definition for this global in the summary
|
|
|
|
// list.
|
|
|
|
auto FirstDefForLinker = llvm::find_if(
|
2016-04-24 16:57:11 +02:00
|
|
|
GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
|
|
|
|
auto Linkage = Summary->linkage();
|
2016-04-01 23:53:50 +02:00
|
|
|
return !GlobalValue::isAvailableExternallyLinkage(Linkage);
|
|
|
|
});
|
2016-05-24 19:24:25 +02:00
|
|
|
// Extern templates can be emitted as available_externally.
|
|
|
|
if (FirstDefForLinker == GVSummaryList.end())
|
|
|
|
return nullptr;
|
|
|
|
return FirstDefForLinker->get();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Populate map of GUID to the prevailing copy for any multiply defined
|
|
|
|
// symbols. Currently assume first copy is prevailing, or any strong
|
|
|
|
// definition. Can be refined with Linker information in the future.
|
|
|
|
static void computePrevailingCopies(
|
|
|
|
const ModuleSummaryIndex &Index,
|
|
|
|
DenseMap<GlobalValue::GUID, const GlobalValueSummary *> &PrevailingCopy) {
|
2016-04-24 16:57:11 +02:00
|
|
|
auto HasMultipleCopies = [&](const GlobalValueSummaryList &GVSummaryList) {
|
|
|
|
return GVSummaryList.size() > 1;
|
|
|
|
};
|
2016-04-01 23:53:50 +02:00
|
|
|
|
2016-05-24 19:24:25 +02:00
|
|
|
for (auto &I : Index) {
|
2017-05-04 20:03:25 +02:00
|
|
|
if (HasMultipleCopies(I.second.SummaryList))
|
|
|
|
PrevailingCopy[I.first] =
|
|
|
|
getFirstDefinitionForLinker(I.second.SummaryList);
|
2016-04-01 23:53:50 +02:00
|
|
|
}
|
2016-05-24 19:24:25 +02:00
|
|
|
}
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
static StringMap<lto::InputFile *>
|
|
|
|
generateModuleMap(std::vector<std::unique_ptr<lto::InputFile>> &Modules) {
|
|
|
|
StringMap<lto::InputFile *> ModuleMap;
|
|
|
|
for (auto &M : Modules) {
|
|
|
|
assert(ModuleMap.find(M->getName()) == ModuleMap.end() &&
|
2016-03-09 02:37:22 +01:00
|
|
|
"Expect unique Buffer Identifier");
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
ModuleMap[M->getName()] = M.get();
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
return ModuleMap;
|
|
|
|
}
|
|
|
|
|
2020-02-16 02:23:18 +01:00
|
|
|
static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index,
|
|
|
|
bool ClearDSOLocalOnDeclarations) {
|
|
|
|
if (renameModuleForThinLTO(TheModule, Index, ClearDSOLocalOnDeclarations))
|
2016-03-09 02:37:22 +01:00
|
|
|
report_fatal_error("renameModuleForThinLTO failed");
|
|
|
|
}
|
|
|
|
|
2017-05-20 02:00:08 +02:00
|
|
|
namespace {
|
|
|
|
class ThinLTODiagnosticInfo : public DiagnosticInfo {
|
|
|
|
const Twine &Msg;
|
|
|
|
public:
|
|
|
|
ThinLTODiagnosticInfo(const Twine &DiagMsg,
|
|
|
|
DiagnosticSeverity Severity = DS_Error)
|
|
|
|
: DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
|
|
|
|
void print(DiagnosticPrinter &DP) const override { DP << Msg; }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Verify the module and strip broken debug info.
|
|
|
|
static void verifyLoadedModule(Module &TheModule) {
|
|
|
|
bool BrokenDebugInfo = false;
|
2017-10-02 20:31:29 +02:00
|
|
|
if (verifyModule(TheModule, &dbgs(), &BrokenDebugInfo))
|
2017-05-20 02:00:08 +02:00
|
|
|
report_fatal_error("Broken module found, compilation aborted!");
|
|
|
|
if (BrokenDebugInfo) {
|
|
|
|
TheModule.getContext().diagnose(ThinLTODiagnosticInfo(
|
|
|
|
"Invalid debug info found, debug info will be stripped", DS_Warning));
|
|
|
|
StripDebugInfo(TheModule);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile *Input,
|
|
|
|
LLVMContext &Context,
|
|
|
|
bool Lazy,
|
|
|
|
bool IsImporting) {
|
|
|
|
auto &Mod = Input->getSingleBitcodeModule();
|
2016-12-01 06:52:32 +01:00
|
|
|
SMDiagnostic Err;
|
|
|
|
Expected<std::unique_ptr<Module>> ModuleOrErr =
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
Lazy ? Mod.getLazyModule(Context,
|
|
|
|
/* ShouldLazyLoadMetadata */ true, IsImporting)
|
|
|
|
: Mod.parseModule(Context);
|
2016-12-01 06:52:32 +01:00
|
|
|
if (!ModuleOrErr) {
|
|
|
|
handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
|
2016-12-01 06:52:32 +01:00
|
|
|
SourceMgr::DK_Error, EIB.message());
|
|
|
|
Err.print("ThinLTO", errs());
|
|
|
|
});
|
|
|
|
report_fatal_error("Can't load module, abort.");
|
|
|
|
}
|
2017-05-20 02:00:08 +02:00
|
|
|
if (!Lazy)
|
|
|
|
verifyLoadedModule(*ModuleOrErr.get());
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
return std::move(*ModuleOrErr);
|
2016-12-01 06:52:32 +01:00
|
|
|
}
|
|
|
|
|
2016-03-26 06:40:34 +01:00
|
|
|
static void
|
|
|
|
crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
|
2020-02-16 02:23:18 +01:00
|
|
|
StringMap<lto::InputFile *> &ModuleMap,
|
|
|
|
const FunctionImporter::ImportMapTy &ImportList,
|
|
|
|
bool ClearDSOLocalOnDeclarations) {
|
2016-12-01 06:52:32 +01:00
|
|
|
auto Loader = [&](StringRef Identifier) {
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto &Input = ModuleMap[Identifier];
|
|
|
|
return loadModuleFromInput(Input, TheModule.getContext(),
|
|
|
|
/*Lazy=*/true, /*IsImporting*/ true);
|
2016-12-01 06:52:32 +01:00
|
|
|
};
|
|
|
|
|
2020-02-16 02:23:18 +01:00
|
|
|
FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);
|
2017-05-20 01:32:21 +02:00
|
|
|
Expected<bool> Result = Importer.importFunctions(TheModule, ImportList);
|
2017-01-08 01:30:27 +01:00
|
|
|
if (!Result) {
|
|
|
|
handleAllErrors(Result.takeError(), [&](ErrorInfoBase &EIB) {
|
|
|
|
SMDiagnostic Err = SMDiagnostic(TheModule.getModuleIdentifier(),
|
|
|
|
SourceMgr::DK_Error, EIB.message());
|
|
|
|
Err.print("ThinLTO", errs());
|
|
|
|
});
|
2016-11-09 18:49:19 +01:00
|
|
|
report_fatal_error("importFunctions failed");
|
2017-01-08 01:30:27 +01:00
|
|
|
}
|
2017-05-20 02:00:08 +02:00
|
|
|
// Verify again after cross-importing.
|
|
|
|
verifyLoadedModule(TheModule);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
2016-12-28 20:37:16 +01:00
|
|
|
static void optimizeModule(Module &TheModule, TargetMachine &TM,
|
2019-10-18 12:54:14 +02:00
|
|
|
unsigned OptLevel, bool Freestanding,
|
|
|
|
ModuleSummaryIndex *Index) {
|
2016-03-09 02:37:22 +01:00
|
|
|
// Populate the PassManager
|
|
|
|
PassManagerBuilder PMB;
|
|
|
|
PMB.LibraryInfo = new TargetLibraryInfoImpl(TM.getTargetTriple());
|
2017-03-28 20:55:44 +02:00
|
|
|
if (Freestanding)
|
|
|
|
PMB.LibraryInfo->disableAllFunctions();
|
2016-03-09 02:37:22 +01:00
|
|
|
PMB.Inliner = createFunctionInliningPass();
|
|
|
|
// FIXME: should get it from the bitcode?
|
2016-12-28 20:37:16 +01:00
|
|
|
PMB.OptLevel = OptLevel;
|
2016-03-09 02:37:22 +01:00
|
|
|
PMB.LoopVectorize = true;
|
|
|
|
PMB.SLPVectorize = true;
|
2017-05-20 02:00:08 +02:00
|
|
|
// Already did this in verifyLoadedModule().
|
|
|
|
PMB.VerifyInput = false;
|
2016-03-09 02:37:22 +01:00
|
|
|
PMB.VerifyOutput = false;
|
2019-10-18 12:54:14 +02:00
|
|
|
PMB.ImportSummary = Index;
|
2016-03-09 02:37:22 +01:00
|
|
|
|
|
|
|
legacy::PassManager PM;
|
|
|
|
|
|
|
|
// Add the TTI (required to inform the vectorizer about register size for
|
|
|
|
// instance)
|
|
|
|
PM.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
|
|
|
|
|
|
|
|
// Add optimizations
|
|
|
|
PMB.populateThinLTOPassManager(PM);
|
|
|
|
|
|
|
|
PM.run(TheModule);
|
|
|
|
}
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
static void
|
|
|
|
addUsedSymbolToPreservedGUID(const lto::InputFile &File,
|
|
|
|
DenseSet<GlobalValue::GUID> &PreservedGUID) {
|
|
|
|
for (const auto &Sym : File.symbols()) {
|
|
|
|
if (Sym.isUsed())
|
|
|
|
PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-24 05:18:01 +02:00
|
|
|
// Convert the PreservedSymbols map from "Name" based to "GUID" based.
|
|
|
|
static DenseSet<GlobalValue::GUID>
|
2017-02-03 08:41:43 +01:00
|
|
|
computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols,
|
|
|
|
const Triple &TheTriple) {
|
|
|
|
DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
|
|
|
|
for (auto &Entry : PreservedSymbols) {
|
2016-04-24 05:18:01 +02:00
|
|
|
StringRef Name = Entry.first();
|
|
|
|
if (TheTriple.isOSBinFormatMachO() && Name.size() > 0 && Name[0] == '_')
|
|
|
|
Name = Name.drop_front();
|
2017-02-03 08:41:43 +01:00
|
|
|
GUIDPreservedSymbols.insert(GlobalValue::getGUID(Name));
|
2016-04-24 05:18:01 +02:00
|
|
|
}
|
2017-02-03 08:41:43 +01:00
|
|
|
return GUIDPreservedSymbols;
|
2016-04-24 05:18:01 +02:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
|
|
|
|
TargetMachine &TM) {
|
|
|
|
SmallVector<char, 128> OutputBuffer;
|
|
|
|
|
|
|
|
// CodeGen
|
|
|
|
{
|
|
|
|
raw_svector_ostream OS(OutputBuffer);
|
|
|
|
legacy::PassManager PM;
|
2016-04-01 10:22:59 +02:00
|
|
|
|
|
|
|
// If the bitcode files contain ARC code and were compiled with optimization,
|
|
|
|
// the ObjCARCContractPass must be run, so do it unconditionally here.
|
|
|
|
PM.add(createObjCARCContractPass());
|
|
|
|
|
|
|
|
// Setup the codegen now.
|
2019-11-14 00:17:46 +01:00
|
|
|
if (TM.addPassesToEmitFile(PM, OS, nullptr, CGFT_ObjectFile,
|
2016-03-09 02:37:22 +01:00
|
|
|
/* DisableVerify */ true))
|
|
|
|
report_fatal_error("Failed to setup codegen");
|
|
|
|
|
|
|
|
// Run codegen now. resulting binary is in OutputBuffer.
|
|
|
|
PM.run(TheModule);
|
|
|
|
}
|
2019-08-15 17:54:37 +02:00
|
|
|
return std::make_unique<SmallVectorMemoryBuffer>(std::move(OutputBuffer));
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
2016-04-21 07:54:23 +02:00
|
|
|
/// Manage caching for a single Module.
|
|
|
|
class ModuleCacheEntry {
|
|
|
|
SmallString<128> EntryPath;
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Create a cache entry. This compute a unique hash for the Module considering
|
|
|
|
// the current list of export/import, and offer an interface to query to
|
|
|
|
// access the content in the cache.
|
|
|
|
ModuleCacheEntry(
|
|
|
|
StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
|
|
|
|
const FunctionImporter::ImportMapTy &ImportList,
|
|
|
|
const FunctionImporter::ExportSetTy &ExportList,
|
|
|
|
const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
|
[ThinLTO] Consolidate cache key computation between new/old LTO APIs
Summary:
The old legacy LTO API had a separate cache key computation, which was
a subset of the cache key computation in the new LTO API (from what I
can tell this is largely just because certain features such as CFI,
dsoLocal, etc are only utilized via the new LTO API). However, having
separate computations is unnecessary (much of the code is duplicated),
and can lead to bugs when adding new optimizations if both cache
computation algorithms aren't updated properly - it's much easier to
maintain if we have a single facility.
This patch refactors the old LTO API code to use the cache key
computation from the new LTO API. To do this, we set up an lto::Config
object and fill in the fields that the old LTO was hashing (the others
will just use the defaults).
There are two notable changes:
- I added a Freestanding flag to the LTO Config. Currently this is only
used by the legacy LTO API. In the patch that added it (D30791) I had
asked about adding it to the new LTO API, but it looks like that was not
addressed. This should probably be discussed as a follow up to this
change, as it is orthogonal.
- The legacy LTO API had some code that was hashing the GUID of all
preserved symbols defined in the module. I looked back at the history of
this (which was added with the original hashing in the legacy LTO API in
D18494), and there is a comment in the review thread that it was added
in preparation for future internalization. We now do the internalization
of course, and that is handled in the new LTO API cache key computation
by hashing the recorded linkage type of all defined globals. Therefore I
didn't try to move over and keep the preserved symbols handling.
Reviewers: steven_wu, pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D54635
llvm-svn: 347592
2018-11-26 21:40:37 +01:00
|
|
|
const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
|
2017-03-28 20:55:44 +02:00
|
|
|
bool Freestanding, const TargetMachineBuilder &TMBuilder) {
|
2016-04-21 07:54:23 +02:00
|
|
|
if (CachePath.empty())
|
|
|
|
return;
|
|
|
|
|
2016-10-08 06:44:18 +02:00
|
|
|
if (!Index.modulePaths().count(ModuleID))
|
|
|
|
// The module does not have an entry, it can't have a hash at all
|
|
|
|
return;
|
|
|
|
|
[ThinLTO] Consolidate cache key computation between new/old LTO APIs
Summary:
The old legacy LTO API had a separate cache key computation, which was
a subset of the cache key computation in the new LTO API (from what I
can tell this is largely just because certain features such as CFI,
dsoLocal, etc are only utilized via the new LTO API). However, having
separate computations is unnecessary (much of the code is duplicated),
and can lead to bugs when adding new optimizations if both cache
computation algorithms aren't updated properly - it's much easier to
maintain if we have a single facility.
This patch refactors the old LTO API code to use the cache key
computation from the new LTO API. To do this, we set up an lto::Config
object and fill in the fields that the old LTO was hashing (the others
will just use the defaults).
There are two notable changes:
- I added a Freestanding flag to the LTO Config. Currently this is only
used by the legacy LTO API. In the patch that added it (D30791) I had
asked about adding it to the new LTO API, but it looks like that was not
addressed. This should probably be discussed as a follow up to this
change, as it is orthogonal.
- The legacy LTO API had some code that was hashing the GUID of all
preserved symbols defined in the module. I looked back at the history of
this (which was added with the original hashing in the legacy LTO API in
D18494), and there is a comment in the review thread that it was added
in preparation for future internalization. We now do the internalization
of course, and that is handled in the new LTO API cache key computation
by hashing the recorded linkage type of all defined globals. Therefore I
didn't try to move over and keep the preserved symbols handling.
Reviewers: steven_wu, pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D54635
llvm-svn: 347592
2018-11-26 21:40:37 +01:00
|
|
|
if (all_of(Index.getModuleHash(ModuleID),
|
|
|
|
[](uint32_t V) { return V == 0; }))
|
2016-10-08 06:44:23 +02:00
|
|
|
// No hash entry, no caching!
|
|
|
|
return;
|
|
|
|
|
[ThinLTO] Consolidate cache key computation between new/old LTO APIs
Summary:
The old legacy LTO API had a separate cache key computation, which was
a subset of the cache key computation in the new LTO API (from what I
can tell this is largely just because certain features such as CFI,
dsoLocal, etc are only utilized via the new LTO API). However, having
separate computations is unnecessary (much of the code is duplicated),
and can lead to bugs when adding new optimizations if both cache
computation algorithms aren't updated properly - it's much easier to
maintain if we have a single facility.
This patch refactors the old LTO API code to use the cache key
computation from the new LTO API. To do this, we set up an lto::Config
object and fill in the fields that the old LTO was hashing (the others
will just use the defaults).
There are two notable changes:
- I added a Freestanding flag to the LTO Config. Currently this is only
used by the legacy LTO API. In the patch that added it (D30791) I had
asked about adding it to the new LTO API, but it looks like that was not
addressed. This should probably be discussed as a follow up to this
change, as it is orthogonal.
- The legacy LTO API had some code that was hashing the GUID of all
preserved symbols defined in the module. I looked back at the history of
this (which was added with the original hashing in the legacy LTO API in
D18494), and there is a comment in the review thread that it was added
in preparation for future internalization. We now do the internalization
of course, and that is handled in the new LTO API cache key computation
by hashing the recorded linkage type of all defined globals. Therefore I
didn't try to move over and keep the preserved symbols handling.
Reviewers: steven_wu, pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D54635
llvm-svn: 347592
2018-11-26 21:40:37 +01:00
|
|
|
llvm::lto::Config Conf;
|
|
|
|
Conf.OptLevel = OptLevel;
|
|
|
|
Conf.Options = TMBuilder.Options;
|
|
|
|
Conf.CPU = TMBuilder.MCpu;
|
|
|
|
Conf.MAttrs.push_back(TMBuilder.MAttr);
|
|
|
|
Conf.RelocModel = TMBuilder.RelocModel;
|
|
|
|
Conf.CGOptLevel = TMBuilder.CGOptLevel;
|
|
|
|
Conf.Freestanding = Freestanding;
|
|
|
|
SmallString<40> Key;
|
|
|
|
computeLTOCacheKey(Key, Conf, Index, ModuleID, ImportList, ExportList,
|
|
|
|
ResolvedODR, DefinedGVSummaries);
|
2018-11-16 08:08:00 +01:00
|
|
|
|
2017-03-20 17:41:57 +01:00
|
|
|
// This choice of file name allows the cache to be pruned (see pruneCache()
|
|
|
|
// in include/llvm/Support/CachePruning.h).
|
[ThinLTO] Consolidate cache key computation between new/old LTO APIs
Summary:
The old legacy LTO API had a separate cache key computation, which was
a subset of the cache key computation in the new LTO API (from what I
can tell this is largely just because certain features such as CFI,
dsoLocal, etc are only utilized via the new LTO API). However, having
separate computations is unnecessary (much of the code is duplicated),
and can lead to bugs when adding new optimizations if both cache
computation algorithms aren't updated properly - it's much easier to
maintain if we have a single facility.
This patch refactors the old LTO API code to use the cache key
computation from the new LTO API. To do this, we set up an lto::Config
object and fill in the fields that the old LTO was hashing (the others
will just use the defaults).
There are two notable changes:
- I added a Freestanding flag to the LTO Config. Currently this is only
used by the legacy LTO API. In the patch that added it (D30791) I had
asked about adding it to the new LTO API, but it looks like that was not
addressed. This should probably be discussed as a follow up to this
change, as it is orthogonal.
- The legacy LTO API had some code that was hashing the GUID of all
preserved symbols defined in the module. I looked back at the history of
this (which was added with the original hashing in the legacy LTO API in
D18494), and there is a comment in the review thread that it was added
in preparation for future internalization. We now do the internalization
of course, and that is handled in the new LTO API cache key computation
by hashing the recorded linkage type of all defined globals. Therefore I
didn't try to move over and keep the preserved symbols handling.
Reviewers: steven_wu, pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D54635
llvm-svn: 347592
2018-11-26 21:40:37 +01:00
|
|
|
sys::path::append(EntryPath, CachePath, "llvmcache-" + Key);
|
2016-04-21 07:54:23 +02:00
|
|
|
}
|
|
|
|
|
2016-04-24 05:18:01 +02:00
|
|
|
// Access the path to this entry in the cache.
|
|
|
|
StringRef getEntryPath() { return EntryPath; }
|
|
|
|
|
2016-04-21 07:54:23 +02:00
|
|
|
// Try loading the buffer for this cache entry.
|
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer() {
|
|
|
|
if (EntryPath.empty())
|
|
|
|
return std::error_code();
|
2018-07-04 16:17:10 +02:00
|
|
|
SmallString<64> ResultPath;
|
2019-07-11 22:29:32 +02:00
|
|
|
Expected<sys::fs::file_t> FDOrErr = sys::fs::openNativeFileForRead(
|
|
|
|
Twine(EntryPath), sys::fs::OF_UpdateAtime, &ResultPath);
|
|
|
|
if (!FDOrErr)
|
|
|
|
return errorToErrorCode(FDOrErr.takeError());
|
[Support] Move llvm::MemoryBuffer to sys::fs::file_t
Summary:
On Windows, Posix integer file descriptors are a compatibility layer
over native file handles provided by the C runtime. There is a hard
limit on the maximum number of file descriptors that a process can open,
and the limit is 8192. LLD typically doesn't run into this limit because
it opens input files, maps them into memory, and then immediately closes
the file descriptor. This prevents it from running out of FDs.
For various reasons, I'd like to open handles to every input file and
keep them open during linking. That requires migrating MemoryBuffer over
to taking open native file handles instead of integer FDs.
Reviewers: aganea, Bigcheese
Reviewed By: aganea
Subscribers: smeenai, silvas, mehdi_amini, hiraditya, steven_wu, dexonsmith, dang, llvm-commits, zturner
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D63453
llvm-svn: 365588
2019-07-10 02:34:13 +02:00
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getOpenFile(
|
2019-07-11 22:29:32 +02:00
|
|
|
*FDOrErr, EntryPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
|
|
|
|
sys::fs::closeFile(*FDOrErr);
|
2018-07-04 16:17:10 +02:00
|
|
|
return MBOrErr;
|
2016-04-21 07:54:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Cache the Produced object file
|
2016-12-14 05:56:42 +01:00
|
|
|
void write(const MemoryBuffer &OutputBuffer) {
|
2016-04-21 07:54:23 +02:00
|
|
|
if (EntryPath.empty())
|
2016-12-14 05:56:42 +01:00
|
|
|
return;
|
2016-04-21 07:54:23 +02:00
|
|
|
|
|
|
|
// Write to a temporary to avoid race condition
|
|
|
|
SmallString<128> TempFilename;
|
2018-03-30 23:35:42 +02:00
|
|
|
SmallString<128> CachePath(EntryPath);
|
|
|
|
llvm::sys::path::remove_filename(CachePath);
|
|
|
|
sys::path::append(TempFilename, CachePath, "Thin-%%%%%%.tmp.o");
|
2019-09-13 22:08:27 +02:00
|
|
|
|
|
|
|
if (auto Err = handleErrors(
|
|
|
|
llvm::writeFileAtomically(TempFilename, EntryPath,
|
|
|
|
OutputBuffer.getBuffer()),
|
|
|
|
[](const llvm::AtomicFileWriteError &E) {
|
|
|
|
std::string ErrorMsgBuffer;
|
|
|
|
llvm::raw_string_ostream S(ErrorMsgBuffer);
|
|
|
|
E.log(S);
|
|
|
|
|
|
|
|
if (E.Error ==
|
|
|
|
llvm::atomic_write_error::failed_to_create_uniq_file) {
|
|
|
|
errs() << "Error: " << ErrorMsgBuffer << "\n";
|
|
|
|
report_fatal_error("ThinLTO: Can't get a temporary file");
|
|
|
|
}
|
|
|
|
})) {
|
|
|
|
// FIXME
|
|
|
|
consumeError(std::move(Err));
|
2016-04-21 07:54:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-05-24 19:24:25 +02:00
|
|
|
static std::unique_ptr<MemoryBuffer>
|
|
|
|
ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index,
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
StringMap<lto::InputFile *> &ModuleMap, TargetMachine &TM,
|
2016-05-24 19:24:25 +02:00
|
|
|
const FunctionImporter::ImportMapTy &ImportList,
|
|
|
|
const FunctionImporter::ExportSetTy &ExportList,
|
|
|
|
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
|
|
|
|
const GVSummaryMapTy &DefinedGlobals,
|
2016-06-08 21:09:22 +02:00
|
|
|
const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
|
2016-05-24 19:24:25 +02:00
|
|
|
bool DisableCodeGen, StringRef SaveTempsDir,
|
2017-03-28 20:55:44 +02:00
|
|
|
bool Freestanding, unsigned OptLevel, unsigned count) {
|
2016-04-24 05:18:01 +02:00
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// "Benchmark"-like optimization: single-source case
|
|
|
|
bool SingleModule = (ModuleMap.size() == 1);
|
|
|
|
|
2020-02-16 02:23:18 +01:00
|
|
|
// When linking an ELF shared object, dso_local should be dropped. We
|
|
|
|
// conservatively do this for -fpic.
|
|
|
|
bool ClearDSOLocalOnDeclarations =
|
|
|
|
TM.getTargetTriple().isOSBinFormatELF() &&
|
|
|
|
TM.getRelocationModel() != Reloc::Static &&
|
|
|
|
TheModule.getPIELevel() == PIELevel::Default;
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
if (!SingleModule) {
|
2020-02-16 02:23:18 +01:00
|
|
|
promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);
|
2016-03-09 02:37:22 +01:00
|
|
|
|
[LTO] Drop non-prevailing definitions only if linkage is not local or appending
Summary:
This fixes PR 37422
In ELF, non-weak symbols can also be non-prevailing. In this particular
PR, the __llvm_profile_* symbols are non-prevailing but weren't getting
dropped - causing multiply-defined errors with lld.
Also add a test, strong_non_prevailing.ll, to ensure that multiple
copies of a strong symbol are dropped.
To fix the test regressions exposed by this fix,
- do not mark prevailing copies for symbols with 'appending' linkage.
There's no one prevailing copy for such symbols.
- fix the prevailing version in dead-strip-fulllto.ll
- explicitly pass exported symbols to llvm-lto in fumcimport.ll and
funcimport_var.ll
Reviewers: tejohnson, pcc
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith,
dang, srhines, llvm-commits
Differential Revision: https://reviews.llvm.org/D54125
llvm-svn: 346436
2018-11-08 21:10:07 +01:00
|
|
|
// Apply summary-based prevailing-symbol resolution decisions.
|
|
|
|
thinLTOResolvePrevailingInModule(TheModule, DefinedGlobals);
|
2016-04-01 23:53:50 +02:00
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// Save temps: after promotion.
|
2016-05-05 07:14:16 +02:00
|
|
|
saveTempBitcode(TheModule, SaveTempsDir, count, ".1.promoted.bc");
|
2016-04-24 05:18:01 +02:00
|
|
|
}
|
|
|
|
|
2016-05-24 19:24:25 +02:00
|
|
|
// Be friendly and don't nuke totally the module when the client didn't
|
|
|
|
// supply anything to preserve.
|
|
|
|
if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
|
|
|
|
// Apply summary-based internalization decisions.
|
|
|
|
thinLTOInternalizeModule(TheModule, DefinedGlobals);
|
|
|
|
}
|
2016-03-09 02:37:22 +01:00
|
|
|
|
2016-04-24 05:18:01 +02:00
|
|
|
// Save internalized bitcode
|
2016-05-05 07:14:16 +02:00
|
|
|
saveTempBitcode(TheModule, SaveTempsDir, count, ".2.internalized.bc");
|
2016-04-24 05:18:01 +02:00
|
|
|
|
|
|
|
if (!SingleModule) {
|
2020-02-16 02:23:18 +01:00
|
|
|
crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
|
|
|
|
ClearDSOLocalOnDeclarations);
|
2016-03-09 02:37:22 +01:00
|
|
|
|
|
|
|
// Save temps: after cross-module import.
|
2016-05-05 07:14:16 +02:00
|
|
|
saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc");
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
2019-10-18 12:54:14 +02:00
|
|
|
optimizeModule(TheModule, TM, OptLevel, Freestanding, &Index);
|
2016-03-09 02:37:22 +01:00
|
|
|
|
2016-05-05 07:14:16 +02:00
|
|
|
saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc");
|
2016-03-09 02:37:22 +01:00
|
|
|
|
2016-04-01 08:47:02 +02:00
|
|
|
if (DisableCodeGen) {
|
|
|
|
// Configured to stop before CodeGen, serialize the bitcode and return.
|
|
|
|
SmallVector<char, 128> OutputBuffer;
|
|
|
|
{
|
|
|
|
raw_svector_ostream OS(OutputBuffer);
|
2016-09-28 23:00:58 +02:00
|
|
|
ProfileSummaryInfo PSI(TheModule);
|
2017-05-10 20:52:16 +02:00
|
|
|
auto Index = buildModuleSummaryIndex(TheModule, nullptr, &PSI);
|
2018-02-14 20:11:32 +01:00
|
|
|
WriteBitcodeToFile(TheModule, OS, true, &Index);
|
2016-04-01 08:47:02 +02:00
|
|
|
}
|
2019-08-15 17:54:37 +02:00
|
|
|
return std::make_unique<SmallVectorMemoryBuffer>(std::move(OutputBuffer));
|
2016-04-01 08:47:02 +02:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
return codegenModule(TheModule, TM);
|
|
|
|
}
|
|
|
|
|
[LTO] Drop non-prevailing definitions only if linkage is not local or appending
Summary:
This fixes PR 37422
In ELF, non-weak symbols can also be non-prevailing. In this particular
PR, the __llvm_profile_* symbols are non-prevailing but weren't getting
dropped - causing multiply-defined errors with lld.
Also add a test, strong_non_prevailing.ll, to ensure that multiple
copies of a strong symbol are dropped.
To fix the test regressions exposed by this fix,
- do not mark prevailing copies for symbols with 'appending' linkage.
There's no one prevailing copy for such symbols.
- fix the prevailing version in dead-strip-fulllto.ll
- explicitly pass exported symbols to llvm-lto in fumcimport.ll and
funcimport_var.ll
Reviewers: tejohnson, pcc
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith,
dang, srhines, llvm-commits
Differential Revision: https://reviews.llvm.org/D54125
llvm-svn: 346436
2018-11-08 21:10:07 +01:00
|
|
|
/// Resolve prevailing symbols. Record resolutions in the \p ResolvedODR map
|
2016-05-24 19:24:25 +02:00
|
|
|
/// for caching, and in the \p Index for application during the ThinLTO
|
|
|
|
/// backends. This is needed for correctness for exported symbols (ensure
|
|
|
|
/// at least one copy kept) and a compile-time optimization (to drop duplicate
|
|
|
|
/// copies when possible).
|
[LTO] Drop non-prevailing definitions only if linkage is not local or appending
Summary:
This fixes PR 37422
In ELF, non-weak symbols can also be non-prevailing. In this particular
PR, the __llvm_profile_* symbols are non-prevailing but weren't getting
dropped - causing multiply-defined errors with lld.
Also add a test, strong_non_prevailing.ll, to ensure that multiple
copies of a strong symbol are dropped.
To fix the test regressions exposed by this fix,
- do not mark prevailing copies for symbols with 'appending' linkage.
There's no one prevailing copy for such symbols.
- fix the prevailing version in dead-strip-fulllto.ll
- explicitly pass exported symbols to llvm-lto in fumcimport.ll and
funcimport_var.ll
Reviewers: tejohnson, pcc
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith,
dang, srhines, llvm-commits
Differential Revision: https://reviews.llvm.org/D54125
llvm-svn: 346436
2018-11-08 21:10:07 +01:00
|
|
|
static void resolvePrevailingInIndex(
|
2016-05-24 19:24:25 +02:00
|
|
|
ModuleSummaryIndex &Index,
|
|
|
|
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
|
[ThinLTO] Auto-hide prevailing linkonce_odr only when all copies eligible
Summary:
We hit undefined references building with ThinLTO when one source file
contained explicit instantiations of a template method (weak_odr) but
there were also implicit instantiations in another file (linkonce_odr),
and the latter was the prevailing copy. In this case the symbol was
marked hidden when the prevailing linkonce_odr copy was promoted to
weak_odr. It led to unsats when the resulting shared library was linked
with other code that contained a reference (expecting to be resolved due
to the explicit instantiation).
Add a CanAutoHide flag to the GV summary to allow the thin link to
identify when all copies are eligible for auto-hiding (because they were
all originally linkonce_odr global unnamed addr), and only do the
auto-hide in that case.
Most of the changes here are due to plumbing the new flag through the
bitcode and llvm assembly, and resulting test changes. I augmented the
existing auto-hide test to check for this situation.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, arphaman, dang, llvm-commits, steven_wu, wmi
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59709
llvm-svn: 360466
2019-05-10 22:08:24 +02:00
|
|
|
&ResolvedODR,
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
|
|
|
|
const DenseMap<GlobalValue::GUID, const GlobalValueSummary *>
|
|
|
|
&PrevailingCopy) {
|
2016-05-24 19:24:25 +02:00
|
|
|
|
|
|
|
auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
|
|
|
|
const auto &Prevailing = PrevailingCopy.find(GUID);
|
|
|
|
// Not in map means that there was only one copy, which must be prevailing.
|
|
|
|
if (Prevailing == PrevailingCopy.end())
|
|
|
|
return true;
|
|
|
|
return Prevailing->second == S;
|
|
|
|
};
|
|
|
|
|
|
|
|
auto recordNewLinkage = [&](StringRef ModuleIdentifier,
|
|
|
|
GlobalValue::GUID GUID,
|
|
|
|
GlobalValue::LinkageTypes NewLinkage) {
|
|
|
|
ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
|
|
|
|
};
|
|
|
|
|
[ThinLTO] Auto-hide prevailing linkonce_odr only when all copies eligible
Summary:
We hit undefined references building with ThinLTO when one source file
contained explicit instantiations of a template method (weak_odr) but
there were also implicit instantiations in another file (linkonce_odr),
and the latter was the prevailing copy. In this case the symbol was
marked hidden when the prevailing linkonce_odr copy was promoted to
weak_odr. It led to unsats when the resulting shared library was linked
with other code that contained a reference (expecting to be resolved due
to the explicit instantiation).
Add a CanAutoHide flag to the GV summary to allow the thin link to
identify when all copies are eligible for auto-hiding (because they were
all originally linkonce_odr global unnamed addr), and only do the
auto-hide in that case.
Most of the changes here are due to plumbing the new flag through the
bitcode and llvm assembly, and resulting test changes. I augmented the
existing auto-hide test to check for this situation.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, arphaman, dang, llvm-commits, steven_wu, wmi
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59709
llvm-svn: 360466
2019-05-10 22:08:24 +02:00
|
|
|
thinLTOResolvePrevailingInIndex(Index, isPrevailing, recordNewLinkage,
|
|
|
|
GUIDPreservedSymbols);
|
2016-05-24 19:24:25 +02:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// Initialize the TargetMachine builder for a given Triple
|
|
|
|
static void initTMBuilder(TargetMachineBuilder &TMBuilder,
|
|
|
|
const Triple &TheTriple) {
|
|
|
|
// Set a default CPU for Darwin triples (copied from LTOCodeGenerator).
|
|
|
|
// FIXME this looks pretty terrible...
|
|
|
|
if (TMBuilder.MCpu.empty() && TheTriple.isOSDarwin()) {
|
|
|
|
if (TheTriple.getArch() == llvm::Triple::x86_64)
|
|
|
|
TMBuilder.MCpu = "core2";
|
|
|
|
else if (TheTriple.getArch() == llvm::Triple::x86)
|
|
|
|
TMBuilder.MCpu = "yonah";
|
2019-09-12 12:22:23 +02:00
|
|
|
else if (TheTriple.getArch() == llvm::Triple::aarch64 ||
|
|
|
|
TheTriple.getArch() == llvm::Triple::aarch64_32)
|
2016-03-09 02:37:22 +01:00
|
|
|
TMBuilder.MCpu = "cyclone";
|
|
|
|
}
|
|
|
|
TMBuilder.TheTriple = std::move(TheTriple);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) {
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
MemoryBufferRef Buffer(Data, Identifier);
|
2017-05-18 05:52:29 +02:00
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto InputOrError = lto::InputFile::create(Buffer);
|
|
|
|
if (!InputOrError)
|
|
|
|
report_fatal_error("ThinLTO cannot create input file: " +
|
|
|
|
toString(InputOrError.takeError()));
|
2017-05-18 05:52:29 +02:00
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto TripleStr = (*InputOrError)->getTargetTriple();
|
2017-05-18 05:52:29 +02:00
|
|
|
Triple TheTriple(TripleStr);
|
|
|
|
|
|
|
|
if (Modules.empty())
|
2016-03-09 02:37:22 +01:00
|
|
|
initTMBuilder(TMBuilder, Triple(TheTriple));
|
2017-05-18 05:52:29 +02:00
|
|
|
else if (TMBuilder.TheTriple != TheTriple) {
|
|
|
|
if (!TMBuilder.TheTriple.isCompatibleWith(TheTriple))
|
|
|
|
report_fatal_error("ThinLTO modules with incompatible triples not "
|
|
|
|
"supported");
|
|
|
|
initTMBuilder(TMBuilder, Triple(TMBuilder.TheTriple.merge(TheTriple)));
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
2017-05-18 05:52:29 +02:00
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
Modules.emplace_back(std::move(*InputOrError));
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
|
|
|
|
PreservedSymbols.insert(Name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
|
2017-02-03 08:41:43 +01:00
|
|
|
// FIXME: At the moment, we don't take advantage of this extra information,
|
|
|
|
// we're conservatively considering cross-references as preserved.
|
|
|
|
// CrossReferencedSymbols.insert(Name);
|
|
|
|
PreservedSymbols.insert(Name);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// TargetMachine factory
|
|
|
|
std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
|
|
|
|
std::string ErrMsg;
|
|
|
|
const Target *TheTarget =
|
|
|
|
TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg);
|
|
|
|
if (!TheTarget) {
|
|
|
|
report_fatal_error("Can't load target for this Triple: " + ErrMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use MAttr as the default set of features.
|
|
|
|
SubtargetFeatures Features(MAttr);
|
|
|
|
Features.getDefaultSubtargetFeatures(TheTriple);
|
|
|
|
std::string FeatureStr = Features.getString();
|
2016-12-28 20:37:16 +01:00
|
|
|
|
2017-08-03 04:16:21 +02:00
|
|
|
return std::unique_ptr<TargetMachine>(
|
|
|
|
TheTarget->createTargetMachine(TheTriple.str(), MCpu, FeatureStr, Options,
|
|
|
|
RelocModel, None, CGOptLevel));
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-03-15 01:04:37 +01:00
|
|
|
* Produce the combined summary index from all the bitcode files:
|
2016-03-09 02:37:22 +01:00
|
|
|
* "thin-link".
|
|
|
|
*/
|
2016-03-15 01:04:37 +01:00
|
|
|
std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
|
2017-05-02 00:04:36 +02:00
|
|
|
std::unique_ptr<ModuleSummaryIndex> CombinedIndex =
|
2019-08-15 17:54:37 +02:00
|
|
|
std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
|
2016-03-09 02:37:22 +01:00
|
|
|
uint64_t NextModuleId = 0;
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
for (auto &Mod : Modules) {
|
|
|
|
auto &M = Mod->getSingleBitcodeModule();
|
|
|
|
if (Error Err =
|
|
|
|
M.readSummary(*CombinedIndex, Mod->getName(), NextModuleId++)) {
|
2016-03-09 02:37:22 +01:00
|
|
|
// FIXME diagnose
|
2016-11-11 20:50:39 +01:00
|
|
|
logAllUnhandledErrors(
|
2017-05-02 00:04:36 +02:00
|
|
|
std::move(Err), errs(),
|
2017-05-01 22:42:32 +02:00
|
|
|
"error: can't create module summary index for buffer: ");
|
2016-03-09 02:37:22 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CombinedIndex;
|
|
|
|
}
|
|
|
|
|
2019-10-24 10:43:37 +02:00
|
|
|
namespace {
|
2019-10-18 12:54:14 +02:00
|
|
|
struct IsExported {
|
|
|
|
const StringMap<FunctionImporter::ExportSetTy> &ExportLists;
|
|
|
|
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols;
|
|
|
|
|
|
|
|
IsExported(const StringMap<FunctionImporter::ExportSetTy> &ExportLists,
|
|
|
|
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
|
|
|
|
: ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
|
|
|
|
|
2019-11-15 14:13:19 +01:00
|
|
|
bool operator()(StringRef ModuleIdentifier, ValueInfo VI) const {
|
2018-01-17 11:33:05 +01:00
|
|
|
const auto &ExportList = ExportLists.find(ModuleIdentifier);
|
2019-11-15 14:13:19 +01:00
|
|
|
return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
|
|
|
|
GUIDPreservedSymbols.count(VI.getGUID());
|
2019-10-18 12:54:14 +02:00
|
|
|
}
|
|
|
|
};
|
2018-01-17 11:33:05 +01:00
|
|
|
|
2019-10-18 12:54:14 +02:00
|
|
|
struct IsPrevailing {
|
|
|
|
const DenseMap<GlobalValue::GUID, const GlobalValueSummary *> &PrevailingCopy;
|
|
|
|
IsPrevailing(const DenseMap<GlobalValue::GUID, const GlobalValueSummary *>
|
|
|
|
&PrevailingCopy)
|
|
|
|
: PrevailingCopy(PrevailingCopy) {}
|
|
|
|
|
|
|
|
bool operator()(GlobalValue::GUID GUID, const GlobalValueSummary *S) const {
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
const auto &Prevailing = PrevailingCopy.find(GUID);
|
|
|
|
// Not in map means that there was only one copy, which must be prevailing.
|
|
|
|
if (Prevailing == PrevailingCopy.end())
|
|
|
|
return true;
|
|
|
|
return Prevailing->second == S;
|
|
|
|
};
|
2019-10-18 12:54:14 +02:00
|
|
|
};
|
2019-10-24 15:54:08 +02:00
|
|
|
} // namespace
|
2018-01-17 11:33:05 +01:00
|
|
|
|
2018-01-29 09:03:30 +01:00
|
|
|
static void computeDeadSymbolsInIndex(
|
|
|
|
ModuleSummaryIndex &Index,
|
|
|
|
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
|
|
|
|
// We have no symbols resolution available. And can't do any better now in the
|
|
|
|
// case where the prevailing symbol is in a native object. It can be refined
|
|
|
|
// with linker information in the future.
|
|
|
|
auto isPrevailing = [&](GlobalValue::GUID G) {
|
|
|
|
return PrevailingType::Unknown;
|
|
|
|
};
|
2018-11-16 08:08:00 +01:00
|
|
|
computeDeadSymbolsWithConstProp(Index, GUIDPreservedSymbols, isPrevailing,
|
|
|
|
/* ImportEnabled = */ true);
|
2018-01-29 09:03:30 +01:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
/**
|
|
|
|
* Perform promotion and renaming of exported internal functions.
|
2016-05-24 19:24:25 +02:00
|
|
|
* Index is updated to reflect linkage changes from weak resolution.
|
2016-03-09 02:37:22 +01:00
|
|
|
*/
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
void ThinLTOCodeGenerator::promote(Module &TheModule, ModuleSummaryIndex &Index,
|
|
|
|
const lto::InputFile &File) {
|
2016-04-21 07:47:17 +02:00
|
|
|
auto ModuleCount = Index.modulePaths().size();
|
2016-04-16 09:02:16 +02:00
|
|
|
auto ModuleIdentifier = TheModule.getModuleIdentifier();
|
2016-11-14 20:21:41 +01:00
|
|
|
|
2016-04-16 09:02:16 +02:00
|
|
|
// Collect for each module the list of function it defines (GUID -> Summary).
|
2016-04-25 23:09:51 +02:00
|
|
|
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
|
2016-04-16 09:02:16 +02:00
|
|
|
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
2016-04-01 23:53:50 +02:00
|
|
|
|
2017-01-05 22:34:18 +01:00
|
|
|
// Convert the preserved symbols set from string to GUID
|
2017-02-03 08:41:43 +01:00
|
|
|
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
|
2017-01-05 22:34:18 +01:00
|
|
|
PreservedSymbols, Triple(TheModule.getTargetTriple()));
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
// Add used symbol to the preserved symbols.
|
|
|
|
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
|
|
|
|
|
2017-01-05 22:34:18 +01:00
|
|
|
// Compute "dead" symbols, we don't want to import/export these!
|
2018-01-29 09:03:30 +01:00
|
|
|
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
|
2017-01-05 22:34:18 +01:00
|
|
|
|
2016-04-21 07:47:17 +02:00
|
|
|
// Generate import/export list
|
|
|
|
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
|
|
|
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
|
|
|
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
2017-06-01 22:30:06 +02:00
|
|
|
ExportLists);
|
2016-04-21 07:47:17 +02:00
|
|
|
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
|
|
|
|
computePrevailingCopies(Index, PrevailingCopy);
|
|
|
|
|
[LTO] Drop non-prevailing definitions only if linkage is not local or appending
Summary:
This fixes PR 37422
In ELF, non-weak symbols can also be non-prevailing. In this particular
PR, the __llvm_profile_* symbols are non-prevailing but weren't getting
dropped - causing multiply-defined errors with lld.
Also add a test, strong_non_prevailing.ll, to ensure that multiple
copies of a strong symbol are dropped.
To fix the test regressions exposed by this fix,
- do not mark prevailing copies for symbols with 'appending' linkage.
There's no one prevailing copy for such symbols.
- fix the prevailing version in dead-strip-fulllto.ll
- explicitly pass exported symbols to llvm-lto in fumcimport.ll and
funcimport_var.ll
Reviewers: tejohnson, pcc
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith,
dang, srhines, llvm-commits
Differential Revision: https://reviews.llvm.org/D54125
llvm-svn: 346436
2018-11-08 21:10:07 +01:00
|
|
|
// Resolve prevailing symbols
|
2016-05-24 19:24:25 +02:00
|
|
|
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
|
|
|
|
PrevailingCopy);
|
2016-05-24 19:24:25 +02:00
|
|
|
|
2019-04-08 20:53:21 +02:00
|
|
|
thinLTOResolvePrevailingInModule(
|
|
|
|
TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
|
|
|
|
|
2016-11-14 20:21:41 +01:00
|
|
|
// Promote the exported values in the index, so that they are promoted
|
|
|
|
// in the module.
|
2019-10-18 12:54:14 +02:00
|
|
|
thinLTOInternalizeAndPromoteInIndex(
|
|
|
|
Index, IsExported(ExportLists, GUIDPreservedSymbols),
|
|
|
|
IsPrevailing(PrevailingCopy));
|
2016-11-14 20:21:41 +01:00
|
|
|
|
2020-02-16 02:23:18 +01:00
|
|
|
// FIXME Set ClearDSOLocalOnDeclarations.
|
|
|
|
promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform cross-module importing for the module identified by ModuleIdentifier.
|
|
|
|
*/
|
|
|
|
void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
ModuleSummaryIndex &Index,
|
|
|
|
const lto::InputFile &File) {
|
2016-03-09 02:37:22 +01:00
|
|
|
auto ModuleMap = generateModuleMap(Modules);
|
2016-04-16 09:02:16 +02:00
|
|
|
auto ModuleCount = Index.modulePaths().size();
|
|
|
|
|
|
|
|
// Collect for each module the list of function it defines (GUID -> Summary).
|
2016-04-25 23:09:51 +02:00
|
|
|
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
|
2016-04-16 09:02:16 +02:00
|
|
|
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
2016-03-26 06:40:34 +01:00
|
|
|
|
2017-01-05 22:34:18 +01:00
|
|
|
// Convert the preserved symbols set from string to GUID
|
2017-02-03 08:41:43 +01:00
|
|
|
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
|
2017-01-05 22:34:18 +01:00
|
|
|
PreservedSymbols, Triple(TheModule.getTargetTriple()));
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
|
|
|
|
|
2017-01-05 22:34:18 +01:00
|
|
|
// Compute "dead" symbols, we don't want to import/export these!
|
2018-01-29 09:03:30 +01:00
|
|
|
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
|
2017-01-05 22:34:18 +01:00
|
|
|
|
2016-03-26 06:40:34 +01:00
|
|
|
// Generate import/export list
|
|
|
|
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
|
|
|
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
2016-04-16 09:02:16 +02:00
|
|
|
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
2017-06-01 22:30:06 +02:00
|
|
|
ExportLists);
|
2016-03-26 06:40:34 +01:00
|
|
|
auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
|
|
|
|
|
2020-02-16 02:23:18 +01:00
|
|
|
// FIXME Set ClearDSOLocalOnDeclarations.
|
|
|
|
crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
|
|
|
|
/*ClearDSOLocalOnDeclarations=*/false);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
2016-05-10 15:48:23 +02:00
|
|
|
/**
|
|
|
|
* Compute the list of summaries needed for importing into module.
|
|
|
|
*/
|
|
|
|
void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
Module &TheModule, ModuleSummaryIndex &Index,
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
|
|
|
|
const lto::InputFile &File) {
|
2016-05-10 15:48:23 +02:00
|
|
|
auto ModuleCount = Index.modulePaths().size();
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
auto ModuleIdentifier = TheModule.getModuleIdentifier();
|
2016-05-10 15:48:23 +02:00
|
|
|
|
|
|
|
// Collect for each module the list of function it defines (GUID -> Summary).
|
|
|
|
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
|
|
|
|
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
|
|
|
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
// Convert the preserved symbols set from string to GUID
|
|
|
|
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
|
|
|
|
PreservedSymbols, Triple(TheModule.getTargetTriple()));
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
|
|
|
|
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
// Compute "dead" symbols, we don't want to import/export these!
|
|
|
|
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
|
|
|
|
|
2016-05-10 15:48:23 +02:00
|
|
|
// Generate import/export list
|
|
|
|
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
|
|
|
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
|
|
|
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
|
|
|
ExportLists);
|
|
|
|
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
llvm::gatherImportedSummariesForModule(
|
|
|
|
ModuleIdentifier, ModuleToDefinedGVSummaries,
|
|
|
|
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
|
2016-05-10 15:48:23 +02:00
|
|
|
}
|
|
|
|
|
2016-05-10 17:54:09 +02:00
|
|
|
/**
|
|
|
|
* Emit the list of files needed for importing into module.
|
|
|
|
*/
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
ModuleSummaryIndex &Index,
|
|
|
|
const lto::InputFile &File) {
|
2016-05-10 17:54:09 +02:00
|
|
|
auto ModuleCount = Index.modulePaths().size();
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
auto ModuleIdentifier = TheModule.getModuleIdentifier();
|
2016-05-10 17:54:09 +02:00
|
|
|
|
|
|
|
// Collect for each module the list of function it defines (GUID -> Summary).
|
|
|
|
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
|
|
|
|
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
|
|
|
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
// Convert the preserved symbols set from string to GUID
|
|
|
|
auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
|
|
|
|
PreservedSymbols, Triple(TheModule.getTargetTriple()));
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
|
|
|
|
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
// Compute "dead" symbols, we don't want to import/export these!
|
|
|
|
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
|
|
|
|
|
2016-05-10 17:54:09 +02:00
|
|
|
// Generate import/export list
|
|
|
|
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
|
|
|
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
|
|
|
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
|
|
|
ExportLists);
|
|
|
|
|
2018-07-10 22:06:04 +02:00
|
|
|
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
llvm::gatherImportedSummariesForModule(
|
|
|
|
ModuleIdentifier, ModuleToDefinedGVSummaries,
|
|
|
|
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
|
2018-07-10 22:06:04 +02:00
|
|
|
|
2016-05-10 17:54:09 +02:00
|
|
|
std::error_code EC;
|
[ThinLTO] Import local variables from the same module as caller
Summary:
We can sometimes end up with multiple copies of a local variable that
have the same GUID in the index. This happens when there are local
variables with the same name that are in different source files having the
same name/path at compile time (but compiled into different bitcode objects).
In this case make sure we import the copy in the caller's module.
This enables importing both of the variables having the same GUID
(but which will have different promoted names since the module paths,
and therefore the module hashes, will be distinct).
Importing the wrong copy is particularly problematic for read only
variables, since we must import them as a local copy whenever
referenced. Otherwise we get undefs at link time.
Note that the llvm-lto.cpp and ThinLTOCodeGenerator changes are needed
for testing the distributed index case via clang, which will be sent as
a separate clang-side patch shortly. We were previously not doing the
dead code/read only computation before computing imports when testing
distributed index generation (like it was for testing importing and
other ThinLTO mechanisms alone).
Reviewers: evgeny777
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D55047
llvm-svn: 347886
2018-11-29 18:02:42 +01:00
|
|
|
if ((EC = EmitImportsFiles(ModuleIdentifier, OutputName,
|
|
|
|
ModuleToSummariesForIndex)))
|
2016-05-10 17:54:09 +02:00
|
|
|
report_fatal_error(Twine("Failed to open ") + OutputName +
|
|
|
|
" to save imports lists\n");
|
|
|
|
}
|
|
|
|
|
2016-04-24 05:18:01 +02:00
|
|
|
/**
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
* Perform internalization. Runs promote and internalization together.
|
|
|
|
* Index is updated to reflect linkage changes.
|
2016-04-24 05:18:01 +02:00
|
|
|
*/
|
|
|
|
void ThinLTOCodeGenerator::internalize(Module &TheModule,
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
ModuleSummaryIndex &Index,
|
|
|
|
const lto::InputFile &File) {
|
2016-04-24 05:18:01 +02:00
|
|
|
initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
|
|
|
|
auto ModuleCount = Index.modulePaths().size();
|
|
|
|
auto ModuleIdentifier = TheModule.getModuleIdentifier();
|
|
|
|
|
|
|
|
// Convert the preserved symbols set from string to GUID
|
|
|
|
auto GUIDPreservedSymbols =
|
2017-02-03 08:41:43 +01:00
|
|
|
computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
|
2016-04-24 05:18:01 +02:00
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
|
|
|
|
|
2016-04-24 05:18:01 +02:00
|
|
|
// Collect for each module the list of function it defines (GUID -> Summary).
|
2016-04-25 23:09:51 +02:00
|
|
|
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
|
2016-04-24 05:18:01 +02:00
|
|
|
Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
|
|
|
|
2017-01-05 22:34:18 +01:00
|
|
|
// Compute "dead" symbols, we don't want to import/export these!
|
2018-01-29 09:03:30 +01:00
|
|
|
computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
|
2017-01-05 22:34:18 +01:00
|
|
|
|
2016-04-24 05:18:01 +02:00
|
|
|
// Generate import/export list
|
|
|
|
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
|
|
|
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
|
|
|
ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
|
2017-06-01 22:30:06 +02:00
|
|
|
ExportLists);
|
2016-04-24 05:18:01 +02:00
|
|
|
auto &ExportList = ExportLists[ModuleIdentifier];
|
|
|
|
|
2016-05-24 19:24:25 +02:00
|
|
|
// Be friendly and don't nuke totally the module when the client didn't
|
|
|
|
// supply anything to preserve.
|
|
|
|
if (ExportList.empty() && GUIDPreservedSymbols.empty())
|
|
|
|
return;
|
|
|
|
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
|
|
|
|
computePrevailingCopies(Index, PrevailingCopy);
|
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
// Resolve prevailing symbols
|
|
|
|
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
|
|
|
|
PrevailingCopy);
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
|
|
|
|
// Promote the exported values in the index, so that they are promoted
|
|
|
|
// in the module.
|
2019-10-18 12:54:14 +02:00
|
|
|
thinLTOInternalizeAndPromoteInIndex(
|
|
|
|
Index, IsExported(ExportLists, GUIDPreservedSymbols),
|
|
|
|
IsPrevailing(PrevailingCopy));
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
|
2020-02-16 02:23:18 +01:00
|
|
|
// FIXME Set ClearDSOLocalOnDeclarations.
|
|
|
|
promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
|
|
|
|
// Internalization
|
|
|
|
thinLTOResolvePrevailingInModule(
|
|
|
|
TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
|
|
|
|
|
2016-05-24 19:24:25 +02:00
|
|
|
thinLTOInternalizeModule(TheModule,
|
|
|
|
ModuleToDefinedGVSummaries[ModuleIdentifier]);
|
2016-04-24 05:18:01 +02:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
/**
|
|
|
|
* Perform post-importing ThinLTO optimizations.
|
|
|
|
*/
|
|
|
|
void ThinLTOCodeGenerator::optimize(Module &TheModule) {
|
|
|
|
initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
|
2016-04-24 05:18:01 +02:00
|
|
|
|
|
|
|
// Optimize now
|
2019-10-18 12:54:14 +02:00
|
|
|
optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding,
|
|
|
|
nullptr);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
2016-12-14 05:56:42 +01:00
|
|
|
/// Write out the generated object file, either from CacheEntryPath or from
|
|
|
|
/// OutputBuffer, preferring hard-link when possible.
|
|
|
|
/// Returns the path to the generated file in SavedObjectsDirectoryPath.
|
[ThinLTO] Adding architecture name into saved object filename
Summary:
For ThinLTOCodegenerator, it has an option to save the object file
outputs into a directory which is essential for debug info. Tools like lldb
and dsymutil will look for these object files for debug info.
On Darwin platform, you can link fat binaries with one single clang
driver invocation like:
$ clang -arch x86_64 -arch i386 -Wl,-object_path_lto,$TMPDIR ...
Unfornately, the output object files for one architecture is going to
overwrite the previous ones and one architecture slice will end up with
no debug info. One example for this is to turn on ThinLTO for sanitizer
dylibs in compiler-rt project.
To fix the issue, add the name for the architecture into the name of the
output object file.
rdar://problem/35482935
Reviewers: tejohnson, bd1976llvm, dexonsmith, JDevlieghere
Reviewed By: dexonsmith
Subscribers: mehdi_amini, aprantl, inglorion, eraman, hiraditya, jkorous, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60924
llvm-svn: 359508
2019-04-29 23:39:54 +02:00
|
|
|
std::string
|
|
|
|
ThinLTOCodeGenerator::writeGeneratedObject(int count, StringRef CacheEntryPath,
|
|
|
|
const MemoryBuffer &OutputBuffer) {
|
|
|
|
auto ArchName = TMBuilder.TheTriple.getArchName();
|
2016-12-14 05:56:42 +01:00
|
|
|
SmallString<128> OutputPath(SavedObjectsDirectoryPath);
|
[ThinLTO] Adding architecture name into saved object filename
Summary:
For ThinLTOCodegenerator, it has an option to save the object file
outputs into a directory which is essential for debug info. Tools like lldb
and dsymutil will look for these object files for debug info.
On Darwin platform, you can link fat binaries with one single clang
driver invocation like:
$ clang -arch x86_64 -arch i386 -Wl,-object_path_lto,$TMPDIR ...
Unfornately, the output object files for one architecture is going to
overwrite the previous ones and one architecture slice will end up with
no debug info. One example for this is to turn on ThinLTO for sanitizer
dylibs in compiler-rt project.
To fix the issue, add the name for the architecture into the name of the
output object file.
rdar://problem/35482935
Reviewers: tejohnson, bd1976llvm, dexonsmith, JDevlieghere
Reviewed By: dexonsmith
Subscribers: mehdi_amini, aprantl, inglorion, eraman, hiraditya, jkorous, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60924
llvm-svn: 359508
2019-04-29 23:39:54 +02:00
|
|
|
llvm::sys::path::append(OutputPath,
|
|
|
|
Twine(count) + "." + ArchName + ".thinlto.o");
|
2016-12-14 05:56:42 +01:00
|
|
|
OutputPath.c_str(); // Ensure the string is null terminated.
|
|
|
|
if (sys::fs::exists(OutputPath))
|
|
|
|
sys::fs::remove(OutputPath);
|
|
|
|
|
|
|
|
// We don't return a memory buffer to the linker, just a list of files.
|
|
|
|
if (!CacheEntryPath.empty()) {
|
|
|
|
// Cache is enabled, hard-link the entry (or copy if hard-link fails).
|
|
|
|
auto Err = sys::fs::create_hard_link(CacheEntryPath, OutputPath);
|
|
|
|
if (!Err)
|
2020-01-28 20:23:46 +01:00
|
|
|
return std::string(OutputPath.str());
|
2016-12-14 05:56:42 +01:00
|
|
|
// Hard linking failed, try to copy.
|
|
|
|
Err = sys::fs::copy_file(CacheEntryPath, OutputPath);
|
|
|
|
if (!Err)
|
2020-01-28 20:23:46 +01:00
|
|
|
return std::string(OutputPath.str());
|
2016-12-14 05:56:42 +01:00
|
|
|
// Copy failed (could be because the CacheEntry was removed from the cache
|
|
|
|
// in the meantime by another process), fall back and try to write down the
|
|
|
|
// buffer to the output.
|
2020-06-20 00:58:51 +02:00
|
|
|
errs() << "remark: can't link or copy from cached entry '" << CacheEntryPath
|
2016-12-14 05:56:42 +01:00
|
|
|
<< "' to '" << OutputPath << "'\n";
|
|
|
|
}
|
|
|
|
// No cache entry, just write out the buffer.
|
|
|
|
std::error_code Err;
|
2019-08-05 07:43:48 +02:00
|
|
|
raw_fd_ostream OS(OutputPath, Err, sys::fs::OF_None);
|
2016-12-14 05:56:42 +01:00
|
|
|
if (Err)
|
|
|
|
report_fatal_error("Can't open output '" + OutputPath + "'\n");
|
|
|
|
OS << OutputBuffer.getBuffer();
|
2020-01-28 20:23:46 +01:00
|
|
|
return std::string(OutputPath.str());
|
2016-12-14 05:56:42 +01:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// Main entry point for the ThinLTO processing
|
|
|
|
void ThinLTOCodeGenerator::run() {
|
2017-01-20 23:45:34 +01:00
|
|
|
// Prepare the resulting object vector
|
|
|
|
assert(ProducedBinaries.empty() && "The generator should not be reused");
|
|
|
|
if (SavedObjectsDirectoryPath.empty())
|
|
|
|
ProducedBinaries.resize(Modules.size());
|
|
|
|
else {
|
|
|
|
sys::fs::create_directories(SavedObjectsDirectoryPath);
|
|
|
|
bool IsDir;
|
|
|
|
sys::fs::is_directory(SavedObjectsDirectoryPath, IsDir);
|
|
|
|
if (!IsDir)
|
|
|
|
report_fatal_error("Unexistent dir: '" + SavedObjectsDirectoryPath + "'");
|
|
|
|
ProducedBinaryFiles.resize(Modules.size());
|
|
|
|
}
|
|
|
|
|
2016-04-01 08:47:02 +02:00
|
|
|
if (CodeGenOnly) {
|
|
|
|
// Perform only parallel codegen and return.
|
|
|
|
ThreadPool Pool;
|
|
|
|
int count = 0;
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
for (auto &Mod : Modules) {
|
2016-04-01 08:47:02 +02:00
|
|
|
Pool.async([&](int count) {
|
|
|
|
LLVMContext Context;
|
|
|
|
Context.setDiscardValueNames(LTODiscardValueNames);
|
|
|
|
|
|
|
|
// Parse module now
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
|
|
|
|
/*IsImporting*/ false);
|
2016-04-01 08:47:02 +02:00
|
|
|
|
|
|
|
// CodeGen
|
2018-09-05 00:54:17 +02:00
|
|
|
auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create());
|
2017-01-20 23:45:34 +01:00
|
|
|
if (SavedObjectsDirectoryPath.empty())
|
|
|
|
ProducedBinaries[count] = std::move(OutputBuffer);
|
|
|
|
else
|
[ThinLTO] Adding architecture name into saved object filename
Summary:
For ThinLTOCodegenerator, it has an option to save the object file
outputs into a directory which is essential for debug info. Tools like lldb
and dsymutil will look for these object files for debug info.
On Darwin platform, you can link fat binaries with one single clang
driver invocation like:
$ clang -arch x86_64 -arch i386 -Wl,-object_path_lto,$TMPDIR ...
Unfornately, the output object files for one architecture is going to
overwrite the previous ones and one architecture slice will end up with
no debug info. One example for this is to turn on ThinLTO for sanitizer
dylibs in compiler-rt project.
To fix the issue, add the name for the architecture into the name of the
output object file.
rdar://problem/35482935
Reviewers: tejohnson, bd1976llvm, dexonsmith, JDevlieghere
Reviewed By: dexonsmith
Subscribers: mehdi_amini, aprantl, inglorion, eraman, hiraditya, jkorous, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60924
llvm-svn: 359508
2019-04-29 23:39:54 +02:00
|
|
|
ProducedBinaryFiles[count] =
|
|
|
|
writeGeneratedObject(count, "", *OutputBuffer);
|
2016-04-01 08:47:02 +02:00
|
|
|
}, count++);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// Sequential linking phase
|
|
|
|
auto Index = linkCombinedIndex();
|
|
|
|
|
|
|
|
// Save temps: index.
|
|
|
|
if (!SaveTempsDir.empty()) {
|
|
|
|
auto SaveTempPath = SaveTempsDir + "index.bc";
|
|
|
|
std::error_code EC;
|
2019-08-05 07:43:48 +02:00
|
|
|
raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
|
2016-03-09 02:37:22 +01:00
|
|
|
if (EC)
|
|
|
|
report_fatal_error(Twine("Failed to open ") + SaveTempPath +
|
|
|
|
" to save optimized bitcode\n");
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-11 19:52:24 +01:00
|
|
|
WriteIndexToFile(*Index, OS);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare the module map.
|
|
|
|
auto ModuleMap = generateModuleMap(Modules);
|
2016-03-26 06:40:34 +01:00
|
|
|
auto ModuleCount = Modules.size();
|
|
|
|
|
2016-04-16 09:02:16 +02:00
|
|
|
// Collect for each module the list of function it defines (GUID -> Summary).
|
2016-04-25 23:09:51 +02:00
|
|
|
StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
|
2016-04-16 09:02:16 +02:00
|
|
|
Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
|
|
|
|
|
2017-01-05 22:34:18 +01:00
|
|
|
// Convert the preserved symbols set from string to GUID, this is needed for
|
|
|
|
// computing the caching hash and the internalization.
|
|
|
|
auto GUIDPreservedSymbols =
|
2017-02-03 08:41:43 +01:00
|
|
|
computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
|
2017-01-05 22:34:18 +01:00
|
|
|
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
// Add used symbol from inputs to the preserved symbols.
|
|
|
|
for (const auto &M : Modules)
|
|
|
|
addUsedSymbolToPreservedGUID(*M, GUIDPreservedSymbols);
|
|
|
|
|
2017-01-05 22:34:18 +01:00
|
|
|
// Compute "dead" symbols, we don't want to import/export these!
|
2018-01-29 09:03:30 +01:00
|
|
|
computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols);
|
2017-01-05 22:34:18 +01:00
|
|
|
|
2018-12-13 20:54:27 +01:00
|
|
|
// Synthesize entry counts for functions in the combined index.
|
|
|
|
computeSyntheticCounts(*Index);
|
|
|
|
|
2020-01-24 21:24:18 +01:00
|
|
|
// Currently there is no support for enabling whole program visibility via a
|
|
|
|
// linker option in the old LTO API, but this call allows it to be specified
|
|
|
|
// via the internal option. Must be done before WPD below.
|
|
|
|
updateVCallVisibilityInIndex(*Index,
|
|
|
|
/* WholeProgramVisibilityEnabledInLTO */ false);
|
|
|
|
|
2019-10-18 12:54:14 +02:00
|
|
|
// Perform index-based WPD. This will return immediately if there are
|
|
|
|
// no index entries in the typeIdMetadata map (e.g. if we are instead
|
|
|
|
// performing IR-based WPD in hybrid regular/thin LTO mode).
|
|
|
|
std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
|
|
|
|
std::set<GlobalValue::GUID> ExportedGUIDs;
|
|
|
|
runWholeProgramDevirtOnIndex(*Index, ExportedGUIDs, LocalWPDTargetsMap);
|
|
|
|
for (auto GUID : ExportedGUIDs)
|
|
|
|
GUIDPreservedSymbols.insert(GUID);
|
|
|
|
|
2016-03-26 06:40:34 +01:00
|
|
|
// Collect the import/export lists for all modules from the call-graph in the
|
|
|
|
// combined index.
|
|
|
|
StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
|
|
|
|
StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
|
2016-04-16 09:02:16 +02:00
|
|
|
ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries, ImportLists,
|
2017-06-01 22:30:06 +02:00
|
|
|
ExportLists);
|
2016-04-21 07:54:23 +02:00
|
|
|
|
2016-05-24 19:24:25 +02:00
|
|
|
// We use a std::map here to be able to have a defined ordering when
|
|
|
|
// producing a hash for the cache entry.
|
|
|
|
// FIXME: we should be able to compute the caching hash for the entry based
|
|
|
|
// on the index, and nuke this map.
|
|
|
|
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
|
|
|
|
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
|
|
|
|
computePrevailingCopies(*Index, PrevailingCopy);
|
|
|
|
|
[LTO] Drop non-prevailing definitions only if linkage is not local or appending
Summary:
This fixes PR 37422
In ELF, non-weak symbols can also be non-prevailing. In this particular
PR, the __llvm_profile_* symbols are non-prevailing but weren't getting
dropped - causing multiply-defined errors with lld.
Also add a test, strong_non_prevailing.ll, to ensure that multiple
copies of a strong symbol are dropped.
To fix the test regressions exposed by this fix,
- do not mark prevailing copies for symbols with 'appending' linkage.
There's no one prevailing copy for such symbols.
- fix the prevailing version in dead-strip-fulllto.ll
- explicitly pass exported symbols to llvm-lto in fumcimport.ll and
funcimport_var.ll
Reviewers: tejohnson, pcc
Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith,
dang, srhines, llvm-commits
Differential Revision: https://reviews.llvm.org/D54125
llvm-svn: 346436
2018-11-08 21:10:07 +01:00
|
|
|
// Resolve prevailing symbols, this has to be computed early because it
|
2016-05-24 19:24:25 +02:00
|
|
|
// impacts the caching.
|
[ThinLTO] Fix handling of weak interposable symbols
Summary:
Keep aliasees alive if their alias is live, otherwise we end up with an
alias to a declaration, which is invalid. This can happen when the
aliasee is weak and non-prevailing.
This fix exposed the fact that we were then attempting to internalize
the weak symbol, which was not exported as it was not prevailing. We
should not internalize interposable symbols in general, unless this is
the prevailing copy, since it can lead to incorrect inlining and other
optimizations. Most of the changes in this patch are due to the
restructuring required to pass down the prevailing callback.
Finally, while implementing the test cases, I found that in the case of
a weak aliasee that is still marked not live because its alias isn't
live, after dropping the definition we incorrectly marked the
declaration with weak linkage when resolving prevailing symbols in the
module. This was due to some special case handling for symbols marked
WeakLinkage in the summary located before instead of after a subsequent
check for the symbol being a declaration. It turns out that we don't
actually need this special case handling any more (looking back at the
history, when that was added the code was structured quite differently)
- we will correctly mark with weak linkage further below when the
definition hasn't been dropped.
Fixes PR42542.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, steven_wu, dexonsmith, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66264
llvm-svn: 369766
2019-08-23 17:18:58 +02:00
|
|
|
resolvePrevailingInIndex(*Index, ResolvedODR, GUIDPreservedSymbols,
|
|
|
|
PrevailingCopy);
|
2016-05-24 19:24:25 +02:00
|
|
|
|
|
|
|
// Use global summary-based analysis to identify symbols that can be
|
|
|
|
// internalized (because they aren't exported or preserved as per callback).
|
|
|
|
// Changes are made in the index, consumed in the ThinLTO backends.
|
2019-10-18 12:54:14 +02:00
|
|
|
updateIndexWPDForExports(*Index,
|
|
|
|
IsExported(ExportLists, GUIDPreservedSymbols),
|
|
|
|
LocalWPDTargetsMap);
|
|
|
|
thinLTOInternalizeAndPromoteInIndex(
|
|
|
|
*Index, IsExported(ExportLists, GUIDPreservedSymbols),
|
|
|
|
IsPrevailing(PrevailingCopy));
|
2016-05-24 19:24:25 +02:00
|
|
|
|
[ThinLTOCodeGenerator] Avoid Rehash StringMap in ThreadPool
Summary:
During threaded thinLTO, it is possible that the entry for current
module doesn't exist in StringMaps (like ExportLists, ResolvedODR,
etc.). Using operator[] might trigger a rehash for the StringMap, which
might happen on multiple threads at the same time.
rdar://problem/43846199
Reviewers: tejohnson, mehdi_amini, kromanova, pcc
Reviewed By: tejohnson
Subscribers: dang, inglorion, eraman, dexonsmith, llvm-commits
Differential Revision: https://reviews.llvm.org/D52049
llvm-svn: 342263
2018-09-14 21:38:21 +02:00
|
|
|
// Make sure that every module has an entry in the ExportLists, ImportList,
|
|
|
|
// GVSummary and ResolvedODR maps to enable threaded access to these maps
|
|
|
|
// below.
|
|
|
|
for (auto &Module : Modules) {
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto ModuleIdentifier = Module->getName();
|
[ThinLTOCodeGenerator] Avoid Rehash StringMap in ThreadPool
Summary:
During threaded thinLTO, it is possible that the entry for current
module doesn't exist in StringMaps (like ExportLists, ResolvedODR,
etc.). Using operator[] might trigger a rehash for the StringMap, which
might happen on multiple threads at the same time.
rdar://problem/43846199
Reviewers: tejohnson, mehdi_amini, kromanova, pcc
Reviewed By: tejohnson
Subscribers: dang, inglorion, eraman, dexonsmith, llvm-commits
Differential Revision: https://reviews.llvm.org/D52049
llvm-svn: 342263
2018-09-14 21:38:21 +02:00
|
|
|
ExportLists[ModuleIdentifier];
|
|
|
|
ImportLists[ModuleIdentifier];
|
|
|
|
ResolvedODR[ModuleIdentifier];
|
|
|
|
ModuleToDefinedGVSummaries[ModuleIdentifier];
|
2016-05-24 20:44:01 +02:00
|
|
|
}
|
2016-05-15 07:49:47 +02:00
|
|
|
|
2016-05-16 21:33:07 +02:00
|
|
|
// Compute the ordering we will process the inputs: the rough heuristic here
|
|
|
|
// is to sort them per size so that the largest module get schedule as soon as
|
|
|
|
// possible. This is purely a compile-time optimization.
|
|
|
|
std::vector<int> ModulesOrdering;
|
|
|
|
ModulesOrdering.resize(Modules.size());
|
|
|
|
std::iota(ModulesOrdering.begin(), ModulesOrdering.end(), 0);
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 04:13:45 +02:00
|
|
|
llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto LSize =
|
|
|
|
Modules[LeftIndex]->getSingleBitcodeModule().getBuffer().size();
|
|
|
|
auto RSize =
|
|
|
|
Modules[RightIndex]->getSingleBitcodeModule().getBuffer().size();
|
llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...)
Summary: The convenience wrapper in STLExtras is available since rL342102.
Reviewers: dblaikie, javed.absar, JDevlieghere, andreadb
Subscribers: MatzeB, sanjoy, arsenm, dschuff, mehdi_amini, sdardis, nemanjai, jvesely, nhaehnle, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, javed.absar, gbedwell, jrtc27, mgrang, atanasyan, steven_wu, george.burgess.iv, dexonsmith, kristina, jsji, llvm-commits
Differential Revision: https://reviews.llvm.org/D52573
llvm-svn: 343163
2018-09-27 04:13:45 +02:00
|
|
|
return LSize > RSize;
|
|
|
|
});
|
2016-05-16 21:33:07 +02:00
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// Parallel optimizer + codegen
|
|
|
|
{
|
[Support] On Windows, ensure hardware_concurrency() extends to all CPU sockets and all NUMA groups
The goal of this patch is to maximize CPU utilization on multi-socket or high core count systems, so that parallel computations such as LLD/ThinLTO can use all hardware threads in the system. Before this patch, on Windows, a maximum of 64 hardware threads could be used at most, in some cases dispatched only on one CPU socket.
== Background ==
Windows doesn't have a flat cpu_set_t like Linux. Instead, it projects hardware CPUs (or NUMA nodes) to applications through a concept of "processor groups". A "processor" is the smallest unit of execution on a CPU, that is, an hyper-thread if SMT is active; a core otherwise. There's a limit of 32-bit processors on older 32-bit versions of Windows, which later was raised to 64-processors with 64-bit versions of Windows. This limit comes from the affinity mask, which historically is represented by the sizeof(void*). Consequently, the concept of "processor groups" was introduced for dealing with systems with more than 64 hyper-threads.
By default, the Windows OS assigns only one "processor group" to each starting application, in a round-robin manner. If the application wants to use more processors, it needs to programmatically enable it, by assigning threads to other "processor groups". This also means that affinity cannot cross "processor group" boundaries; one can only specify a "preferred" group on start-up, but the application is free to allocate more groups if it wants to.
This creates a peculiar situation, where newer CPUs like the AMD EPYC 7702P (64-cores, 128-hyperthreads) are projected by the OS as two (2) "processor groups". This means that by default, an application can only use half of the cores. This situation could only get worse in the years to come, as dies with more cores will appear on the market.
== The problem ==
The heavyweight_hardware_concurrency() API was introduced so that only *one hardware thread per core* was used. Once that API returns, that original intention is lost, only the number of threads is retained. Consider a situation, on Windows, where the system has 2 CPU sockets, 18 cores each, each core having 2 hyper-threads, for a total of 72 hyper-threads. Both heavyweight_hardware_concurrency() and hardware_concurrency() currently return 36, because on Windows they are simply wrappers over std::thread::hardware_concurrency() -- which can only return processors from the current "processor group".
== The changes in this patch ==
To solve this situation, we capture (and retain) the initial intention until the point of usage, through a new ThreadPoolStrategy class. The number of threads to use is deferred as late as possible, until the moment where the std::threads are created (ThreadPool in the case of ThinLTO).
When using hardware_concurrency(), setting ThreadCount to 0 now means to use all the possible hardware CPU (SMT) threads. Providing a ThreadCount above to the maximum number of threads will have no effect, the maximum will be used instead.
The heavyweight_hardware_concurrency() is similar to hardware_concurrency(), except that only one thread per hardware *core* will be used.
When LLVM_ENABLE_THREADS is OFF, the threading APIs will always return 1, to ensure any caller loops will be exercised at least once.
Differential Revision: https://reviews.llvm.org/D71775
2020-02-14 04:49:57 +01:00
|
|
|
ThreadPool Pool(heavyweight_hardware_concurrency(ThreadCount));
|
2016-05-16 21:33:07 +02:00
|
|
|
for (auto IndexCount : ModulesOrdering) {
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto &Mod = Modules[IndexCount];
|
2016-03-09 02:37:22 +01:00
|
|
|
Pool.async([&](int count) {
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto ModuleIdentifier = Mod->getName();
|
2016-04-21 07:47:17 +02:00
|
|
|
auto &ExportList = ExportLists[ModuleIdentifier];
|
2016-04-16 09:02:16 +02:00
|
|
|
|
2018-11-16 08:08:00 +01:00
|
|
|
auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
|
2016-04-21 07:54:23 +02:00
|
|
|
|
|
|
|
// The module may be cached, this helps handling it.
|
2016-04-24 05:18:01 +02:00
|
|
|
ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
|
|
|
|
ImportLists[ModuleIdentifier], ExportList,
|
2016-05-24 19:24:25 +02:00
|
|
|
ResolvedODR[ModuleIdentifier],
|
[ThinLTO] Consolidate cache key computation between new/old LTO APIs
Summary:
The old legacy LTO API had a separate cache key computation, which was
a subset of the cache key computation in the new LTO API (from what I
can tell this is largely just because certain features such as CFI,
dsoLocal, etc are only utilized via the new LTO API). However, having
separate computations is unnecessary (much of the code is duplicated),
and can lead to bugs when adding new optimizations if both cache
computation algorithms aren't updated properly - it's much easier to
maintain if we have a single facility.
This patch refactors the old LTO API code to use the cache key
computation from the new LTO API. To do this, we set up an lto::Config
object and fill in the fields that the old LTO was hashing (the others
will just use the defaults).
There are two notable changes:
- I added a Freestanding flag to the LTO Config. Currently this is only
used by the legacy LTO API. In the patch that added it (D30791) I had
asked about adding it to the new LTO API, but it looks like that was not
addressed. This should probably be discussed as a follow up to this
change, as it is orthogonal.
- The legacy LTO API had some code that was hashing the GUID of all
preserved symbols defined in the module. I looked back at the history of
this (which was added with the original hashing in the legacy LTO API in
D18494), and there is a comment in the review thread that it was added
in preparation for future internalization. We now do the internalization
of course, and that is handled in the new LTO API cache key computation
by hashing the recorded linkage type of all defined globals. Therefore I
didn't try to move over and keep the preserved symbols handling.
Reviewers: steven_wu, pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, dang, llvm-commits
Differential Revision: https://reviews.llvm.org/D54635
llvm-svn: 347592
2018-11-26 21:40:37 +01:00
|
|
|
DefinedGVSummaries, OptLevel, Freestanding,
|
|
|
|
TMBuilder);
|
2016-12-14 05:56:42 +01:00
|
|
|
auto CacheEntryPath = CacheEntry.getEntryPath();
|
2016-04-21 07:54:23 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
|
2018-05-14 14:53:11 +02:00
|
|
|
LLVM_DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss")
|
|
|
|
<< " '" << CacheEntryPath << "' for buffer "
|
|
|
|
<< count << " " << ModuleIdentifier << "\n");
|
2016-04-24 05:18:01 +02:00
|
|
|
|
2016-04-21 07:54:23 +02:00
|
|
|
if (ErrOrBuffer) {
|
|
|
|
// Cache Hit!
|
2016-12-14 05:56:42 +01:00
|
|
|
if (SavedObjectsDirectoryPath.empty())
|
|
|
|
ProducedBinaries[count] = std::move(ErrOrBuffer.get());
|
|
|
|
else
|
|
|
|
ProducedBinaryFiles[count] = writeGeneratedObject(
|
[ThinLTO] Adding architecture name into saved object filename
Summary:
For ThinLTOCodegenerator, it has an option to save the object file
outputs into a directory which is essential for debug info. Tools like lldb
and dsymutil will look for these object files for debug info.
On Darwin platform, you can link fat binaries with one single clang
driver invocation like:
$ clang -arch x86_64 -arch i386 -Wl,-object_path_lto,$TMPDIR ...
Unfornately, the output object files for one architecture is going to
overwrite the previous ones and one architecture slice will end up with
no debug info. One example for this is to turn on ThinLTO for sanitizer
dylibs in compiler-rt project.
To fix the issue, add the name for the architecture into the name of the
output object file.
rdar://problem/35482935
Reviewers: tejohnson, bd1976llvm, dexonsmith, JDevlieghere
Reviewed By: dexonsmith
Subscribers: mehdi_amini, aprantl, inglorion, eraman, hiraditya, jkorous, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60924
llvm-svn: 359508
2019-04-29 23:39:54 +02:00
|
|
|
count, CacheEntryPath, *ErrOrBuffer.get());
|
2016-04-21 07:54:23 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMContext Context;
|
|
|
|
Context.setDiscardValueNames(LTODiscardValueNames);
|
|
|
|
Context.enableDebugTypeODRUniquing();
|
2019-10-28 22:53:31 +01:00
|
|
|
auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
|
2019-06-17 18:06:00 +02:00
|
|
|
Context, RemarksFilename, RemarksPasses, RemarksFormat,
|
2019-06-14 18:20:51 +02:00
|
|
|
RemarksWithHotness, count);
|
2016-11-19 19:20:05 +01:00
|
|
|
if (!DiagFileOrErr) {
|
|
|
|
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
|
|
|
|
report_fatal_error("ThinLTO: Can't get an output file for the "
|
|
|
|
"remarks");
|
|
|
|
}
|
2016-04-21 07:54:23 +02:00
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// Parse module now
|
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols
Summary:
Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool.
ThinLTOCodeGenerator currently does not preserve llvm.used symbols and
it can internalize them. In order to pass the necessary information to the
legacy ThinLTOCodeGenerator, the input to the code generator is
rewritten to be based on lto::InputFile.
Now ThinLTO using the legacy LTO API will requires data layout in
Module.
"internalize" thinlto action in llvm-lto is updated to run both
"promote" and "internalize" with the same configuration as
ThinLTOCodeGenerator. The old "promote" + "internalize" option does not
produce the same output as ThinLTOCodeGenerator.
This fixes: PR41236
rdar://problem/49293439
Reviewers: tejohnson, pcc, kromanova, dexonsmith
Reviewed By: tejohnson
Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60421
llvm-svn: 358601
2019-04-17 19:38:09 +02:00
|
|
|
auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
|
|
|
|
/*IsImporting*/ false);
|
2016-03-09 02:37:22 +01:00
|
|
|
|
|
|
|
// Save temps: original file.
|
2016-04-24 05:18:01 +02:00
|
|
|
saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
|
2016-03-09 02:37:22 +01:00
|
|
|
|
2016-04-16 09:02:16 +02:00
|
|
|
auto &ImportList = ImportLists[ModuleIdentifier];
|
2016-04-24 05:18:01 +02:00
|
|
|
// Run the main process now, and generates a binary
|
2016-04-21 07:54:23 +02:00
|
|
|
auto OutputBuffer = ProcessThinLTOModule(
|
2016-03-26 06:40:34 +01:00
|
|
|
*TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
|
2016-05-24 19:24:25 +02:00
|
|
|
ExportList, GUIDPreservedSymbols,
|
|
|
|
ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
|
2017-03-28 20:55:44 +02:00
|
|
|
DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count);
|
2016-04-21 07:54:23 +02:00
|
|
|
|
2016-12-14 05:56:42 +01:00
|
|
|
// Commit to the cache (if enabled)
|
|
|
|
CacheEntry.write(*OutputBuffer);
|
|
|
|
|
|
|
|
if (SavedObjectsDirectoryPath.empty()) {
|
|
|
|
// We need to generated a memory buffer for the linker.
|
|
|
|
if (!CacheEntryPath.empty()) {
|
2018-07-30 21:41:25 +02:00
|
|
|
// When cache is enabled, reload from the cache if possible.
|
2018-03-30 23:35:42 +02:00
|
|
|
// Releasing the buffer from the heap and reloading it from the
|
2018-07-30 21:41:25 +02:00
|
|
|
// cache file with mmap helps us to lower memory pressure.
|
|
|
|
// The freed memory can be used for the next input file.
|
2018-03-30 23:35:42 +02:00
|
|
|
// The final binary link will read from the VFS cache (hopefully!)
|
|
|
|
// or from disk (if the memory pressure was too high).
|
2016-12-14 05:56:42 +01:00
|
|
|
auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();
|
|
|
|
if (auto EC = ReloadedBufferOrErr.getError()) {
|
2018-03-30 23:35:42 +02:00
|
|
|
// On error, keep the preexisting buffer and print a diagnostic.
|
2020-06-20 00:58:51 +02:00
|
|
|
errs() << "remark: can't reload cached file '" << CacheEntryPath
|
2016-12-14 05:56:42 +01:00
|
|
|
<< "': " << EC.message() << "\n";
|
|
|
|
} else {
|
|
|
|
OutputBuffer = std::move(*ReloadedBufferOrErr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ProducedBinaries[count] = std::move(OutputBuffer);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ProducedBinaryFiles[count] = writeGeneratedObject(
|
[ThinLTO] Adding architecture name into saved object filename
Summary:
For ThinLTOCodegenerator, it has an option to save the object file
outputs into a directory which is essential for debug info. Tools like lldb
and dsymutil will look for these object files for debug info.
On Darwin platform, you can link fat binaries with one single clang
driver invocation like:
$ clang -arch x86_64 -arch i386 -Wl,-object_path_lto,$TMPDIR ...
Unfornately, the output object files for one architecture is going to
overwrite the previous ones and one architecture slice will end up with
no debug info. One example for this is to turn on ThinLTO for sanitizer
dylibs in compiler-rt project.
To fix the issue, add the name for the architecture into the name of the
output object file.
rdar://problem/35482935
Reviewers: tejohnson, bd1976llvm, dexonsmith, JDevlieghere
Reviewed By: dexonsmith
Subscribers: mehdi_amini, aprantl, inglorion, eraman, hiraditya, jkorous, dang, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60924
llvm-svn: 359508
2019-04-29 23:39:54 +02:00
|
|
|
count, CacheEntryPath, *OutputBuffer);
|
2016-05-16 21:33:07 +02:00
|
|
|
}, IndexCount);
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-15 23:54:18 +01:00
|
|
|
pruneCache(CacheOptions.Path, CacheOptions.Policy);
|
2016-04-21 07:54:23 +02:00
|
|
|
|
2016-03-09 02:37:22 +01:00
|
|
|
// If statistics were requested, print them out now.
|
|
|
|
if (llvm::AreStatisticsEnabled())
|
|
|
|
llvm::PrintStatistics();
|
2017-05-16 11:43:21 +02:00
|
|
|
reportAndResetTimings();
|
2016-03-09 02:37:22 +01:00
|
|
|
}
|