@@ -192,12 +192,20 @@ bool LockOwnershipInfo::applyTransferFunc(const BasicBlock *BB,
192192 // Get a function state if it exists
193193 const auto FuncStateIt = FuncStates.find (CalledFunc);
194194 if (FuncStateIt != FuncStates.end ()) {
195- // Update the current state with callee's exit state
196- for (const auto &[Lock, State] : FuncStateIt->second .ExitState ) {
197- if (State.IsLocked )
198- handleLock (InState, I, Lock);
199- else
195+ // Use lock summaries to update the current state:
196+ // 1. Remove locks that the callee may unlock
197+ for (const Value *Lock : FuncStateIt->second .MayUnlock ) {
198+ const auto It = InState.find (Lock);
199+ if (It != InState.end ()) {
200+ LLVM_DEBUG (dbgs () << " Removing lock (MayUnlock): " << *Lock << " \n " );
200201 handleUnlock (InState, I, Lock);
202+ }
203+ }
204+
205+ // 2. Add locks that the callee must lock
206+ for (const Value *Lock : FuncStateIt->second .MustLock ) {
207+ LLVM_DEBUG (dbgs () << " Adding lock (MustLock): " << *Lock << " \n " );
208+ handleLock (InState, I, Lock);
201209 }
202210 }
203211 continue ;
@@ -291,6 +299,38 @@ void LockOwnershipInfo::buildSummary(const Function *F, bool InstrToLockFlag) {
291299 }
292300 }
293301
302+ // 5. Compute lock summaries for interprocedural analysis
303+ const LockStateTy &EntryState = InStates[&EntryBB];
304+ SmallPtrSet<const Value *, 4 > &MayUnlock = FuncStateIt->second .MayUnlock ;
305+ SmallPtrSet<const Value *, 4 > &MustLock = FuncStateIt->second .MustLock ;
306+
307+ MayUnlock.clear ();
308+ MustLock.clear ();
309+
310+ // MayUnlock: Locks that are locked at entry but either not locked or absent at exit
311+ for (const auto &[Lock, State] : EntryState) {
312+ if (State.IsLocked ) {
313+ const auto ExitIt = ExitState.find (Lock);
314+ // Lock is unlocked if it doesn't exist in exit state or exists but is not locked
315+ if (ExitIt == ExitState.end () || !ExitIt->second .IsLocked ) {
316+ MayUnlock.insert (Lock);
317+ LLVM_DEBUG (dbgs () << " MayUnlock: " << *Lock << " \n " );
318+ }
319+ }
320+ }
321+
322+ // MustLock: Locks that are locked at exit but were either not locked or absent at entry
323+ for (const auto &[Lock, State] : ExitState) {
324+ if (State.IsLocked ) {
325+ const auto EntryIt = EntryState.find (Lock);
326+ // Lock is newly acquired if it doesn't exist in entry state or exists but is not locked
327+ if (EntryIt == EntryState.end () || !EntryIt->second .IsLocked ) {
328+ MustLock.insert (Lock);
329+ LLVM_DEBUG (dbgs () << " MustLock: " << *Lock << " \n " );
330+ }
331+ }
332+ }
333+
294334 // Traverse CFG in reverse post-order
295335 // ReversePostOrderTraversal<const Function *> RPOT(&F);
296336 // for (const BasicBlock *BB : RPOT) {
0 commit comments