Index: include/llvm/Analysis/Passes.h =================================================================== --- include/llvm/Analysis/Passes.h +++ include/llvm/Analysis/Passes.h @@ -24,6 +24,11 @@ class PassInfo; class LibCallInfo; + //===--------------------------------------------------------------------===// + // + // createStaticGlobalAAPass - This pass provides alias info for + // static global values that do not have their addresses taken. + // Pass *createStaticGlobalAAPass(); //===--------------------------------------------------------------------===// Index: lib/Analysis/IPA/StaticGlobalsAA.cpp =================================================================== --- lib/Analysis/IPA/StaticGlobalsAA.cpp +++ lib/Analysis/IPA/StaticGlobalsAA.cpp @@ -1,4 +1,4 @@ -//===- StaticGlobalAA.cpp - Simple Mod/Ref Analysis for Globals -----------===// +//===- StaticGlobalsAA.cpp - Simple Alias Analysis for Static Globals -----===// // // The LLVM Compiler Infrastructure // @@ -9,6 +9,7 @@ #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Constants.h" @@ -23,6 +24,27 @@ #define DEBUG_TYPE "staticglobal-aa" namespace { + + struct GlobalCaptureTracker : public CaptureTracker { + explicit GlobalCaptureTracker() : Captured(false) {} + + void tooManyUses() override { Captured = true; } + + bool shouldExplore(const Use *U) override { + if (isa(U->getUser())) + return true; + else + return false; + } + + bool captured(const Use *U) override { + Captured = true; + return true; + } + + bool Captured; + }; + class StaticGlobalAA : public ModulePass, public AliasAnalysis { SmallPtrSet NonAddressTakenGlobals; @@ -46,7 +68,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AliasAnalysis::getAnalysisUsage(AU); - AU.setPreservesAll(); // Does not transform code + AU.setPreservesAll(); } //------------------------------------------------ @@ -54,7 +76,6 @@ // AliasResult alias(const Location &LocA, const Location &LocB) override; void deleteValue(Value *V) override; - //void copyValue(Value *From, Value *To) override; void addEscapingUse(Use &U) override; /// getAdjustedAnalysisPointer - This method is used when a pass implements @@ -79,50 +100,17 @@ Pass *llvm::createStaticGlobalAAPass() { return new StaticGlobalAA(); } -static bool hasAddressTaken(Value *V) { - - if (!V->getType()->isPointerTy()) { - return false; - } - - // Iterate through the users of the value to see if they take the address - // somehow. - for (Use &U : V->uses()) { - User *VU = U.getUser(); - - if (isa(VU)) - continue; - // Using the address to store data, not storing the pointer itself. - else if (isa(VU)) { - if (VU->getOperand(0) != V) - continue; - } - // GEP and BitCast do not take the address, but could be nested within - // instructions that do. - else if (isa(VU) || isa(VU)) { - if (!hasAddressTaken(VU)) - continue; - } - DEBUG(dbgs() << "StaticGlobalAA: " << V->getName() - << " has its address taken\n"); - return true; - } - DEBUG(dbgs() << "StaticGlobalAA: " << V->getName() - << " does not have its address taken\n"); - return false; -} - /// AnalyzeGlobals - Scan through the users of all of the internal -/// GlobalValue's in the program. If none of them have their "address taken" -/// (really, their address passed to something nontrivial), record this fact, -/// and record the functions that they are used directly in. +/// GlobalValue's in the Module, recording the one's which do not have their +/// address taken. void StaticGlobalAA::AnalyzeGlobals(Module &M) { DEBUG(dbgs() << "StaticGlobalAA: Analyzing globals\n"); for (auto &GV : M.globals()) { - if (GV.hasLocalLinkage()) { - if (!isa(GV)) - if (!hasAddressTaken(&GV)) - NonAddressTakenGlobals.insert(&GV); + if (GV.hasLocalLinkage() && !isa(GV)) { + GlobalCaptureTracker Tracker; + PointerMayBeCaptured(&GV, &Tracker); + if (!Tracker.Captured) + NonAddressTakenGlobals.insert(&GV); } } } @@ -142,20 +130,13 @@ const GlobalValue *GV1 = dyn_cast(UV1); const GlobalValue *GV2 = dyn_cast(UV2); if (GV1 || GV2) { - // If the global's address is taken, pretend we don't know it's a pointer to - // the global. - if (GV1 && !NonAddressTakenGlobals.count(GV1)) GV1 = nullptr; - if (GV2 && !NonAddressTakenGlobals.count(GV2)) GV2 = nullptr; - // If the two pointers are derived from two different non-addr-taken // globals, or if one is and the other isn't, we know these can't alias. - if ((GV1 || GV2) && GV1 != GV2) { + if (NonAddressTakenGlobals.count(GV1) || + NonAddressTakenGlobals.count(GV2)) { DEBUG(dbgs() << "Found NoAlias with static global\n"); return NoAlias; } - - // Otherwise if they are both derived from the same addr-taken global, we - // can't know the two accesses don't overlap. } return AliasAnalysis::alias(LocA, LocB); } Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -272,8 +272,6 @@ // opportunities that creates). MPM.add(createBitTrackingDCEPass()); // Delete dead bit computations - //MPM.add(createStaticGlobalAAPass()); - // Run instcombine after redundancy elimination to exploit opportunities // opened up by them. MPM.add(createInstructionCombiningPass());