-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Key-type customization in CanonicalValueStore
and ClangDecl
cleanups
#5743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,17 +20,22 @@ class Decl; | |
namespace Carbon::SemIR { | ||
|
||
// A Clang declaration mapped to a Carbon instruction. | ||
// Using custom hashing since the declaration is keyed by the `decl` member for | ||
// lookup. | ||
// TODO: Avoid custom hashing by either having the data structure support keying | ||
// or create a dedicated mapping. See | ||
// https://discord.com/channels/655572317891461132/768530752592805919/1384999468293947537 | ||
// | ||
// Note that Clang's AST uses address-identity for nodes, which means the | ||
// pointer is the canonical way to represent a specific AST node and is expected | ||
// to be sufficient for comparison, hashing, etc. | ||
struct ClangDecl : public Printable<ClangDecl> { | ||
auto Print(llvm::raw_ostream& out) const -> void; | ||
|
||
friend auto CarbonHashtableEq(const ClangDecl& lhs, const ClangDecl& rhs) | ||
-> bool { | ||
return HashtableEq(lhs.decl, rhs.decl); | ||
// Equality comparison uses the address-identity property of the Clang AST and | ||
// just compares the `decl` pointers. We canonicalize on these to avoid ever | ||
// having different instructions for the same declaration. | ||
chandlerc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
auto operator==(const ClangDecl& rhs) const -> bool { | ||
return decl == rhs.decl; | ||
} | ||
// Support direct comparison with the Clang AST node pointer. | ||
auto operator==(const clang::Decl* rhs_decl) const -> bool { | ||
return decl == rhs_decl; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC the concern raised by @geoffromer correctly, we should make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to leave comments to explain why I don't think this is needed, also discussed some in the Discord... The instruction ID isn't part of the identity of a declaration, it is just associated data. It's value is completely determined by the declaration pointer. Comparing them both should be redundant. Is there an added comment that would make this more clear than the current ones? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
But this isn't an invariant of the type itself, it's an invariant of how the type is used. Relying so deeply on that invariant makes Ideally I'd prefer to decouple this type from that invariant, e.g. by teaching Failing that, I think we should more explicitly document the coupling with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
FWIW, I think that is true regardless of the inclusion of
The And what this PR does is extend that to also support teaching But all of that is in the context of this being coupled to the value store, not some independently useful type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I accepted your comment, but to your point this is really about the core of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm merging to unblock other work, but if you'd like any further changes to the comments here, happy to make them in follow-up PRs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment changes look good to me. My only hesitation is that as I understand it, the hash/equality customization will break if |
||
|
||
// Hashing for ClangDecl. See common/hashing.h. | ||
|
@@ -45,15 +50,28 @@ struct ClangDecl : public Printable<ClangDecl> { | |
clang::Decl* decl = nullptr; | ||
|
||
// The instruction the Clang declaration is mapped to. | ||
// | ||
// This is stored along side the `decl` pointer to avoid having to lookup both | ||
// the pointer and the instruction ID in two separate areas of storage. | ||
InstId inst_id; | ||
}; | ||
|
||
// The ID of a `ClangDecl`. | ||
// | ||
// These IDs are importantly distinct from the `inst_id` associated with each | ||
// declaration. These form a dense range of IDs that is used to reference the | ||
// AST node pointers without storing those pointers directly into SemIR and | ||
// needing space to hold a full pointer. We can't avoid having these IDs without | ||
// embedding pointers directly into the storage of SemIR as part of an | ||
// instruction. | ||
struct ClangDeclId : public IdBase<ClangDeclId> { | ||
static constexpr llvm::StringLiteral Label = "clang_decl_id"; | ||
|
||
using ValueType = ClangDecl; | ||
|
||
// Use the AST node pointer directly when doing `Lookup` to find an ID. | ||
using KeyType = clang::Decl*; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @jonmeow raised a concern that we should change the ID as it could be used in multiple value stores, but perhaps just defining the key type is less of an issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Happy to hear Jon's thoughts here -- the ID type already dictates the value type, and even the reference type, so it seemed reasonable to also dictate the key type... Not sure what the looser coupling would look like? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bricknerb You were putting value-specific functions here (inside the ID), I think this approach is different. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note in part, I expect |
||
|
||
using IdBase::IdBase; | ||
}; | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.