GH-111485: Break up instructions with unused cache entries into component micro-ops#113169
GH-111485: Break up instructions with unused cache entries into component micro-ops#113169markshannon merged 8 commits intopython:mainfrom
Conversation
| DISPATCH(); | ||
| } | ||
| """ | ||
| self.run_cases_test(input, output) |
There was a problem hiding this comment.
I'm not sure this test is covering everything that changed in this PR.
There was a problem hiding this comment.
Probably not, it is just a smoke test.
The real test is that everything continues to work properly.
There was a problem hiding this comment.
Actually, it would be nice if there was a test that adds a /* Skip N cache entries */ comment where it wasn't before this PR, so we could see regressions around that. (I don't care about the singular/plural, but I care about it appearing at all.)
| PyObject *self; | ||
| PyObject *callable; | ||
| /* Skip 1 cache entry */ | ||
| /* Skip 2 cache entries */ |
There was a problem hiding this comment.
Can it print only that second line?
There was a problem hiding this comment.
The source is inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused))
So it is skipping 1 entry, then skipping 2 entries.
We could combine them into /* Skip 3 cache entries */ but that would lose the structure, and I don't think it is worth the effort.
gvanrossum
left a comment
There was a problem hiding this comment.
LG except I am mystified by the logic for unused in desugar_inst().
| static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); | ||
| PyObject *seq; | ||
| PyObject **values; | ||
| /* Skip 1 cache entry */ |
There was a problem hiding this comment.
In summary, this PR doesn't change the generated cases except by adding some comments.
| DISPATCH(); | ||
| } | ||
| """ | ||
| self.run_cases_test(input, output) |
There was a problem hiding this comment.
Actually, it would be nice if there was a test that adds a /* Skip N cache entries */ comment where it wasn't before this PR, so we could see regressions around that. (I don't care about the singular/plural, but I care about it appearing at all.)
| op_inputs: list[parser.InputEffect] = [] | ||
| parts: list[Part] = [] | ||
| uop_index = -1 | ||
| for input in inst.inputs: | ||
| if isinstance(input, parser.CacheEffect) and input.name == "unused": | ||
| parts.append(Skip(input.size)) | ||
| else: | ||
| op_inputs.append(input) | ||
| if uop_index < 0: | ||
| uop_index = len(parts) | ||
| parts.append(Skip(0)) | ||
| uop = make_uop("_" + inst.name, inst, op_inputs) | ||
| uop.implicitly_created = True | ||
| uops[inst.name] = uop | ||
| add_instruction(name, [uop], instructions) | ||
| if uop_index < 0: | ||
| parts.append(uop) | ||
| else: | ||
| parts[uop_index] = uop | ||
| add_instruction(name, parts, instructions) |
There was a problem hiding this comment.
Something here feels so clever it needs a comment. and/or an assert We're adding a Skip(0) in L360 and overwriting that in L367. Could we ever add multiple Skip(0) entries? Then we'd be overwriting the first Skip(0) only. Probably my question makes no sense, and a comment would clarify that.
Separately, maybe Skip should have been named Unused? Or even UnusedCacheEffect? Because that's what it represents, right?
There was a problem hiding this comment.
We have to add Skip(0) due to type constraints. The natural thing to add would be None, but the then we need to add casts, or messy types.
Skip skips over caches entries, so I think the name is better than Unused. We could add Cache though.
A bit out of scope for this PR, though.
… component micro-ops (pythonGH-113169)
… component micro-ops (pythonGH-113169)
… component micro-ops (pythonGH-113169)
Break up
instinto more uops if they containunusedcache entries.Ideally, micro-ops should not have unused cache entries. This PR implements that for
instdeclarations.For example:
currently converts to:
With this PR it becomes: