1
0
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:
Benjamin Kramer 2019-11-14 16:07:13 +01:00
parent d1026cccc3
commit 5fe79eb481
8 changed files with 41 additions and 68 deletions

View File

@ -59,7 +59,7 @@ void thinLTOResolvePrevailingInIndex(
/// must apply the changes to the Module via thinLTOInternalizeModule. /// must apply the changes to the Module via thinLTOInternalizeModule.
void thinLTOInternalizeAndPromoteInIndex( void thinLTOInternalizeAndPromoteInIndex(
ModuleSummaryIndex &Index, ModuleSummaryIndex &Index,
function_ref<bool(StringRef, ValueInfo)> isExported, function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
isPrevailing); isPrevailing);

View File

@ -98,7 +98,7 @@ public:
using ImportMapTy = StringMap<FunctionsToImportTy>; using ImportMapTy = StringMap<FunctionsToImportTy>;
/// The set contains an entry for every global value the module exports. /// 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. /// A function of this type is used to load modules referenced by the index.
using ModuleLoaderTy = using ModuleLoaderTy =

View File

@ -251,7 +251,7 @@ void runWholeProgramDevirtOnIndex(
/// devirt target names for any locals that were exported. /// devirt target names for any locals that were exported.
void updateIndexWPDForExports( void updateIndexWPDForExports(
ModuleSummaryIndex &Summary, ModuleSummaryIndex &Summary,
function_ref<bool(StringRef, ValueInfo)> isExported, function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap); std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap);
} // end namespace llvm } // end namespace llvm

View File

@ -146,11 +146,9 @@ void llvm::computeLTOCacheKey(
// Include the hash for the current module // Include the hash for the current module
auto ModHash = Index.getModuleHash(ModuleID); auto ModHash = Index.getModuleHash(ModuleID);
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash))); Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
for (const auto &VI : ExportList) { for (auto F : ExportList)
auto GUID = VI.getGUID();
// The export list can impact the internalization, be conservative here // 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 // Include the hash for every module we import functions from. The set of
// imported symbols for each module may affect code generation and is // imported symbols for each module may affect code generation and is
@ -385,12 +383,12 @@ static bool isWeakObjectWithRWAccess(GlobalValueSummary *GVS) {
} }
static void thinLTOInternalizeAndPromoteGUID( static void thinLTOInternalizeAndPromoteGUID(
GlobalValueSummaryList &GVSummaryList, ValueInfo VI, GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
function_ref<bool(StringRef, ValueInfo)> isExported, function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
isPrevailing) { isPrevailing) {
for (auto &S : GVSummaryList) { for (auto &S : GVSummaryList) {
if (isExported(S->modulePath(), VI)) { if (isExported(S->modulePath(), GUID)) {
if (GlobalValue::isLocalLinkage(S->linkage())) if (GlobalValue::isLocalLinkage(S->linkage()))
S->setLinkage(GlobalValue::ExternalLinkage); S->setLinkage(GlobalValue::ExternalLinkage);
} else if (EnableLTOInternalization && } else if (EnableLTOInternalization &&
@ -398,7 +396,7 @@ static void thinLTOInternalizeAndPromoteGUID(
// doesn't resolve them. // doesn't resolve them.
!GlobalValue::isLocalLinkage(S->linkage()) && !GlobalValue::isLocalLinkage(S->linkage()) &&
(!GlobalValue::isInterposableLinkage(S->linkage()) || (!GlobalValue::isInterposableLinkage(S->linkage()) ||
isPrevailing(VI.getGUID(), S.get())) && isPrevailing(GUID, S.get())) &&
S->linkage() != GlobalValue::AppendingLinkage && S->linkage() != GlobalValue::AppendingLinkage &&
// We can't internalize available_externally globals because this // We can't internalize available_externally globals because this
// can break function pointer equality. // can break function pointer equality.
@ -417,12 +415,12 @@ static void thinLTOInternalizeAndPromoteGUID(
// as external and non-exported values as internal. // as external and non-exported values as internal.
void llvm::thinLTOInternalizeAndPromoteInIndex( void llvm::thinLTOInternalizeAndPromoteInIndex(
ModuleSummaryIndex &Index, ModuleSummaryIndex &Index,
function_ref<bool(StringRef, ValueInfo)> isExported, function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
isPrevailing) { isPrevailing) {
for (auto &I : Index) for (auto &I : Index)
thinLTOInternalizeAndPromoteGUID( thinLTOInternalizeAndPromoteGUID(I.second.SummaryList, I.first, isExported,
I.second.SummaryList, Index.getValueInfo(I), isExported, isPrevailing); isPrevailing);
} }
// Requires a destructor for std::vector<InputModule>. // Requires a destructor for std::vector<InputModule>.
@ -1332,10 +1330,11 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
ExportedGUIDs.insert( ExportedGUIDs.insert(
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Def))); GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Def)));
auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) { auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
const auto &ExportList = ExportLists.find(ModuleIdentifier); const auto &ExportList = ExportLists.find(ModuleIdentifier);
return (ExportList != ExportLists.end() && ExportList->second.count(VI)) || return (ExportList != ExportLists.end() &&
ExportedGUIDs.count(VI.getGUID()); ExportList->second.count(GUID)) ||
ExportedGUIDs.count(GUID);
}; };
// Update local devirtualized targets that were exported by cross-module // Update local devirtualized targets that were exported by cross-module

View File

@ -589,10 +589,11 @@ struct IsExported {
const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
: ExportLists(ExportLists), GUIDPreservedSymbols(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); const auto &ExportList = ExportLists.find(ModuleIdentifier);
return (ExportList != ExportLists.end() && ExportList->second.count(VI)) || return (ExportList != ExportLists.end() &&
GUIDPreservedSymbols.count(VI.getGUID()); ExportList->second.count(GUID)) ||
GUIDPreservedSymbols.count(GUID);
} }
}; };

