mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-15 16:09:02 +00:00
[GMR] Fix a long-standing bug in GlobalsModRef where it failed to clear
out the per-function modref data structures when functions were deleted or when globals were deleted. I don't actually know how the global deletion side of this bug hasn't been hit before, but for the other it just-so-happens that functions aren't likely to be deleted in the particular part of the LTO pipeline where we currently enable GMR, so we got lucky. With this patch, I can self-host with GMR enabled in the normal pass pipeline! I was a bit concerned about the compile-time impact of this chang, which is part of what motivated my prior string of patches to make the per-function datastructure very dense and fast to walk. With those changes in place, I can't measure a significant compile time difference (the difference is around 0.1% which is *way* below the noise) before and after this patch when building a linked bitcode for all of Clang. Differential Revision: http://reviews.llvm.org/D11453 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243385 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bd426c622e
commit
89576cea3f
@ -180,6 +180,13 @@ public:
|
||||
GlobalMRI = ModRefInfo(GlobalMRI | NewMRI);
|
||||
}
|
||||
|
||||
/// Clear a global's ModRef info. Should be used when a global is being
|
||||
/// deleted.
|
||||
void eraseModRefInfoForGlobal(const GlobalValue &GV) {
|
||||
if (AlignedMap *P = Info.getPointer())
|
||||
P->Map.erase(&GV);
|
||||
}
|
||||
|
||||
private:
|
||||
/// All of the information is encoded into a single pointer, with a three bit
|
||||
/// integer in the low three bits. The high bit provides a flag for when this
|
||||
@ -215,11 +222,13 @@ class GlobalsModRef : public ModulePass, public AliasAnalysis {
|
||||
|
||||
void deleted() override {
|
||||
Value *V = getValPtr();
|
||||
if (auto *F = dyn_cast<Function>(V))
|
||||
GMR.FunctionInfos.erase(F);
|
||||
|
||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
|
||||
if (GMR.NonAddressTakenGlobals.erase(GV)) {
|
||||
// This global might be an indirect global. If so, remove it and
|
||||
// remove
|
||||
// any AllocRelatedValues for it.
|
||||
// remove any AllocRelatedValues for it.
|
||||
if (GMR.IndirectGlobals.erase(GV)) {
|
||||
// Remove any entries in AllocsForIndirectGlobals for this global.
|
||||
for (auto I = GMR.AllocsForIndirectGlobals.begin(),
|
||||
@ -228,6 +237,11 @@ class GlobalsModRef : public ModulePass, public AliasAnalysis {
|
||||
if (I->second == GV)
|
||||
GMR.AllocsForIndirectGlobals.erase(I);
|
||||
}
|
||||
|
||||
// Scan the function info we have collected and remove this global
|
||||
// from all of them.
|
||||
for (auto &FIPair : GMR.FunctionInfos)
|
||||
FIPair.second.eraseModRefInfoForGlobal(*GV);
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,11 +375,13 @@ Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }
|
||||
/// (really, their address passed to something nontrivial), record this fact,
|
||||
/// and record the functions that they are used directly in.
|
||||
void GlobalsModRef::AnalyzeGlobals(Module &M) {
|
||||
SmallPtrSet<Function *, 64> TrackedFunctions;
|
||||
for (Function &F : M)
|
||||
if (F.hasLocalLinkage())
|
||||
if (!AnalyzeUsesOfPointer(&F)) {
|
||||
// Remember that we are tracking this global.
|
||||
NonAddressTakenGlobals.insert(&F);
|
||||
TrackedFunctions.insert(&F);
|
||||
Handles.emplace_front(*this, &F);
|
||||
Handles.front().I = Handles.begin();
|
||||
++NumNonAddrTakenFunctions;
|
||||
@ -381,12 +397,22 @@ void GlobalsModRef::AnalyzeGlobals(Module &M) {
|
||||
Handles.emplace_front(*this, &GV);
|
||||
Handles.front().I = Handles.begin();
|
||||
|
||||
for (Function *Reader : Readers)
|
||||
for (Function *Reader : Readers) {
|
||||
if (TrackedFunctions.insert(Reader).second) {
|
||||
Handles.emplace_front(*this, Reader);
|
||||
Handles.front().I = Handles.begin();
|
||||
}
|
||||
FunctionInfos[Reader].addModRefInfoForGlobal(GV, MRI_Ref);
|
||||
}
|
||||
|
||||
if (!GV.isConstant()) // No need to keep track of writers to constants
|
||||
for (Function *Writer : Writers)
|
||||
for (Function *Writer : Writers) {
|
||||
if (TrackedFunctions.insert(Writer).second) {
|
||||
Handles.emplace_front(*this, Writer);
|
||||
Handles.front().I = Handles.begin();
|
||||
}
|
||||
FunctionInfos[Writer].addModRefInfoForGlobal(GV, MRI_Mod);
|
||||
}
|
||||
++NumNonAddrTakenGlobalVars;
|
||||
|
||||
// If this global holds a pointer type, see if it is an indirect global.
|
||||
|
Loading…
Reference in New Issue
Block a user