clang 24.0.0git
Utils.h
Go to the documentation of this file.
1//===- Utils.h - Utility Functions for Lifetime Safety --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7// This file provides utilities for the lifetime safety analysis, including
8// join operations for LLVM's immutable data structures.
9//
10//===----------------------------------------------------------------------===//
11#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_UTILS_H
12#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_UTILS_H
13
14#include "llvm/ADT/ImmutableMap.h"
15#include "llvm/ADT/ImmutableSet.h"
16
18
19/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
20/// Used for giving ID to loans and origins.
21template <typename Tag> struct ID {
23
24 bool operator==(const ID<Tag> &Other) const { return Value == Other.Value; }
25 bool operator!=(const ID<Tag> &Other) const { return !(*this == Other); }
26 bool operator<(const ID<Tag> &Other) const { return Value < Other.Value; }
28 ID<Tag> Tmp = *this;
29 ++Value;
30 return Tmp;
31 }
32 void Profile(llvm::FoldingSetNodeID &IDBuilder) const {
33 IDBuilder.AddInteger(Value);
34 }
35};
36
37/// The lifetime analyses do not benefit from canonicalizing their immutable
38/// collections, so they opt out of it via these aliases.
39template <typename T>
40using SetTy =
41 llvm::ImmutableSet<T, llvm::ImutContainerInfo<T>, /*Canonicalize=*/false>;
42
43template <typename KeyT, typename ValT>
44using MapTy = llvm::ImmutableMap<KeyT, ValT, llvm::ImutKeyValueInfo<KeyT, ValT>,
45 /*Canonicalize=*/false>;
46
47/// Computes the union of two ImmutableSets.
48template <typename T>
50 return F.unionSets(A, B);
51}
52
53/// Describes the strategy for joining two `ImmutableMap` instances, primarily
54/// differing in how they handle keys that are unique to one of the maps.
55///
56/// A `Symmetric` join is universally correct, while an `Asymmetric` join
57/// serves as a performance optimization. The latter is applicable only when the
58/// join operation possesses a left identity element, allowing for a more
59/// efficient, one-sided merge.
60enum class JoinKind {
61 /// A symmetric join applies the `JoinValues` operation to keys unique to
62 /// either map, ensuring that values from both maps contribute to the result.
64 /// An asymmetric join preserves keys unique to the first map as-is, while
65 /// applying the `JoinValues` operation only to keys unique to the second map.
67};
68
69/// Computes the key-wise union of two ImmutableMaps in a single traversal
70/// (see ImmutableMap::Factory::mergeWith), sharing subtrees the two maps do
71/// not overlap. This assumes -- as the swap below already does -- that
72/// JoinValues is commutative with a left identity, which holds for the
73/// lifetime lattices.
74template <typename KeyT, typename ValT, typename Joiner>
77 Joiner JoinValues, JoinKind Kind) {
78 if (A.getRootWithoutRetain() == B.getRootWithoutRetain())
79 return A;
80 // Drive the merge with the taller map so the shorter one is the one split.
81 if (A.getHeight() < B.getHeight())
82 std::swap(A, B);
83
84 using ValueTy = typename MapTy<KeyT, ValT>::value_type;
85 auto Combine = [&JoinValues](const ValueTy *AElem,
86 const ValueTy *BElem) -> std::pair<KeyT, ValT> {
87 const KeyT &Key = AElem ? AElem->first : BElem->first;
88 return std::pair<KeyT, ValT>(Key,
89 JoinValues(AElem ? &AElem->second : nullptr,
90 BElem ? &BElem->second : nullptr));
91 };
92 // Asymmetric keeps keys unique to either map as-is (valid because JoinValues
93 // has a left identity); symmetric passes unmatched keys through JoinValues.
94 // The lifetime joins are idempotent lattice joins, so pointer-identical
95 // subtrees (common once one state is derived from the other) can be shared.
96 return F.mergeWith(A, B, Combine,
97 /*KeepUnmatched=*/Kind == JoinKind::Asymmetric,
98 /*SkipShared=*/true);
99}
100} // namespace clang::lifetimes::internal::utils
101
102namespace llvm {
103template <typename Tag>
104struct DenseMapInfo<clang::lifetimes::internal::utils::ID<Tag>> {
106
107 static unsigned getHashValue(const ID &Val) {
108 return DenseMapInfo<uint32_t>::getHashValue(Val.Value);
109 }
110
111 static bool isEqual(const ID &LHS, const ID &RHS) { return LHS == RHS; }
112};
113} // namespace llvm
114
115#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_UTILS_H
llvm::ImmutableSet< T, llvm::ImutContainerInfo< T >, false > SetTy
The lifetime analyses do not benefit from canonicalizing their immutable collections,...
Definition Utils.h:40
llvm::ImmutableMap< KeyT, ValT, llvm::ImutKeyValueInfo< KeyT, ValT >, false > MapTy
Definition Utils.h:44
JoinKind
Describes the strategy for joining two ImmutableMap instances, primarily differing in how they handle...
Definition Utils.h:60
@ Asymmetric
An asymmetric join preserves keys unique to the first map as-is, while applying the JoinValues operat...
Definition Utils.h:66
@ Symmetric
A symmetric join applies the JoinValues operation to keys unique to either map, ensuring that values ...
Definition Utils.h:63
SetTy< T > join(SetTy< T > A, SetTy< T > B, typename SetTy< T >::Factory &F)
Computes the union of two ImmutableSets.
Definition Utils.h:49
The JSON file list parser is used to communicate input to InstallAPI.
@ Other
Other implicit parameter.
Definition Decl.h:1774
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
A generic, type-safe wrapper for an ID, distinguished by its Tag type.
Definition Utils.h:21
bool operator!=(const ID< Tag > &Other) const
Definition Utils.h:25
void Profile(llvm::FoldingSetNodeID &IDBuilder) const
Definition Utils.h:32
bool operator<(const ID< Tag > &Other) const
Definition Utils.h:26
bool operator==(const ID< Tag > &Other) const
Definition Utils.h:24
static bool isEqual(const ID &LHS, const ID &RHS)
Definition Utils.h:111
clang::lifetimes::internal::utils::ID< Tag > ID
Definition Utils.h:105