[PATCH] D11453: [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.
Chandler Carruth
chandlerc at gmail.com
Sat Jul 25 00:14:56 PDT 2015
Ping.
While I CC'ed Hal on this directly because I know he's interested in AA
stuff, if anyone else has time to review, it would definitely be
appreciated.
On Thu, Jul 23, 2015 at 2:04 AM Chandler Carruth <chandlerc at gmail.com>
wrote:
> chandlerc created this revision.
> chandlerc added a reviewer: hfinkel.
> chandlerc added a subscriber: llvm-commits.
>
> 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.
>
> http://reviews.llvm.org/D11453
>
> Files:
> lib/Analysis/IPA/GlobalsModRef.cpp
>
> Index: lib/Analysis/IPA/GlobalsModRef.cpp
> ===================================================================
> --- lib/Analysis/IPA/GlobalsModRef.cpp
> +++ lib/Analysis/IPA/GlobalsModRef.cpp
> @@ -180,6 +180,13 @@
> 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,19 +222,26 @@
>
> 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(),
> E = GMR.AllocsForIndirectGlobals.end();
> I != E; ++I)
> if (I->second == GV)
> GMR.AllocsForIndirectGlobals.erase(I);
> }
> +
> + // Scan the function info we have collected and remove tihs
> global
> + // from all of them.
> + for (auto &FIPair : GMR.FunctionInfos)
> + FIPair.second.eraseModRefInfoForGlobal(*GV);
> }
> }
>
> @@ -361,11 +375,13 @@
> /// (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 @@
> 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.
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150725/113f70d3/attachment.html>
More information about the llvm-commits
mailing list