mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:20:13 +01:00
Use the `CheckIRId` as a unique identifier for the scope of an `InstId` - if an `InstId` is created within the scope of one `CheckIRId` it must not be used in the scope of a different `CheckIRId`. This is achieved without extra storage, but with false negatives for large inputs. When an `InstId` is created, the original index of the `Inst` is XORed with a tag derived from the `CheckIRId` to produce the final `InstId`. When the `InstId` is used, the expected tag is XORed with the `InstId` to get back to the original index - if the tags don't match, the resulting index will be corrupted, likely too large - resulting in an out of bounds index CHECK-failure. (the tag value is derived as such: * take the CheckIRId * left shift one bit (padding zero) * left shift another bit (padding 1 - used to signify that the resulting `InstId` has a tag combined into it) * reverse the bits In this way, the tag is unlikely to overlap with the index for small test cases - making it possible to separate out the `CheckIRId` from the index in these cases to provide more meaningful debugging/CHECK messages, and more informative `SemIR` textual dumping that can now include the `CheckIRId` along with the `Inst`'s index in the name of an `inst`) The test churn here is improved printing as tagged `InstId`s can now, with best effort (more likely for small test cases where the `CheckIRId` and the `Inst` index aren't at risk of overlapping from the high and low bits), render the `CheckIRId` as part of the inst's name. Going from `instNN` to `irMM.instNN`. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>