{"id":14991151,"url":"https://github.com/raffaeletranfaglia/llvm-middle-end-optimizations","last_synced_at":"2025-04-12T03:25:42.823Z","repository":{"id":231734557,"uuid":"782127929","full_name":"RaffaeleTranfaglia/LLVM-Middle-End-Optimizations","owner":"RaffaeleTranfaglia","description":"Machine independent passes to optimise LLVM intermediate representation.","archived":false,"fork":false,"pushed_at":"2024-06-09T17:09:00.000Z","size":1255,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T23:05:00.362Z","etag":null,"topics":["cpp","llvm","llvm-ir","llvm-pass","optimization"],"latest_commit_sha":null,"homepage":"https://llvm.org/","language":"C++","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/RaffaeleTranfaglia.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,"publiccode":null,"codemeta":null}},"created_at":"2024-04-04T17:33:28.000Z","updated_at":"2024-06-09T17:09:04.000Z","dependencies_parsed_at":"2024-09-25T00:34:17.222Z","dependency_job_id":null,"html_url":"https://github.com/RaffaeleTranfaglia/LLVM-Middle-End-Optimizations","commit_stats":{"total_commits":59,"total_committers":4,"mean_commits":14.75,"dds":0.5932203389830508,"last_synced_commit":"d5aab0f6c266f62d6362c1f5ba819d7373b2d69e"},"previous_names":["raffaeletranfaglia/llvm-middle-end-optimizations"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaffaeleTranfaglia%2FLLVM-Middle-End-Optimizations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaffaeleTranfaglia%2FLLVM-Middle-End-Optimizations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaffaeleTranfaglia%2FLLVM-Middle-End-Optimizations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaffaeleTranfaglia%2FLLVM-Middle-End-Optimizations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RaffaeleTranfaglia","download_url":"https://codeload.github.com/RaffaeleTranfaglia/LLVM-Middle-End-Optimizations/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248511281,"owners_count":21116382,"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":["cpp","llvm","llvm-ir","llvm-pass","optimization"],"created_at":"2024-09-24T14:21:36.043Z","updated_at":"2025-04-12T03:25:42.803Z","avatar_url":"https://github.com/RaffaeleTranfaglia.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LLVM-Middle-End-Optimizations\nMachine independent passes to optimise LLVM intermediate representation.  \n\n## Local Optimizations\n### Installation\nIn order to run the optimization passes, it is necessary having LLVM 17.0.6 source code installed.  \nOfficial repository [here](https://github.com/llvm/llvm-project).  \n\nThe following steps assume that LLVM 17.0.6 has been installed.  \nClone the current repository:\n```\ngit clone https://github.com/RaffaeleTranfaglia/LLVM-Middle-End-Optimizations.git\n```\n`src/LocalOpts/LocalOpts.cpp` file must be moved to the following directory:  \n```\n$SRC/llvm/lib/Transforms/Utils\n```\nAdd `LocalOpts.cpp` in `$SRC/llvm/lib/Transforms/Utils/CMakeLists.txt`.  \n`src/LocalOpts/LocalOpts.h` file must be moved to the following directory:  \n```\n$SRC/llvm/include/llvm/Transforms/Utils\n```\nReplace `SRC/llvm/lib/Passes/PassRegistry.def` with the provided `src/PassRegistry.def`.  \nAdd the follwing line to `SRC/llvm/lib/Passes/PassBuilder.cpp`:\n```\n#include \"llvm/Transforms/Utils/LocalOpts.h\"\n```\nWhere `$SRC` is the source folder of the project.  \nTo compile the source code:\n```\ncd $ROOT/BUILD\nmake opt\nmake install\n```\n  \nOtherwise, to install the source code already containig the optimized passes' files: [here](https://github.com/Glixes/LLVM_middle_end).\n\n### Introduced Optimizations\n\n#### Constant Folding\nConstant Folding execute at compile time operations involving contant values.  \nExamples:\n- `x = 4 + 9` \u0026#8594; `x = 13 + 0`\n- `x = 6 * 2` \u0026#8594; `x = 12 + 0`\n\nObservation:\nThe assignment of the computed constant is carryed out using an addition of the given constant with zero.  \nAfterwards the introduced `add` will furtherly be optimized by the Algebric Identity optimization.\n\n#### Algebraic Identity optimization \nAlgebraic Identity aims to optimise operation containing neutral values.  \nExamples:\n- `y = x + 0` \u0026#8594; every use of `y` is replaced with `x`\n- `a = b * 1` \u0026#8594; every use of `a` is replaced with `b`\n\n#### Strength Reduction\nA strength reduction pass replace `mul` instructions with shift instruction to reduce computational complexity. \nExample:\n- `x * 15` \u0026#8594; `(x \u003c\u003c 4) - x`\n- `x * 17` \u0026#8594; `(x \u003c\u003c 5) - 15x`\n- `x / 16` \u0026#8594; `x \u003e\u003e 4`\n\nObservations:  \nIn case the element \"subtracted\" can be optimized, the algorithm will optimize further more the operation. In case it is used on divisions, the divisor **must** be an exact multiple of 2.\n\n#### Multi-instruction optimization\nMulti instruction optimization operates in cases where, given a SSA register, the same fixed amount is addend and subtracted from it.\nExamples:\n- `y = x + 2; z = y - 2` \u0026#8594; every use of `z` is replaced with `x`\n- `y = x + 2; z = y / 2` \u0026#8594; every use of `z` is replaced with `x`\n\n## Global Optimizations\n`DataFlowAnalysis` folder contains global optimizations algorithms.  \nOptimization tasks addressed:\n- Very Busy Expressions\n- Dominator Analysis\n- Constant Propagation\n\n### Loop Invariant Code Motion (LICM)\nInstructions that does not change from one iteration to another can be moved outside the loop in order to be executed only once.\n\nInstructions that meet the following requirements are candidate for code motion:\n- are invariant\n- dominate their uses\n- dominate the exits of the loop or are dead outside the loop\n\nCandidated instruction may be moved outside the loop (just before the loop header, in the so called preheader block) in order to be executed only one time.  \n  \n`LoopOpts.cpp` and `LoopOpts.h` files contain the Loop Invariant Code Motion pass.  \nIn order to make the pass work, `src/GlobalOpts/LoopOpts.cpp` file must be moved to the following directory:  \n```\n$SRC/llvm/lib/Transforms/Utils\n```\nAdd `LoopOpts.cpp` in `$SRC/llvm/lib/Transforms/Utils/CMakeLists.txt`.  \n`src/GlobalOpts/LoopOpts.h` file must be moved to the following directory:  \n```\n$SRC/llvm/include/llvm/Transforms/Utils\n```\nReplace `SRC/llvm/lib/Passes/PassRegistry.def` with the provided `src/PassRegistry.def`.  \nAdd the follwing line to `SRC/llvm/lib/Passes/PassBuilder.cpp`:\n```\n#include \"llvm/Transforms/Utils/LoopFusion.h\"\n```\nWhere `$SRC` is the source folder of the project.  \nTo compile the source code:\n```\ncd $ROOT/BUILD\nmake opt\nmake install\n```\n\n### Loop Fusion\nGiven two loops that satisfy the follwing requirements:\n- are adjacent\n    - there cannot be any statement that execute between them\n- have the same number of iterations\n- are control flow equivalent\n    - given two loop Lj and Lk, Lj before Lk, Lk dominates Lj and Lj post-dominates Lk\n- are distance independent or have a non negative dependence distance\n    -  a negative distance dependence occurs between Lj and Lk, Lj before Lk, when at iteration m from Lk uses a value that is computed by Lj at a future iteration m+n (where n \u003e 0).\n\nThen they can be fused, i.e. the body of the latter is connected after the body of the former.\n\n`LoopFusion.cpp` and `LoopFusion.h` files contain the Loop Fusion pass.  \nIn order to make the pass work, `src/GlobalOpts/LoopFusion.cpp` file must be moved to the following directory:  \n```\n$SRC/llvm/lib/Transforms/Utils\n```\nAdd `LoopFusion.cpp` in `$SRC/llvm/lib/Transforms/Utils/CMakeLists.txt`.  \n`src/LoopOpts.h` file must be moved to the following directory:  \n```\n$SRC/llvm/include/llvm/Transforms/Utils\n```\nReplace `SRC/llvm/lib/Passes/PassRegistry.def` with the provided `src/PassRegistry.def`.  \nAdd the follwing line to `SRC/llvm/lib/Passes/PassBuilder.cpp`:\n```\n#include \"llvm/Transforms/Utils/LoopFusion.h\"\n```\nWhere `$SRC` is the source folder of the project.  \nTo compile the source code:\n```\ncd $ROOT/BUILD\nmake opt\nmake install\n```\n\n#### Example\nThe example defined in `Test/loop_fus_ex1_virtualregs.ll` shows the loop fusion pass in action.\n\n![loop_before_fusion](/imgs/loop_before_fusion.png)\n\n![loop_after_fusion](/imgs/loop_after_fusion.png)\n\n## Testing\n`Tests` folder contains different LLVM files to test the optimizations.\n\nCompile the source code:\n```\ncd $ROOT/BUILD\nmake opt\nmake install\n```\n\nTo create a file that uses virtual registries starting from the file written in C:\n```\nopt -p mem2reg \u003cfile_name\u003e.c -o \u003cfile_name_virtualmem\u003e.bc\nllvm-dis \u003cfile_name_virtualmem\u003e.bc -o \u003cfile_name_virtualmem\u003e.ll\n```\nThis step is needed only for global passes.  \nTo directly start from the .ll file with virtual registers, both source files (.c and .ll) are provided in the `Tests/` directory.\n\nTo run tests:\n```\nopt -p \u003coptimization_pass_name\u003e \u003cfile_name\u003e.ll -o \u003cfile_name_optimized\u003e.bc\nllvm-dis \u003cfile_name_optimized\u003e.bc -o \u003cfile_name_optimized\u003e.ll\n```\n\nNote:\nImplemented passes names are `localopts`, `loopopts` and `loopfusion`.\n\n## Authors\n- Raffaele Tranfaglia\n- Matteo Venturi\n- Mirco Piccinini\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraffaeletranfaglia%2Fllvm-middle-end-optimizations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraffaeletranfaglia%2Fllvm-middle-end-optimizations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraffaeletranfaglia%2Fllvm-middle-end-optimizations/lists"}