mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
Revert "[ThinLTO] Add correctness check for RO/WO variable import"
This reverts commit a2292cc537b561416c21e8d4017715d652c144cc. Breaks clang selfhost w/ThinLTO.
This commit is contained in:
parent
d1026cccc3
commit
5fe79eb481
@ -59,7 +59,7 @@ void thinLTOResolvePrevailingInIndex(
|
||||
/// must apply the changes to the Module via thinLTOInternalizeModule.
|
||||
void thinLTOInternalizeAndPromoteInIndex(
|
||||
ModuleSummaryIndex &Index,
|
||||
function_ref<bool(StringRef, ValueInfo)> isExported,
|
||||
function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
|
||||
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
|
||||
isPrevailing);
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
using ImportMapTy = StringMap<FunctionsToImportTy>;
|
||||
|
||||
/// The set contains an entry for every global value the module exports.
|
||||
using ExportSetTy = DenseSet<ValueInfo>;
|
||||
using ExportSetTy = std::unordered_set<GlobalValue::GUID>;
|
||||
|
||||
/// A function of this type is used to load modules referenced by the index.
|
||||
using ModuleLoaderTy =
|
||||
|
@ -251,7 +251,7 @@ void runWholeProgramDevirtOnIndex(
|
||||
/// devirt target names for any locals that were exported.
|
||||
void updateIndexWPDForExports(
|
||||
ModuleSummaryIndex &Summary,
|
||||
function_ref<bool(StringRef, ValueInfo)> isExported,
|
||||
function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
|
||||
std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap);
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -146,11 +146,9 @@ void llvm::computeLTOCacheKey(
|
||||
// Include the hash for the current module
|
||||
auto ModHash = Index.getModuleHash(ModuleID);
|
||||
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
|
||||
for (const auto &VI : ExportList) {
|
||||
auto GUID = VI.getGUID();
|
||||
for (auto F : ExportList)
|
||||
// The export list can impact the internalization, be conservative here
|
||||
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&GUID, sizeof(GUID)));
|
||||
}
|
||||
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&F, sizeof(F)));
|
||||
|
||||
// Include the hash for every module we import functions from. The set of
|
||||
// imported symbols for each module may affect code generation and is
|
||||
@ -385,12 +383,12 @@ static bool isWeakObjectWithRWAccess(GlobalValueSummary *GVS) {
|
||||
}
|
||||
|
||||
static void thinLTOInternalizeAndPromoteGUID(
|
||||
GlobalValueSummaryList &GVSummaryList, ValueInfo VI,
|
||||
function_ref<bool(StringRef, ValueInfo)> isExported,
|
||||
GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
|
||||
function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
|
||||
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
|
||||
isPrevailing) {
|
||||
for (auto &S : GVSummaryList) {
|
||||
if (isExported(S->modulePath(), VI)) {
|
||||
if (isExported(S->modulePath(), GUID)) {
|
||||
if (GlobalValue::isLocalLinkage(S->linkage()))
|
||||
S->setLinkage(GlobalValue::ExternalLinkage);
|
||||
} else if (EnableLTOInternalization &&
|
||||
@ -398,7 +396,7 @@ static void thinLTOInternalizeAndPromoteGUID(
|
||||
// doesn't resolve them.
|
||||
!GlobalValue::isLocalLinkage(S->linkage()) &&
|
||||
(!GlobalValue::isInterposableLinkage(S->linkage()) ||
|
||||
isPrevailing(VI.getGUID(), S.get())) &&
|
||||
isPrevailing(GUID, S.get())) &&
|
||||
S->linkage() != GlobalValue::AppendingLinkage &&
|
||||
// We can't internalize available_externally globals because this
|
||||
// can break function pointer equality.
|
||||
@ -417,12 +415,12 @@ static void thinLTOInternalizeAndPromoteGUID(
|
||||
// as external and non-exported values as internal.
|
||||
void llvm::thinLTOInternalizeAndPromoteInIndex(
|
||||
ModuleSummaryIndex &Index,
|
||||
function_ref<bool(StringRef, ValueInfo)> isExported,
|
||||
function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
|
||||
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
|
||||
isPrevailing) {
|
||||
for (auto &I : Index)
|
||||
thinLTOInternalizeAndPromoteGUID(
|
||||
I.second.SummaryList, Index.getValueInfo(I), isExported, isPrevailing);
|
||||
thinLTOInternalizeAndPromoteGUID(I.second.SummaryList, I.first, isExported,
|
||||
isPrevailing);
|
||||
}
|
||||
|
||||
// Requires a destructor for std::vector<InputModule>.
|
||||
@ -1332,10 +1330,11 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
|
||||
ExportedGUIDs.insert(
|
||||
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Def)));
|
||||
|
||||
auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
|
||||
auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
|
||||
const auto &ExportList = ExportLists.find(ModuleIdentifier);
|
||||
return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
|
||||
ExportedGUIDs.count(VI.getGUID());
|
||||
return (ExportList != ExportLists.end() &&
|
||||
ExportList->second.count(GUID)) ||
|
||||
ExportedGUIDs.count(GUID);
|
||||
};
|
||||
|
||||
// Update local devirtualized targets that were exported by cross-module
|
||||
|
@ -589,10 +589,11 @@ struct IsExported {
|
||||
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
|
||||
: ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
|
||||
|
||||
bool operator()(StringRef ModuleIdentifier, ValueInfo VI) const {
|
||||
bool operator()(StringRef ModuleIdentifier, GlobalValue::GUID GUID) const {
|
||||
const auto &ExportList = ExportLists.find(ModuleIdentifier);
|
||||
return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
|
||||
GUIDPreservedSymbols.count(VI.getGUID());
|
||||
return (ExportList != ExportLists.end() &&
|
||||
ExportList->second.count(GUID)) ||
|
||||
GUIDPreservedSymbols.count(GUID);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -308,7 +308,7 @@ static void computeImportForReferencedGlobals(
|
||||
|
||||
auto MarkExported = [&](const ValueInfo &VI, const GlobalValueSummary *S) {
|
||||
if (ExportLists)
|
||||
(*ExportLists)[S->modulePath()].insert(VI);
|
||||
(*ExportLists)[S->modulePath()].insert(VI.getGUID());
|
||||
};
|
||||
|
||||
for (auto &RefSummary : VI.getSummaryList())
|
||||
@ -497,7 +497,7 @@ static void computeImportForFunction(
|
||||
// Make exports in the source module.
|
||||
if (ExportLists) {
|
||||
auto &ExportList = (*ExportLists)[ExportModulePath];
|
||||
ExportList.insert(VI);
|
||||
ExportList.insert(VI.getGUID());
|
||||
if (!PreviouslyImported) {
|
||||
// This is the first time this function was exported from its source
|
||||
// module, so mark all functions and globals it references as exported
|
||||
@ -505,11 +505,14 @@ static void computeImportForFunction(
|
||||
// For efficiency, we unconditionally add all the referenced GUIDs
|
||||
// to the ExportList for this module, and will prune out any not
|
||||
// defined in the module later in a single pass.
|
||||
for (auto &Edge : ResolvedCalleeSummary->calls())
|
||||
ExportList.insert(Edge.first);
|
||||
|
||||
for (auto &Ref : ResolvedCalleeSummary->refs())
|
||||
ExportList.insert(Ref);
|
||||
for (auto &Edge : ResolvedCalleeSummary->calls()) {
|
||||
auto CalleeGUID = Edge.first.getGUID();
|
||||
ExportList.insert(CalleeGUID);
|
||||
}
|
||||
for (auto &Ref : ResolvedCalleeSummary->refs()) {
|
||||
auto GUID = Ref.getGUID();
|
||||
ExportList.insert(GUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -627,37 +630,6 @@ static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index,
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
checkVariableImport(const ModuleSummaryIndex &Index,
|
||||
StringMap<FunctionImporter::ImportMapTy> &ImportLists,
|
||||
StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
|
||||
|
||||
DenseSet<GlobalValue::GUID> FlattenedImports;
|
||||
|
||||
for (auto &ImportPerModule : ImportLists)
|
||||
for (auto &ExportPerModule : ImportPerModule.second)
|
||||
FlattenedImports.insert(ExportPerModule.second.begin(),
|
||||
ExportPerModule.second.end());
|
||||
|
||||
// Checks that all GUIDs of read/writeonly vars we see in export lists
|
||||
// are also in the import lists. Otherwise we my face linker undefs,
|
||||
// because readonly and writeonly vars are internalized in their
|
||||
// source modules.
|
||||
auto IsReadOrWriteOnlyVar = [&](StringRef ModulePath, const ValueInfo &VI) {
|
||||
auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
|
||||
Index.findSummaryInModule(VI, ModulePath));
|
||||
return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS));
|
||||
};
|
||||
|
||||
for (auto &ExportPerModule : ExportLists)
|
||||
for (auto &VI : ExportPerModule.second)
|
||||
if (!FlattenedImports.count(VI.getGUID()) &&
|
||||
IsReadOrWriteOnlyVar(ExportPerModule.first(), VI))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Compute all the import and export for every module using the Index.
|
||||
void llvm::ComputeCrossModuleImport(
|
||||
const ModuleSummaryIndex &Index,
|
||||
@ -682,13 +654,14 @@ void llvm::ComputeCrossModuleImport(
|
||||
for (auto &ELI : ExportLists) {
|
||||
const auto &DefinedGVSummaries =
|
||||
ModuleToDefinedGVSummaries.lookup(ELI.first());
|
||||
std::remove_if(ELI.second.begin(), ELI.second.end(),
|
||||
[&](const ValueInfo &VI) {
|
||||
return !DefinedGVSummaries.count(VI.getGUID());
|
||||
});
|
||||
for (auto EI = ELI.second.begin(); EI != ELI.second.end();) {
|
||||
if (!DefinedGVSummaries.count(*EI))
|
||||
EI = ELI.second.erase(EI);
|
||||
else
|
||||
++EI;
|
||||
}
|
||||
}
|
||||
|
||||
assert(checkVariableImport(Index, ImportLists, ExportLists));
|
||||
#ifndef NDEBUG
|
||||
LLVM_DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size()
|
||||
<< " modules:\n");
|
||||
|
@ -710,7 +710,7 @@ void runWholeProgramDevirtOnIndex(
|
||||
|
||||
void updateIndexWPDForExports(
|
||||
ModuleSummaryIndex &Summary,
|
||||
function_ref<bool(StringRef, ValueInfo)> isExported,
|
||||
function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
|
||||
std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap) {
|
||||
for (auto &T : LocalWPDTargetsMap) {
|
||||
auto &VI = T.first;
|
||||
@ -718,7 +718,7 @@ void updateIndexWPDForExports(
|
||||
assert(VI.getSummaryList().size() == 1 &&
|
||||
"Devirt of local target has more than one copy");
|
||||
auto &S = VI.getSummaryList()[0];
|
||||
if (!isExported(S->modulePath(), VI))
|
||||
if (!isExported(S->modulePath(), VI.getGUID()))
|
||||
continue;
|
||||
|
||||
// It's been exported by a cross module import.
|
||||
|
@ -250,12 +250,12 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
|
||||
// contains summaries from the source modules if they are being imported.
|
||||
// We might have a non-null VI and get here even in that case if the name
|
||||
// matches one in this module (e.g. weak or appending linkage).
|
||||
auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
|
||||
ImportIndex.findSummaryInModule(VI, M.getModuleIdentifier()));
|
||||
auto* GVS = dyn_cast_or_null<GlobalVarSummary>(
|
||||
ImportIndex.findSummaryInModule(VI, M.getModuleIdentifier()));
|
||||
if (GVS &&
|
||||
(ImportIndex.isReadOnly(GVS) || ImportIndex.isWriteOnly(GVS))) {
|
||||
V->addAttribute("thinlto-internalize");
|
||||
// Objects referenced by writeonly GV initializer should not be
|
||||
// Objects referenced by writeonly GV initializer should not be
|
||||
// promoted, because there is no any kind of read access to them
|
||||
// on behalf of this writeonly GV. To avoid promotion we convert
|
||||
// GV initializer to 'zeroinitializer'. This effectively drops
|
||||
|
Loading…
Reference in New Issue
Block a user