From d483a8abe0194a50043a50982dd312472121e2fa Mon Sep 17 00:00:00 2001 From: Egor Zhdan Date: Thu, 20 Feb 2025 17:30:02 +0000 Subject: [PATCH] [cxx-interop] Workaround a template instantiation issue `class GVNPass` has a private member `ValueTable VN`, where `ValueTable` uses a forward-declared type `Expression`, which is declared in a .cpp file. This is currently causing issues since Swift started importing private fields of C++ types. rdar://145070564 --- llvm/include/llvm/Transforms/Scalar/GVN.h | 34 +++++++++++++++++++++++ llvm/lib/Transforms/Scalar/GVN.cpp | 34 ----------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/llvm/include/llvm/Transforms/Scalar/GVN.h b/llvm/include/llvm/Transforms/Scalar/GVN.h index c8be390799836..971ebe6bfa190 100644 --- a/llvm/include/llvm/Transforms/Scalar/GVN.h +++ b/llvm/include/llvm/Transforms/Scalar/GVN.h @@ -410,4 +410,38 @@ struct GVNSinkPass : PassInfoMixin { } // end namespace llvm +struct llvm::GVNPass::Expression { + uint32_t opcode; + bool commutative = false; + // The type is not necessarily the result type of the expression, it may be + // any additional type needed to disambiguate the expression. + Type *type = nullptr; + SmallVector varargs; + + AttributeList attrs; + + Expression(uint32_t o = ~2U) : opcode(o) {} + + bool operator==(const Expression &other) const { + if (opcode != other.opcode) + return false; + if (opcode == ~0U || opcode == ~1U) + return true; + if (type != other.type) + return false; + if (varargs != other.varargs) + return false; + if ((!attrs.isEmpty() || !other.attrs.isEmpty()) && + !attrs.intersectWith(type->getContext(), other.attrs).has_value()) + return false; + return true; + } + + friend hash_code hash_value(const Expression &Value) { + return hash_combine( + Value.opcode, Value.type, + hash_combine_range(Value.varargs.begin(), Value.varargs.end())); + } +}; + #endif // LLVM_TRANSFORMS_SCALAR_GVN_H diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 3f306bb52c12a..6dc8fee5bf3c3 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -137,40 +137,6 @@ static cl::opt MaxNumInsnsPerBlock( cl::desc("Max number of instructions to scan in each basic block in GVN " "(default = 100)")); -struct llvm::GVNPass::Expression { - uint32_t opcode; - bool commutative = false; - // The type is not necessarily the result type of the expression, it may be - // any additional type needed to disambiguate the expression. - Type *type = nullptr; - SmallVector varargs; - - AttributeList attrs; - - Expression(uint32_t o = ~2U) : opcode(o) {} - - bool operator==(const Expression &other) const { - if (opcode != other.opcode) - return false; - if (opcode == ~0U || opcode == ~1U) - return true; - if (type != other.type) - return false; - if (varargs != other.varargs) - return false; - if ((!attrs.isEmpty() || !other.attrs.isEmpty()) && - !attrs.intersectWith(type->getContext(), other.attrs).has_value()) - return false; - return true; - } - - friend hash_code hash_value(const Expression &Value) { - return hash_combine( - Value.opcode, Value.type, - hash_combine_range(Value.varargs.begin(), Value.varargs.end())); - } -}; - namespace llvm { template <> struct DenseMapInfo {