================
@@ -6771,6 +6771,240 @@ LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
 // code for that information.
 class MappableExprsHandler {
 public:
+  /// Custom comparator for attach-pointer expressions that compares them by
+  /// complexity (i.e. their component-depth) first, then by the order in which
+  /// they were computed by collectAttachPtrExprInfo(), if they are 
semantically
+  /// different.
+  struct AttachPtrExprComparator {
+    const MappableExprsHandler *Handler;
+    // Cache of previous equality comparison results.
+    mutable llvm::DenseMap<std::pair<const Expr *, const Expr *>, bool>
+        CachedEqualityComparisons;
+
+    AttachPtrExprComparator(const MappableExprsHandler *H) : Handler(H) {}
+
+    // Return true iff LHS is "less than" RHS.
+    bool operator()(const Expr *LHS, const Expr *RHS) const {
+      if (LHS == RHS)
+        return false;
+
+      // First, compare by complexity (depth)
+      auto ItLHS = Handler->AttachPtrComponentDepthMap.find(LHS);
+      auto ItRHS = Handler->AttachPtrComponentDepthMap.find(RHS);
+
+      std::optional<size_t> DepthLHS =
+          (ItLHS != Handler->AttachPtrComponentDepthMap.end()) ? ItLHS->second
+                                                               : std::nullopt;
+      std::optional<size_t> DepthRHS =
+          (ItRHS != Handler->AttachPtrComponentDepthMap.end()) ? ItRHS->second
+                                                               : std::nullopt;
+
+      // std::nullopt (no attach pointer) has lowest complexity
+      if (!DepthLHS.has_value() && !DepthRHS.has_value()) {
+        // Both have same complexity, now check semantic equality
+        if (areEqual(LHS, RHS))
+          return false;
+        // Different semantically, compare by computation order
+        return wasComputedBefore(LHS, RHS);
+      }
+      if (!DepthLHS.has_value())
+        return true; // LHS has lower complexity
+      if (!DepthRHS.has_value())
+        return false; // RHS has lower complexity
+
+      // Both have values, compare by depth (lower depth = lower complexity)
+      if (DepthLHS.value() != DepthRHS.value())
+        return DepthLHS.value() < DepthRHS.value();
+
+      // Same complexity, now check semantic equality
+      if (areEqual(LHS, RHS))
+        return false;
+      // Different semantically, compare by computation order
+      return wasComputedBefore(LHS, RHS);
+    }
+
+  public:
+    /// Return true if \p LHS and \p RHS are semantically equal. Uses 
pre-cached
+    /// results, if available, otherwise does a recursive semantic comparison.
+    bool areEqual(const Expr *LHS, const Expr *RHS) const {
+      // Check cache first for faster lookup
+      auto CachedResultIt = CachedEqualityComparisons.find({LHS, RHS});
+      if (CachedResultIt != CachedEqualityComparisons.end())
+        return CachedResultIt->second;
+
+      bool ComparisonResult = areSemanticallyEqual(LHS, RHS);
+
+      // Cache the result for future lookups (both orders since semantic
+      // equality is commutative)
+      CachedEqualityComparisons[{LHS, RHS}] = ComparisonResult;
+      CachedEqualityComparisons[{RHS, LHS}] = ComparisonResult;
+      return ComparisonResult;
+    }
+
+    /// Compare the two attach-ptr expressions by their computation order.
+    /// Returns true iff LHS was computed before RHS by
+    /// collectAttachPtrExprInfo().
+    bool wasComputedBefore(const Expr *LHS, const Expr *RHS) const {
+      const size_t &OrderLHS = Handler->AttachPtrComputationOrderMap.at(LHS);
+      const size_t &OrderRHS = Handler->AttachPtrComputationOrderMap.at(RHS);
+
+      return OrderLHS < OrderRHS;
+    }
+
+  private:
+    /// Helper function to compare attach-pointer expressions semantically.
+    /// This function handles various expression types that can be part of an
+    /// attach-pointer.
+    /// TODO: Not urgent, but we should ideally return true when comparing
+    /// `p[10]`, `*(p + 10)`,  `*(p + 5 + 5)`, `p[10:1]` etc.
+    bool areSemanticallyEqual(const Expr *LHS, const Expr *RHS) const {
----------------
kparzysz wrote:

This looks like a useful utility to have.  Maybe it could go in 
SemaExpr[CXX].cpp at some point in the future?

https://github.com/llvm/llvm-project/pull/155625
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to