diff --git a/llvm/include/llvm/CodeGen/LexicalScopes.h b/llvm/include/llvm/CodeGen/LexicalScopes.h --- a/llvm/include/llvm/CodeGen/LexicalScopes.h +++ b/llvm/include/llvm/CodeGen/LexicalScopes.h @@ -163,10 +163,19 @@ void getMachineBasicBlocks(const DILocation *DL, SmallPtrSetImpl &MBBs); - /// dominates - Return true if DebugLoc's lexical scope dominates at least one - /// machine instruction's lexical scope in a given machine basic block. + /// Return true if DebugLoc's lexical scope dominates at least one machine + /// instruction's lexical scope in a given machine basic block. bool dominates(const DILocation *DL, MachineBasicBlock *MBB); + /// An overload of \ref LexicalScopes::dominates that accepts a callback + /// which looks up the set of blocks that have instructions belonging to a + /// lexical scope identified by \p DL. + using GetMBBsCallback = + function_ref &( + const DILocation *)>; + bool dominates(const DILocation *DL, MachineBasicBlock *MBB, + GetMBBsCallback GetMBBsForDL); + /// findLexicalScope - Find lexical scope, either regular or inlined, for the /// given DebugLoc. Return NULL if not found. LexicalScope *findLexicalScope(const DILocation *DL); diff --git a/llvm/lib/CodeGen/LexicalScopes.cpp b/llvm/lib/CodeGen/LexicalScopes.cpp --- a/llvm/lib/CodeGen/LexicalScopes.cpp +++ b/llvm/lib/CodeGen/LexicalScopes.cpp @@ -302,9 +302,18 @@ MBBs.insert(&*CurMBBIt); } -/// dominates - Return true if DebugLoc's lexical scope dominates at least one -/// machine instruction's lexical scope in a given machine basic block. bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) { + SmallPtrSet Set; + auto GetMBBsForDL = [this, &Set](const DILocation *DL) + -> SmallPtrSetImpl & { + getMachineBasicBlocks(DL, Set); + return Set; + }; + return dominates(DL, MBB, GetMBBsForDL); +} + +bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB, + GetMBBsCallback GetMBBsForDL) { assert(MF && "Unexpected uninitialized LexicalScopes object!"); LexicalScope *Scope = getOrCreateLexicalScope(DL); if (!Scope) @@ -317,8 +326,7 @@ // Fetch all the blocks in DLs scope. Because the range / block list also // contain any subscopes, any instruction that DL dominates can be found // in the block set. - SmallPtrSet Set; - getMachineBasicBlocks(DL, Set); + SmallPtrSetImpl &Set = GetMBBsForDL(DL); return Set.count(MBB) != 0; } diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp --- a/llvm/lib/CodeGen/LiveDebugValues.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues.cpp @@ -189,13 +189,41 @@ } }; +/// A subclass of \ref LexicalScopes that caches information needed to speed up +/// calls to \ref LexicalScopes::dominates. +class CachingLexicalScopes final : public LexicalScopes { + using BlockSetT = SmallPtrSet; + DenseMap> Cache; + +public: + CachingLexicalScopes() : LexicalScopes() {} + + void initialize(const MachineFunction &MF) { + Cache.clear(); + LexicalScopes::initialize(MF); + } + + bool dominates(const DILocation *DL, MachineBasicBlock *MBB) { + auto GetMBBsForDL = [this](const DILocation *DL) + -> SmallPtrSetImpl & { + std::unique_ptr &BlockSet = Cache[DL]; + if (!BlockSet) { + BlockSet = std::make_unique(); + getMachineBasicBlocks(DL, *BlockSet); + } + return *BlockSet; + }; + return LexicalScopes::dominates(DL, MBB, GetMBBsForDL); + } +}; + class LiveDebugValues : public MachineFunctionPass { private: const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; const TargetFrameLowering *TFI; BitVector CalleeSavedRegs; - LexicalScopes LS; + CachingLexicalScopes LS; VarLocSet::Allocator Alloc; enum struct TransferKind { TransferCopy, TransferSpill, TransferRestore }; @@ -203,20 +231,16 @@ /// Keeps track of lexical scopes associated with a user value's source /// location. class UserValueScopes { - DebugLoc DL; - LexicalScopes &LS; - SmallPtrSet LBlocks; + const DebugLoc &DL; + CachingLexicalScopes &LS; public: - UserValueScopes(DebugLoc D, LexicalScopes &L) : DL(std::move(D)), LS(L) {} + UserValueScopes(const DebugLoc &D, CachingLexicalScopes &L) + : DL(D), LS(L) {} /// Return true if current scope dominates at least one machine /// instruction in a given machine basic block. - bool dominates(MachineBasicBlock *MBB) { - if (LBlocks.empty()) - LS.getMachineBasicBlocks(DL, LBlocks); - return LBlocks.count(MBB) != 0 || LS.dominates(DL, MBB); - } + bool dominates(MachineBasicBlock *MBB) { return LS.dominates(DL, MBB); } }; using FragmentInfo = DIExpression::FragmentInfo; @@ -269,7 +293,7 @@ const ConstantInt *CImm; } Loc; - VarLoc(const MachineInstr &MI, LexicalScopes &LS) + VarLoc(const MachineInstr &MI, CachingLexicalScopes &LS) : Var(MI.getDebugVariable(), MI.getDebugExpression(), MI.getDebugLoc()->getInlinedAt()), Expr(MI.getDebugExpression()), MI(MI), UVS(MI.getDebugLoc(), LS) { @@ -298,7 +322,8 @@ /// Take the variable and machine-location in DBG_VALUE MI, and build an /// entry location using the given expression. - static VarLoc CreateEntryLoc(const MachineInstr &MI, LexicalScopes &LS, + static VarLoc CreateEntryLoc(const MachineInstr &MI, + CachingLexicalScopes &LS, const DIExpression *EntryExpr, unsigned Reg) { VarLoc VL(MI, LS); assert(VL.Kind == RegisterKind); @@ -313,7 +338,7 @@ /// location will turn into the normal location if the backup is valid at /// the time of the primary location clobbering. static VarLoc CreateEntryBackupLoc(const MachineInstr &MI, - LexicalScopes &LS, + CachingLexicalScopes &LS, const DIExpression *EntryExpr) { VarLoc VL(MI, LS); assert(VL.Kind == RegisterKind); @@ -326,7 +351,7 @@ /// function entry), and build a copy of an entry value backup location by /// setting the register location to NewReg. static VarLoc CreateEntryCopyBackupLoc(const MachineInstr &MI, - LexicalScopes &LS, + CachingLexicalScopes &LS, const DIExpression *EntryExpr, unsigned NewReg) { VarLoc VL(MI, LS); @@ -339,8 +364,8 @@ /// Copy the register location in DBG_VALUE MI, updating the register to /// be NewReg. - static VarLoc CreateCopyLoc(const MachineInstr &MI, LexicalScopes &LS, - unsigned NewReg) { + static VarLoc CreateCopyLoc(const MachineInstr &MI, + CachingLexicalScopes &LS, unsigned NewReg) { VarLoc VL(MI, LS); assert(VL.Kind == RegisterKind); VL.Loc.RegNo = NewReg; @@ -350,7 +375,7 @@ /// Take the variable described by DBG_VALUE MI, and create a VarLoc /// locating it in the specified spill location. static VarLoc CreateSpillLoc(const MachineInstr &MI, unsigned SpillBase, - int SpillOffset, LexicalScopes &LS) { + int SpillOffset, CachingLexicalScopes &LS) { VarLoc VL(MI, LS); assert(VL.Kind == RegisterKind); VL.Kind = SpillLocKind;