{"id":20707325,"url":"https://github.com/code-help-tutor/ct-coursework-3-code-generation","last_synced_at":"2025-03-11T05:20:11.006Z","repository":{"id":234136501,"uuid":"785022160","full_name":"code-help-tutor/CT-Coursework-3-Code-Generation","owner":"code-help-tutor","description":"CT 代写代做 编程辅导, code help, CS tutor, WeChat: cstutorcs Email: tutorcs@163.com","archived":false,"fork":false,"pushed_at":"2024-04-11T03:05:21.000Z","size":145,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-17T20:31:36.426Z","etag":null,"topics":["ct"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/code-help-tutor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-11T03:05:15.000Z","updated_at":"2024-04-11T03:05:25.000Z","dependencies_parsed_at":"2024-04-18T09:30:03.914Z","dependency_job_id":null,"html_url":"https://github.com/code-help-tutor/CT-Coursework-3-Code-Generation","commit_stats":null,"previous_names":["code-help-tutor/ct-coursework-3-code-generation"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-help-tutor%2FCT-Coursework-3-Code-Generation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-help-tutor%2FCT-Coursework-3-Code-Generation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-help-tutor%2FCT-Coursework-3-Code-Generation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-help-tutor%2FCT-Coursework-3-Code-Generation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/code-help-tutor","download_url":"https://codeload.github.com/code-help-tutor/CT-Coursework-3-Code-Generation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242974988,"owners_count":20215397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ct"],"created_at":"2024-11-17T01:25:44.075Z","updated_at":"2025-03-11T05:20:10.971Z","avatar_url":"https://github.com/code-help-tutor.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![BuildAndTest](../../workflows/BuildAndTest/badge.svg?branch=main) ![Points badge](../../blob/badges/.github/badges/points.svg)\r\n\r\n# CT 2022/23 | Coursework 3 - Code Generation\r\n\r\n**Deadline:** Fri, 31.03.2023 (Week 11), 22:00  \r\n## Provided\r\n\r\nThis coursework already provides:\r\n\r\n- I) Lowering from the choco AST (`choco.ast`) to a flat version of the choco AST (`choco.ir`).\r\n- II) A skeleton for lowering the `choco.ir` to an SSA RISCV-V dialect (`riscv_ssa`).\r\n- III) Lowering from `riscv_ssa` to a dialect for RISC-V assembly (`riscv`).\r\n- IV) A printer for the `riscv` dialect which emits assembly files.\r\n\r\n\r\n## Tasks\r\n1. Core: Code generation\r\n2. Expert: Optimization\r\n\r\n\r\n## Quick Install (for DICE-like environments)\r\n\r\n### Download This Coursework\r\n\r\nFirst, you will need to **clone** the repository. If you used GitHub before, you will already have either an HTTPS access token, or an SSH key. If you do not have either, you will need to create this. You can use either, just follow the guides below:\r\n  - To create an SSH key, use [this](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)\r\n  - To create an HTTPS token, use [this](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)\r\n    At some point, you will be asked to specify what you want to do with the token: feel free to tick all the boxes.\r\n\r\n  At this point, you can clone the repository:\r\n  - if you used HTTPS above, use the command\r\n    ```\r\n    git clone https://github.com/compiling-techniques/REPOSITORY_NAME.git\r\n    ```\r\n  - if you used SSH, use the command\r\n    ```\r\n    git clone git@github.com:compiling-techniques/REPOSITORY_NAME.git\r\n    ```\r\nNow enter the repository directory: `cd REPOSITORY_NAME`. If this is your first time using Git, you will need to set up a bit of configuration:\r\n  ```\r\n  git config --global user.name \"your_github_username\"\r\n  git config --global user.email \"your_github_email\"\r\n  ```\r\n  This will set your username and email globally (for all repositories, unless they overwrite this), so all future GitHub repositories will already have this set up. If you do not wish to do that, just omit the `--global`.\r\n  You can verify the setup using `git config -l`, which will just tell you what settings you set.\r\n\r\n### Installation\r\n\r\nYou can create an isolated python environment using [venv](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment).\r\nTo set up `venv` for the assignment, follow the steps below (a summary is given below the bulleted list):\r\n\r\n1. Set up a virtual environment for the assignment with `python3 -m venv env`.\r\n   This creates a subdirectory called `env` in the current folder that creates an isolated version of Python.\r\n2. Activate the virtual environment by [`source`ing](https://linuxcommand.org/lc3_man_pages/sourceh.html) the activation file: `source env/bin/activate`\r\n3. Confirm that you are in the virtual environment by running `which python`. The output should be `/path/to/coursework/env/bin/python`.\r\n4. Run `pip install -U -r requirements.txt` to install dependencies within the virtual environment.\r\n5. Run `pip install -e .` to install the ChocoPy compiler as a package.\r\n6. If you are using PyCharm, please configure PyCharm to work with the environment by following the instructions on\r\n   this page of the PyCharm manual: [Configure a virtual environment](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html).\r\n\r\nIn summary, the process looks as follows:\r\n\r\n```bash\r\n/path/to/coursework$ /afs/inf.ed.ac.uk/group/teaching/ct/python/3.10/bin/python3.10 -m venv env # set up virtual environment called `env`\r\n\r\n/path/to/coursework$ source env/bin/activate # run activation file\r\n\r\n(env) /path/to/coursework$ # (env) shows up\r\n\r\n(env) /path/to/coursework$ which python # confirm python path\r\n/path/to/coursework/env/bin/python\r\n\r\n(env) /path/to/coursework$ pip install -U -r requirements.txt # install dependencies\r\n\r\n(env) /path/to/coursework$ pip install -e . # install ChocoPy as a package\r\n\r\n(env) /path/to/coursework$ # get to hacking, and best of luck! :)\r\n```\r\n\r\n#### PyCharm\r\n\r\nIt would be convenient for you, if you used a modern IDE for Python.\r\nA popular choice, `PyCharm`, comes pre-installed in your DICE desktop environment.\r\n\r\nIf you decide to use `PyCharm`, in order to install the packages, you should open the embedded terminal (`Alt+F12` by default)\r\nand follow the previous instructions using `pip install -U -r requirements.txt`.\r\n\r\n#### Using GitHub code spaces\r\n\r\nInstead of cloning the repository to your local machine, you can also use GitHub codespaces to do your coursework. This is a beta-test, so it is an optional offer that is delivered on a best-effort basis. TO use GitHub codespaces click on the green \"Code\" button at the top of this repository, select \"code spaces\" and create your personal codespace. Then enter the console and run:\r\n\r\n```bash\r\n$ export PATH=/home/codespace/.local/lib/python3.10/site-packages/bin/:$PATH\r\n$ pip install -U -r requirements.txt # install dependencies\r\n$ pip install -e . # install ChocoPy as a package\r\n$ # get to hacking, and best of luck! :)\r\n```\r\n\r\n### Test your solutions\r\n\r\nYou can use `lit` to automatically test your code, which is include in the `requirements.txt`.\r\n\r\nTo run it locally, do:\r\n\r\n```bash\r\nlit -v tests/end-to-end\r\n```\r\n\r\nThis will examine recursively all the files with valid formats inside the above directory.\r\nThe `-v` flag adds a verbose output with more information in case some tests fail.\r\nYou can also leverage the `--timeout \u003cseconds\u003e` flag, in order to bound the time allowed for your test cases to run.\r\nThis way you can detect if your parser loops infinitely in some test cases.\r\n\r\nFor more details on the configuration of `lit`, see `tests/lit.cfg`.\r\nFor more info on `lit` check the [online documentation](https://filecheck.readthedocs.io/en/latest/01-what-is-filecheck.html).\r\n\r\n## Task 1 - Code Generation\r\n\r\nThe goal of task 1 is to write a code generator for the [ChocoPy Language](https://chocopy.org), targeting the [RISC-V architecture](https://riscv.org/).\r\nThe output RISC-V program will be run on a RISC-V interpreter.\r\n\r\nIn particular, you need to implement the lowering from the `choco.ir` dialect to the `riscv_ssa` dialect.\r\nThe template already provides a partial implementation of the lowering.\r\nYou will have to implement the rest.\r\n\r\n### 1. Getting Started\r\n**First read this README completely and carefully!**\r\nIt explains the lowering phases of the code generation, as well as how to run the assembly code.\r\nWe have also added some [hints](#6-Hints) that are useful for this coursework.\r\n\r\nTo understand how lowering from `choco.ast` to `choco.ir` works (step I), have a look at `choco/choco_ast_to_choco_flat.py`.\r\nAfter you have a quick look, it would be particularly useful for understanding the next steps, if you get a good understanding of the following files:\r\n\r\n* `choco/choco_flat_introduce_library_calls.py`\r\n* `choco/for_to_while.py`\r\n\r\nThe `choco.ir` dialect is described in `choco/dialects/choco_flat.py`.\r\n\r\n### 2. RISC-V SSA Dialect\r\n\r\nTo understand how you should lower `choco.ir` to `riscv_ssa` (step II), you need look at what RISC-V instructions are available in the class `RISCVSSA` of `riscv/ssa_dialect.py`.\r\n\r\nEach instruction subclasses a RISC-V Operation, e.g., `Riscv1Rd1Rs1ImmOperation`, which tells you how to use this particular instruction.\r\nFor example, the aforementioned operation uses one destination register (`Rd`), one source register (`Rs`) and one immediate (`Imm`).\r\nA RISC-V instruction that corresponds to this encoding is `AddIOp`, which adds an immediate to the source register, and places the result on the destination register.\r\n\r\n### 3. Runtime Library\r\n\r\nWe give you the implementation of the runtime library, which is automatically added to your riscv programs. Some of the library function calls are already generated by the frontend, but you will need to generate some calls for these functions:\r\n* `_malloc`: Allocate in the heap the number of bytes given as argument, and return a pointer to it.\r\n* `_error_len_none`: Print an error and exit the program. This should be used when `len` is called on a `None` value.\r\n* `_list_index_oob`: Print an error and exit the program. This should be used when an array is accessed out of bounds.\r\n* `_list_index_none`: Print an error and exit the program. This should be used when `None` is indexed.\r\n\r\n### 4. Rewriter API\r\n\r\nIn order to transform the IRs, you will need to use the xDSL rewriter engine.\r\nHere is for instance the given skeleton for the `UnaryExpr` rewrite pattern:\r\n```\r\nclass UnaryExprPattern(RewritePattern):\r\n\r\n    @op_type_rewrite_pattern\r\n    def match_and_rewrite(self, unary_op: UnaryExpr,\r\n                          rewriter: PatternRewriter):\r\n        raise NotImplementedError()\r\n```\r\n\r\nThe `match_and_rewrite` method will be called for each `UnaryExpr` in the IR.\r\nThe `rewriter` argument has multiple methods that you will need to use throughout the coursework:\r\n* `insert_op_before_matched_op`: Inserts new operations given as inputs before the matched operation (`unary_op` here).\r\n* `erase_matched_op`: Erase the matched operation. If the matched operation had results that are still used, this will trigger an error.\r\n* `erase_op`: Erase the given operation. The given operation should either be the matched\r\n  operation, or an operation contained in the matched operation's regions and blocks. If the\r\n  given operation had results that are still used, this will trigger an error.\r\n* `replace_matched_op`: Replace the matched operation with new operations given as input. The\r\n  SSA results of the matched operation will be replaced by the SSA results of the last given\r\n  operation. Optionally, you can provide a list of SSA values to replace the results of the\r\n  matched operation.\r\n* `inline_block_before_matched_op`: Move the operations in a block right before the matched operation.\r\n\r\nNote that `insert_op_before_matched_op` and `inline_block_before_matched_op` should not be used after `replace_matched_op` or `erase_matched_op`.\r\n\r\n### 5. Coding\r\n\r\nTo get started coding look at the file `choco/choco_flat_to_riscv_ssa.py` which contains an incomplete implementation of the lowering to `riscv_ssa`.\r\n\r\nThe file contains:\r\n\r\n- An example rewrite pattern for call expressions.\r\n- A utility function to call the rewriters that lower `choco.ir` to `riscv_ssa`.\r\n\r\n**You will need to complete the implementations of the other rewrite patterns**.\r\n\r\n\r\n#### We suggest the following order when implementing the rewrite patterns:\r\n\r\n1. Literals (except strings)\r\n2. Unary expressions (arithmetic and logical)\r\n3. Arithmetic binary expressions\r\n4. Assign statements (alloca, load, store)\r\n5. If statements\r\n6. Logical and conditional expressions\r\n7. While statements\r\n8. List expressions\r\n9. Index operation\r\n10. String literals and string operations\r\n\r\nThe `tests/end-to-end` folder contains a directory for each section,\r\nmaking it easier to check your progress.\r\n\r\nNow, you can actually execute a ChocoPy program!\r\nFirst, you can get the RISC-V assembly, by doing:\r\n\r\n```bash\r\ncd /path/to/coursework\r\nchoco-opt -p all -t riscv tests/end-to-end/print-integer-literal.choc\r\n```\r\n\r\nSecond, you can run the RISC-V assembly, using the `riscv-interpreter` tool:\r\n\r\n```bash\r\nriscv-interpreter tests/riscv/interpreter/hello_world.s\r\n```\r\n\r\nFinally, you can combine the above tools in order to execute directly a ChocoPy program:\r\n\r\n```bash\r\ncd /path/to/coursework\r\nchoco-opt -p all -t riscv tests/end-to-end/print-integer-literal.choc \u003etemp.s \u0026\u0026 riscv-interpreter temp.s\r\n```\r\n\r\nAlso, take a look at how `lit` will run tests with filecheck, examining the first line of, e.g., `tests/end-to-end/print-integer-literal.choc`.\r\n\r\n### 6. Simplifications\r\n\r\nIn your implementation, values will all be unboxed, meaning that they do not carry type information.\r\nHowever, with unboxed, it is not possible to use any value of type `object`, since we\r\ncannot recover its original type statically. To simplify your implementation, we will thus not test\r\nany code that has `object` values, or heterogeneous lists. In particular, this include expressions\r\nsuch as `if True then 2 else \"foo\"`, or `[0, True]`.\r\n\r\nSimilarly, we only support `print` with a `bool`, `int`, or `str` input.\r\n\r\n### 7. Hints\r\n\r\n#### Alloca, Load, Store\r\n\r\nInitially, you can check the correct implementation of `Alloca`, `Store` and `Load`, using the test cases inside `end-to-end/var-defs`.\r\n`Alloca` and `Store` are necessary for variable definitions, `Store` is also necessary for assignments, and `Load` is necessary whenever you are accessing a variable.\r\n\r\n#### and, or, and if/else expressions\r\n\r\nThe `and`, `or`, and `if/else` expressions use short-circuit evaluation. This\r\nmeans that in the case of an `and` for instance, `False and foo()` will not lead\r\nto the execution of `foo`, since `and` will return `False` for any value\r\nreturned by `foo`. This is important in the case where `foo` has a side-effect.\r\n\r\n`and`, `or`, and `if/else` expressions use regions to separate both \"branches\".\r\nSince both branches can have SSA variables, the \"result\" of a branch is given by\r\nthe `yield` operation. Here is for instance the code for `0 \u003e 1 or 1 \u003e= 2`:\r\n\r\n```\r\nbuiltin.module() {\r\n  choco.ir.func_def() [\"func_name\" = \"_main\", \"return_type\" = !choco.ir.named_type\u003c\"\u003cNone\u003e\"\u003e] {\r\n    %0 : !choco.ir.named_type\u003c\"bool\"\u003e = choco.ir.effectful_binary_expr() [\"op\" = \"or\"] {\r\n      %1 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 0 : !i32]\r\n      %2 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 1 : !i32]\r\n      %3 : !choco.ir.named_type\u003c\"bool\"\u003e = choco.ir.binary_expr(%1 : !choco.ir.named_type\u003c\"int\"\u003e, %2 : !choco.ir.named_type\u003c\"int\"\u003e) [\"op\" = \"\u003e\"]\r\n      choco.ir.yield(%3 : !choco.ir.named_type\u003c\"bool\"\u003e)\r\n    } {\r\n      %4 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 1 : !i32]\r\n      %5 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 2 : !i32]\r\n      %6 : !choco.ir.named_type\u003c\"bool\"\u003e = choco.ir.binary_expr(%4 : !choco.ir.named_type\u003c\"int\"\u003e, %5 : !choco.ir.named_type\u003c\"int\"\u003e) [\"op\" = \"\u003e=\"]\r\n      choco.ir.yield(%6 : !choco.ir.named_type\u003c\"bool\"\u003e)\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n#### If Statement\r\n\r\nThings will start to become more difficult with control flow.\r\nEssentially, control flow constructs will be needed for if-else statements, while statements, but also for the logical binary expressions (`and`/`or`) and the conditional expression.\r\n\r\nAssume the following program:\r\n\r\n```python\r\nif True:\r\n  42\r\nelse:\r\n  17\r\n```\r\n\r\nYou can see what is the `choco.ir` form of this program by running:\r\n\r\n```\r\n$ choco-opt -p check-assign-target,name-analysis,type-checking,choco-ast-to-choco-flat,choco-flat-introduce-library-calls,for-to-while /path/to/program\r\n\r\nbuiltin.module() {\r\n  choco.ir.func_def() [\"func_name\" = \"_main\", \"return_type\" = !choco.ir.named_type\u003c\"\u003cNone\u003e\"\u003e] {\r\n    %0 : !choco.ir.named_type\u003c\"bool\"\u003e = choco.ir.literal() [\"value\" = !choco.ir.bool\u003cTrue\u003e]\r\n    choco.ir.if(%0 : !choco.ir.named_type\u003c\"bool\"\u003e) {\r\n      %1 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 42 : !i32]\r\n    } {\r\n      %2 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 17 : !i32]\r\n    }\r\n  }\r\n}\r\n```\r\n\r\nNotice the SSA values created for the condition (`%0`), the value in the if-then block (`%1`), and the value in the if-else block (`%2`).\r\n\r\nWe sketch how you should approach control flow, when lowering from `choco.ir` to `riscv_ssa`:\r\n\r\n1. Assuming that you evaluate conditions by comparing them with zero, you need an SSA value for the constant `0`.\r\n2. You need a RISC-V branch instruction to compare your condition with zero.\r\n3. Since we have control flow, you need labels to represent locations in code, i.e., where is the code for the if-then block, for the if-else block, and for the code after the if statement.\r\n4. If your condition evaluates to false, then you need to jump to the if-else label.\r\n5. Otherwise, you continue with the if-then block, but you also need an extra instruction to jump to the code after the if statement.\r\n\r\nThe correct `riscv_ssa` output would be:\r\n\r\n```\r\n$ choco-opt -p check-assign-target,name-analysis,type-checking,choco-ast-to-choco-flat,choco-flat-introduce-library-calls,for-to-while,choco-flat-to-riscv-ssa /path/to/program\r\n\r\nbuiltin.module() {\r\n  riscv_ssa.func() [\"func_name\" = \"_main\"] {\r\n    %0 : !riscv_ssa.reg = riscv_ssa.li() [\"immediate\" = 1 : !i32]\r\n    %1 : !riscv_ssa.reg = riscv_ssa.li() [\"immediate\" = 0 : !i32]\r\n    riscv_ssa.beq(%0 : !riscv_ssa.reg, %1 : !riscv_ssa.reg) [\"offset\" = !riscv.label\u003cif_else_1\u003e]\r\n    riscv_ssa.label() [\"label\" = !riscv.label\u003cif_then_1\u003e]\r\n    %2 : !riscv_ssa.reg = riscv_ssa.li() [\"immediate\" = 42 : !i32]\r\n    riscv_ssa.j() [\"offset\" = !riscv.label\u003cif_after_1\u003e]\r\n    riscv_ssa.label() [\"label\" = !riscv.label\u003cif_else_1\u003e]\r\n    %3 : !riscv_ssa.reg = riscv_ssa.li() [\"immediate\" = 17 : !i32]\r\n    riscv_ssa.label() [\"label\" = !riscv.label\u003cif_after_1\u003e]\r\n  }\r\n}\r\n```\r\n\r\nThere are many things to notice here.\r\n\r\n* `%0` is the SSA value of `True` in the condition.\r\n* `%1` is the SSA value of zero.\r\n* `riscv_ssa.beq` compares the condition with zero. If the condition evaluates to zero (i.e., false), we jump to the `if_else_1` label.\r\n* Otherwise, we continue to the if-then block (`if_then_1` label).\r\n* `%2` is the only thing inside the if-then block.\r\n* `riscv_ssa.j` jumps over the if-else block to the code after if (`if_after_1` label).\r\n* `%3` is the only thing inside the if-else block.\r\n\r\nIn order to generate branch instructions in the `riscv_ssa` dialect, you can choose one of the `BEQOp`, `BNEOp`, etc.\r\nSee the `ricsv/ssa_dialect` for more details.\r\n\r\nThese instructions are of `Riscv2Rs1OffOperation` type, which means that they take two SSA values and one offset as an argument.\r\nThe offset should be a string representing the label name to which you are branching.\r\n\r\nA final thing to keep in mind is that each label name should be unique.\r\nIf you use for the `if_then_label` variable the string `\"if_then\"`, and your program contains multiple if statements,\r\nyou will end up with identical label names (which is wrong).\r\n\r\nUse the counters provided in the rewrite patterns to get unique names for your labels.\r\n\r\n## Task 2 - Code Optimization\r\n\r\nThe goal of this task is to optimize the code in terms of code size,\r\nthat is to reduce the generated lines of RISC-V assembly.\r\n\r\nWe give examples of different forms below.\r\n\r\n### Getting Started\r\n\r\nFor this task, you can modify or add any pass you want, at any level (dialect) of the compilation pipeline.\r\nWe only ask you to not modify nor remove the library calls, nor change the command line API.\r\nBe careful that your optimizations are correct, because otherwise you might lose points in task 1 as well!\r\n\r\nThe files in `tests/end-to-end/code-size-optimization` contain examples that have some optimization opportunities.\r\nWe recommend you to implement these optimizations (in order of difficulty):\r\n* Constant folding (you can continue the implementation of `choco/constant_folding.py`)\r\n* Some arithmetic rewrite rules (such as `x * 0 = 0`, or `(x + 3) + 5 = x + 8`)\r\n* Removal of unnecessary `load`/`store` for temporary chocopy variables.\r\n* Improving the register allocator to not always spill registers on the stack.\r\n  This can be done in a pass after the translation of riscv-ssa to riscv, or by modifying\r\n  the register allocator (hard, but would yield better code reduction).\r\n\r\nWe include two minimal examples of rewriters, which operate on the `choco.ir` level.\r\nSo, you need to have a good understanding of the following files:\r\n\r\n* `choco/constant_folding.py`\r\n* `choco/dead_code_elimination.py`\r\n\r\n### Adding a new pass to `choco-opt`\r\n\r\nWe take as similar approach as in `choco/constant_folding.py`.\r\n\r\nFirst, you need to create a similar file, e.g., `choco/your_new_pass.py`.\r\n\r\nThen, this file can contain your rewriter pattern and a function that will invoke the `PatternRewriteWalker` with your rewriter.\r\nFor example, this function could be called `choco_flat_your_new_pass`, assuming that your new pass operates on `choco.ir` (choco flat).\r\n\r\nFinally, you need to import this invocation function from `choco-opt`, by including:\r\n\r\n```python\r\nfrom choco.your_new_pass import choco_flat_your_new_pass\r\n```\r\n\r\nand, also, you need to add the function into the `passes_native` list:\r\n\r\n```python\r\n    passes_native = [\r\n        # Semantic Analysis\r\n        check_assign_target,\r\n        # ...\r\n\r\n        # IR Optimization\r\n        # ...\r\n        choco_flat_your_new_pass,\r\n\r\n        # Code Generation\r\n        # ...\r\n    ]\r\n\r\n```\r\n\r\n\r\n\r\nAdding a new separate pass could help with development and debugging, as you can include only some of your passes in `choco-opt` invocation and see if one of them is causing an error.\r\n\r\nIn particular, instead of passing `-p all` to `choco-opt`, you can be explicit about the passes:\r\n\r\n\r\n```bash\r\ncd /path/to/coursework\r\nchoco-opt -p check-assign-target,name-analysis,type-checking,warn-dead-code,choco-ast-to-choco-flat,choco-flat-introduce-library-calls,choco-flat-constant-folding,choco-flat-dead-code-elimination,for-to-while,choco-flat-to-riscv-ssa,riscv-ssa-to-riscv,riscv-function-lowering -t riscv tests/end-to-end/print-integer-literal.choc\r\n```\r\n\r\nNotice the `choco-flat-constant-folding` and `choco-flat-dead-code-elimination` passes.\r\nYou could remove or add more passes likewise.\r\nRun:\r\n\r\n```bash\r\nchoco-opt -h\r\n```\r\n\r\nfor more info.\r\n\r\nIf you want to always use the `-p all` flag for brevity, you can also comment out the pass you want to remove from the `passes_native` list in `choco-opt`.\r\n\r\n### Examples\r\n\r\n#### Dead code elimination in the `choco.ir`:\r\n\r\nThe code:\r\n```\r\nbuiltin.module() {\r\n  choco.ir.func_def() [\"func_name\" = \"_main\", \"return_type\" = !choco.ir.named_type\u003c\"\u003cNone\u003e\"\u003e] {\r\n    %0 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 42 : !i32]\r\n    %1 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 8 : !i32]\r\n    choco.ir.call_expr(%0 : !choco.ir.named_type\u003c\"int\"\u003e) [\"func_name\" = \"print\"]\r\n  }\r\n}\r\n```\r\ncan be converted to:\r\n```\r\nbuiltin.module() {\r\n  choco.ir.func_def() [\"func_name\" = \"_main\", \"return_type\" = !choco.ir.named_type\u003c\"\u003cNone\u003e\"\u003e] {\r\n    %0 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 42 : !i32]\r\n    choco.ir.call_expr(%0 : !choco.ir.named_type\u003c\"int\"\u003e) [\"func_name\" = \"print\"]\r\n  }\r\n}\r\n```\r\nwhere the SSA value `%1` was removed since it was not used later.\r\n\r\n#### Constant propagation and dead code elimination in the `choco.ir`:\r\n\r\nThe code:\r\n```\r\nbuiltin.module() {\r\n  choco.ir.func_def() [\"func_name\" = \"_main\", \"return_type\" = !choco.ir.named_type\u003c\"\u003cNone\u003e\"\u003e] {\r\n    %0 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 42 : !i32]\r\n    %1 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 8 : !i32]\r\n    %2 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.binary_expr(%0 : !choco.ir.named_type\u003c\"int\"\u003e, %1 : !choco.ir.named_type\u003c\"int\"\u003e) [\"op\" = \"+\"]\r\n    choco.ir.call_expr(%2 : !choco.ir.named_type\u003c\"int\"\u003e) [\"func_name\" = \"print\"]\r\n  }\r\n}\r\n```\r\n\r\ncan be converted to:\r\n\r\n```\r\nbuiltin.module() {\r\n  choco.ir.func_def() [\"func_name\" = \"_main\", \"return_type\" = !choco.ir.named_type\u003c\"\u003cNone\u003e\"\u003e] {\r\n    %0 : !choco.ir.named_type\u003c\"int\"\u003e = choco.ir.literal() [\"value\" = 50 : !i32]\r\n    choco.ir.call_expr(%0 : !choco.ir.named_type\u003c\"int\"\u003e) [\"func_name\" = \"print\"]\r\n  }\r\n}\r\n```\r\n\r\nwhere the binary expression was replaced by the sum of the constants,\r\nand the SSA values `%1` and `%2` were eliminated as dead.\r\nThe dead code elimination was enabled by the constant propagation.\r\n\r\n## Implementation guidelines\r\n\r\n###  Commit and push your changes to GitHub\r\n\r\nYou are encouraged to commit your changes regularly.\r\nThis allows you to track\r\nthe history of your changes so that you can revert to an earlier version of your code if you need to.\r\nIt also protects you from losing any of your work in the case of a computer failure.\r\n\r\nFurthermore, every time you commit and push your changes in the `main` branch, your points are updated,\r\ngiving you continuous feedback on your implementation.\r\n\r\n### Check your points\r\n\r\nThis badge shows how many successful test cases you've had so far.\r\n\r\n ![Points badge](../../blob/badges/.github/badges/points.svg)\r\n\r\nThese points are **provisional** and are not related to the final grade.\r\nThe number of successful test cases is only an indicator of how strong your implementation is,\r\nwith respect to how many language features it covers.\r\nYour parser will be tested also on other test cases,\r\nso it is important that you write your own tests to ensure that your code is thoroughly tested.\r\n\r\nOnce you have pushed all of your changes to GitHub and you are happy with your code and your points, you're finished! We will grade your last submission.\r\nSubmissions after the deadline, will result in penalties without an approved extension. See \"Assessment\" on Learn for details.\r\n\r\n## Misc\r\n\r\nFollow our academic guidelines and take advantage of Piazza to discuss any open questions.\r\n\r\nFor the following courseworks, the full lexer and parser will be provided.\r\n\r\n### Guidelines\r\nPlease remember the good scholarly practice requirements of the University regarding work for credit.\r\n\r\nThe number of passing test cases is intended to give you an idea of the quality of the code.\r\nHowever, the actual grading of your coursework takes place after the deadline and takes into account public and hidden automatic tests, as well as potential manual reviews.\r\n\r\nSubmitted code will be checked for similarity with other submissions using the MOSS system. MOSS has been effective in the past at finding similarities and it is not fooled by name changes or reordering of code blocks. Courseworks are INDIVIDUAL, and we expect everyone to turn in their sole, independent work.\r\n\r\nExtensions: Please refer to the \"Assessment\" page on Learn for information on extensions.\r\n\r\n### Questions\r\nIf you have questions, you should consult the lecture slides and recordings. If you have questions about the coursework, please start by **checking existing discussions on Piazza**. If you can't find the answer to your question, start a new discussion. It is quite possible that other students will have encountered and solved the same problem and will be able to help you. The TA will also monitor Piazza and clarify things as necessary, after allowing time for student discussion to take place.\r\n# CT Coursework 3 Code Generation\n\n# 程序代做代写 CS编程辅导\n\n# WeChat: cstutorcs\n\n# Email: tutorcs@163.com\n\n# CS Tutor\n\n# Code Help\n\n# Programming Help\n\n# Computer Science Tutor\n\n# QQ: 749389476\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-help-tutor%2Fct-coursework-3-code-generation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcode-help-tutor%2Fct-coursework-3-code-generation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-help-tutor%2Fct-coursework-3-code-generation/lists"}