| # Making Unified Intermediate Representation (UIR) Changes |
| |
| For general information on export data, see [here](../../README.md). |
| |
| UIR is the serial form of the compiler's intermediate representation, used to |
| propagate bodies of generic and/or inlined functions from one compilation unit |
| to another. |
| |
| The Go compiler has a single, canonical UIR writer implementation in |
| `src/cmd/compile/internal/noder/writer.go`. When we update the byte stream that |
| the UIR writer writes, *all* of the UIR readers need to be reviewed and |
| potentially updated; a change might not be backward compatible for them. These |
| instructions outline the steps required to keep all UIR readers up-to-date. |
| |
| ## The Writer |
| |
| The UIR version written by the compiler is controlled by |
| `src/cmd/compile/internal/noder/unified.go`. Do not change this yet. Instead: |
| |
| 1. Add a version flag N+1 for `MyChange` in `internal/pkgbits/version.go`. |
| 2. Update the UIR writer in `src/cmd/compile/internal/noder/writer.go` to guard |
| the writing of any fields added in N+1. Note: readers still on version N |
| *must* be oblivious to this change to avoid breaking the readers on |
| submission. |
| |
| ## The Readers |
| |
| Besides the compiler itself, there are other readers in go, x/tools, and |
| externally. Those in x/tools and the general public exist because |
| `go list -export` produces export data files in this format and we support the |
| ability of applications to decode it. |
| |
| > Note that there is an upcoming plan to decouple the compiler's IR from x/tools |
| > by changing the format encoded by `go list -export`; this would make UIR a |
| > private detail of the compiler, free to break at any time. For now, these |
| > instructions must still be followed. |
| |
| We assume that external readers will update on their own. The necessary reader |
| updates in go and x/tools are detailed below. |
| |
| ### go |
| |
| 3. Update the compiler's own UIR reader in |
| `src/cmd/compile/internal/noder/reader.go` to guard the reading of any fields |
| added in N+1. |
| 4. Repeat this change for the readers in `src/go/internal/gcimporter/ureader.go` |
| and `src/cmd/compile/internal/importer/ureader.go`. Note that these readers |
| only read data needed for type checking (in `src/go/types` and |
| `src/cmd/compile/internal/types2` respectively). For instance, they do not |
| read exported function bodies. Thus, it's possible that a change to UIR (such |
| as the encoding of function bodies) would require no change to these readers. |
| |
| ### x/tools |
| |
| 5. Add a version flag for `MyChange` in `internal/pkgbits/version.go`. Note: |
| x/tools has its own pkgbits implementation, which is intended to be an exact |
| copy of the [one in go](#the-writer). Any change made to one must be |
| reflected in the other. |
| 6. Update the x/tools UIR reader in `internal/gcimporter/ureader.go` to guard |
| the reading of any fields added in N+1. Call this commit C. |
| 7. In go, take the commit hash for C and update `src/cmd/go.mod` to use x/tools@C |
| per the [vendoring instructions](https://go.dev/wiki/MinorReleases#cherry-pick-cls-for-vendored-golangorgx-packages). |
| |
| ## Finalizing |
| |
| > If this UIR change will be tested, check the [following section](#testing) and |
| > consider when it makes to finalize. |
| |
| Only after reviewing *all* of the readers, bump the UIR version written by the |
| writer to N+1 in `src/cmd/compile/internal/noder/unified.go`. Because the |
| readers have already been updated to handle version N+1, this change is |
| compatible. |
| |
| ## Testing |
| |
| If making changes related to some new feature requiring extensive testing, it's |
| best to postpone bumping the UIR version until *all* of the tests are in. To |
| commit tests incrementally, develop them with a locally-incremented UIR version |
| and commit *skipped* tests; don't yet bump the remote UIR version. |
| |
| Once all of the required tests are in, bump the remote UIR version while turning |
| on all of the previously skipped tests. This minimizes churn on the UIR version |
| as testing uncovers any discrepancies. |