View File

@ -308,7 +308,7 @@ static void computeImportForReferencedGlobals(
auto MarkExported = [&](const ValueInfo &VI, const GlobalValueSummary *S) { auto MarkExported = [&](const ValueInfo &VI, const GlobalValueSummary *S) {
if (ExportLists) if (ExportLists)
(*ExportLists)[S->modulePath()].insert(VI); (*ExportLists)[S->modulePath()].insert(VI.getGUID());
}; };
for (auto &RefSummary : VI.getSummaryList()) for (auto &RefSummary : VI.getSummaryList())
@ -497,7 +497,7 @@ static void computeImportForFunction(
// Make exports in the source module. // Make exports in the source module.
if (ExportLists) { if (ExportLists) {
auto &ExportList = (*ExportLists)[ExportModulePath]; auto &ExportList = (*ExportLists)[ExportModulePath];
ExportList.insert(VI); ExportList.insert(VI.getGUID());
if (!PreviouslyImported) { if (!PreviouslyImported) {
// This is the first time this function was exported from its source // This is the first time this function was exported from its source
// module, so mark all functions and globals it references as exported // 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 // For efficiency, we unconditionally add all the referenced GUIDs
// to the ExportList for this module, and will prune out any not // to the ExportList for this module, and will prune out any not
// defined in the module later in a single pass. // defined in the module later in a single pass.
for (auto &Edge : ResolvedCalleeSummary->calls()) for (auto &Edge : ResolvedCalleeSummary->calls()) {
ExportList.insert(Edge.first); auto CalleeGUID = Edge.first.getGUID();
ExportList.insert(CalleeGUID);
for (auto &Ref : ResolvedCalleeSummary->refs()) }
ExportList.insert(Ref); for (auto &Ref : ResolvedCalleeSummary->refs()) {
auto GUID = Ref.getGUID();
ExportList.insert(GUID);
}
} }
} }
} }
@ -627,37 +630,6 @@ static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index,
} }
#endif #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. /// Compute all the import and export for every module using the Index.
void llvm::ComputeCrossModuleImport( void llvm::ComputeCrossModuleImport(
const ModuleSummaryIndex &Index, const ModuleSummaryIndex &Index,
@ -682,13 +654,14 @@ void llvm::ComputeCrossModuleImport(
for (auto &ELI : ExportLists) { for (auto &ELI : ExportLists) {
const auto &DefinedGVSummaries = const auto &DefinedGVSummaries =
ModuleToDefinedGVSummaries.lookup(ELI.first()); ModuleToDefinedGVSummaries.lookup(ELI.first());
std::remove_if(ELI.second.begin(), ELI.second.end(), for (auto EI = ELI.second.begin(); EI != ELI.second.end();) {
[&](const ValueInfo &VI) { if (!DefinedGVSummaries.count(*EI))
return !DefinedGVSummaries.count(VI.getGUID()); EI = ELI.second.erase(EI);
}); else
++EI;
}
} }
assert(checkVariableImport(Index, ImportLists, ExportLists));
#ifndef NDEBUG #ifndef NDEBUG
LLVM_DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size() LLVM_DEBUG(dbgs() << "Import/Export lists for " << ImportLists.size()
<< " modules:\n"); << " modules:\n");

View File

@ -710,7 +710,7 @@ void runWholeProgramDevirtOnIndex(
void updateIndexWPDForExports( void updateIndexWPDForExports(
ModuleSummaryIndex &Summary, ModuleSummaryIndex &Summary,
function_ref<bool(StringRef, ValueInfo)> isExported, function_ref<bool(StringRef, GlobalValue::GUID)> isExported,
std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap) { std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap) {
for (auto &T : LocalWPDTargetsMap) { for (auto &T : LocalWPDTargetsMap) {
auto &VI = T.first; auto &VI = T.first;
@ -718,7 +718,7 @@ void updateIndexWPDForExports(
assert(VI.getSummaryList().size() == 1 && assert(VI.getSummaryList().size() == 1 &&
"Devirt of local target has more than one copy"); "Devirt of local target has more than one copy");
auto &S = VI.getSummaryList()[0]; auto &S = VI.getSummaryList()[0];
if (!isExported(S->modulePath(), VI)) if (!isExported(S->modulePath(), VI.getGUID()))
continue; continue;
// It's been exported by a cross module import. // It's been exported by a cross module import.

View File

@ -250,12 +250,12 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
// contains summaries from the source modules if they are being imported. // 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 // 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). // matches one in this module (e.g. weak or appending linkage).
auto *GVS = dyn_cast_or_null<GlobalVarSummary>( auto* GVS = dyn_cast_or_null<GlobalVarSummary>(
ImportIndex.findSummaryInModule(VI, M.getModuleIdentifier())); ImportIndex.findSummaryInModule(VI, M.getModuleIdentifier()));
if (GVS && if (GVS &&
(ImportIndex.isReadOnly(GVS) || ImportIndex.isWriteOnly(GVS))) { (ImportIndex.isReadOnly(GVS) || ImportIndex.isWriteOnly(GVS))) {
V->addAttribute("thinlto-internalize"); 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 // promoted, because there is no any kind of read access to them
// on behalf of this writeonly GV. To avoid promotion we convert // on behalf of this writeonly GV. To avoid promotion we convert
// GV initializer to 'zeroinitializer'. This effectively drops // GV initializer to 'zeroinitializer'. This effectively drops