-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Include a fingerprint of the specific arguments in mangled names. #4771
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 |
---|---|---|
|
@@ -17,7 +17,7 @@ namespace Carbon::SemIR { | |
namespace { | ||
struct Worklist { | ||
// The file containing the instruction we're currently processing. | ||
const File* sem_ir; | ||
const File* sem_ir = nullptr; | ||
// The instructions we need to compute fingerprints for. | ||
llvm::SmallVector<std::pair<const File*, InstId>> todo; | ||
// The contents of the current instruction as accumulated so far. This is used | ||
|
@@ -28,6 +28,15 @@ struct Worklist { | |
// the cache if not already present. | ||
Map<std::pair<const File*, InstId>, uint64_t>* fingerprints; | ||
|
||
// Prepare to fingerprint a new instruction. | ||
auto Prepare(const File* file) -> void { | ||
sem_ir = file; | ||
contents.clear(); | ||
} | ||
|
||
// Finish fingerprinting and compute the fingerprint. | ||
auto Finish() -> uint64_t { return llvm::stable_hash_combine(contents); } | ||
|
||
// Add an invalid marker to the contents. This is used when the entity | ||
// contains an invalid ID. This uses an arbitrary fixed value that is assumed | ||
// to be unlikely to collide with a valid value. | ||
|
@@ -306,8 +315,7 @@ struct Worklist { | |
auto [arg0_kind, arg1_kind] = inst.ArgKinds(); | ||
|
||
// Prepare to fingerprint this instruction. | ||
sem_ir = next_sem_ir; | ||
contents.clear(); | ||
Prepare(next_sem_ir); | ||
|
||
// Add the instruction's fields to the contents. | ||
Add(inst.kind()); | ||
|
@@ -326,8 +334,7 @@ struct Worklist { | |
// pop it from the todo list. Otherwise, we leave it on the todo list so | ||
// we can compute its fingerprint once we've finished the work we added. | ||
if (todo.size() == init_size) { | ||
auto fingerprint = llvm::stable_hash_combine(contents); | ||
fingerprints->Insert(std::pair(next_sem_ir, next_inst_id), fingerprint); | ||
fingerprints->Insert(std::pair(next_sem_ir, next_inst_id), Finish()); | ||
todo.pop_back(); | ||
} | ||
} | ||
|
@@ -337,11 +344,25 @@ struct Worklist { | |
|
||
auto InstFingerprinter::GetOrCompute(const File* file, InstId inst_id) | ||
-> uint64_t { | ||
Worklist worklist = {.sem_ir = nullptr, | ||
.todo = {{file, inst_id}}, | ||
Worklist worklist = {.todo = {{file, inst_id}}, | ||
.fingerprints = &fingerprints_}; | ||
worklist.Run(); | ||
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. Sorta aside, but the new GetOrCompute avoids doing a second lookup, and it seems like Run() could also keep around the last fingerprint and return it, which would be the same as the lookup here and save us that? 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. Good point, done. (In this PR for convenience, let me know if you'd prefer that I split it out.) |
||
return fingerprints_.Lookup(std::pair(file, inst_id)).value(); | ||
} | ||
|
||
auto InstFingerprinter::GetOrCompute(const File* file, | ||
InstBlockId inst_block_id) -> uint64_t { | ||
Worklist worklist = {.todo = {}, .fingerprints = &fingerprints_}; | ||
worklist.Prepare(file); | ||
worklist.Add(inst_block_id); | ||
if (!worklist.todo.empty()) { | ||
worklist.Run(); | ||
worklist.Prepare(file); | ||
worklist.Add(inst_block_id); | ||
} | ||
Comment on lines
+366
to
+372
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 don't love how this is breaking the rather nice Worklist/Run abstraction. /me goes to stare at Worklist and see if this can be done internally I see, it's because Or a possibly heavier or different shaped hammer: 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. Yeah, I find this a little unsatisfying too. We can't construct a real I think switching to storing a variant in the todo list could be a bit heavyweight. On the other hand, if we see the same One other option I considered was storing an 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. Ok thanks. Yeah if we're concerned with performance here, having some kind of benchmark that we can look at would be great! I would be a little surprised if a variant of two ids is noticeably worse than one id, but we can't tell without measuring. 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. For the performance impact, it's mostly the extra levels in the Merkle tree that I'm concerned with, rather than the variant itself. I'd expect that it's a win to add separate levels for 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. Ah, I was not imagining that changing actually, I think. Maybe I will send a lil followup to this and you can see if you like what I am picturing or not. 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. #4776 is what I was thinking, see what you think. No hard feelings if it's not what you'd like. |
||
CARBON_CHECK(worklist.todo.empty(), | ||
"Should not require more than two passes."); | ||
return worklist.Finish(); | ||
} | ||
|
||
} // namespace Carbon::SemIR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great :) I was wondering inside if this would be a good idea on the last PR