{"id":21411657,"url":"https://github.com/flandrade/live-variable-analysis","last_synced_at":"2025-04-18T03:33:12.560Z","repository":{"id":83193441,"uuid":"558796863","full_name":"flandrade/live-variable-analysis","owner":"flandrade","description":"Live Variable Analysis with Haskell","archived":false,"fork":false,"pushed_at":"2023-09-07T11:49:51.000Z","size":13,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-29T06:21:55.645Z","etag":null,"topics":["compilers","haskell","live-variable-analysis"],"latest_commit_sha":null,"homepage":"","language":"Haskell","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/flandrade.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2022-10-28T10:14:01.000Z","updated_at":"2024-07-12T12:34:30.000Z","dependencies_parsed_at":"2024-11-22T17:47:57.166Z","dependency_job_id":null,"html_url":"https://github.com/flandrade/live-variable-analysis","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flandrade%2Flive-variable-analysis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flandrade%2Flive-variable-analysis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flandrade%2Flive-variable-analysis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flandrade%2Flive-variable-analysis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flandrade","download_url":"https://codeload.github.com/flandrade/live-variable-analysis/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249420371,"owners_count":21268833,"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":["compilers","haskell","live-variable-analysis"],"created_at":"2024-11-22T17:47:07.876Z","updated_at":"2025-04-18T03:33:12.527Z","avatar_url":"https://github.com/flandrade.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Live Variable Analysis\n\nThis project is an implementation of live variable analysis, a technique used in compilers to determine the\nvariables that are still in use at a certain point in a program's execution.\n\n## Implementation and Running the Analysis\n\nThe implementation of live variable analysis in this project uses a data flow analysis algorithm to track\nthe flow of variables through the program. The algorithm takes into account the control flow of the program\nand the use and definition of variables at each program point. The analysis is performed on the\nintermediate representation of the program represented as a\n[control flow graph](https://en.wikipedia.org/wiki/Control-flow_graph).\n\nThe algorithm employed is based on the iterative data flow analysis method, where multiple passes\nare made over the program until the results converge to a stable solution. The implementation was\nwritten in Haskell and uses a map structure to store the live variables at each point in the\nprogram.\n\nTo run the analysis:\n\n```bash\ncabal install\ncabal run\n```\n\n### Expressions\n\nAn arithmetic expression is given by the following syntax: $e ::= n | x | e_1 + e_2 | e_1 - e_2 | e_1 * e_2$\n\n```haskell\ndata AExpression\n  = Literal Int\n  | Variable String\n  | Add AExpression AExpression\n  | Sub AExpression AExpression\n  | Mul AExpression AExpression\n```\n\nFor example, the arithmetic expression `x + 1` is represented as: `Add (E.Variable \"x\") (E.Literal 1)`\n\nOn the other hand, a boolean expression is given by the following syntax: $b ::= e_1 \\leq e_2 | e_1 = e_2 | b_1 \\land b_2$\n\n```haskell\ndata BExpression\n  = Leq AExpression AExpression\n  | Equal AExpression AExpression\n  | And BExpression BExpression\n```\n\nFor example, the boolean expression `x \u003c= 1` is represented as: `Leq (E.Variable \"x\") (E.Literal 1)`\n\n## Representation of the Control Flow Graph\n\nIn this implementation, programs are encoded into a CFG, where the basic blocks are assignments and boolean expressions. Each basic block will contain a unique label. In live variable analysis, the process receives a program’s Control Flow Graph (CFG) and yields, for every block in the CFG, the set of live variables before and after that block.\n\nHere is an example in [While](https://www.cs.cmu.edu/~aldrich/courses/15-819O-13sp/resources/while-language.pdf):\n\n```while\nx := 1\nwhile y \u003e 0 do\n    y := y - 1;\n    x := 2;\n```\n\n```mermaid\ngraph TD\n    A[x:=1] --\u003e B[y\u003e0]\n    B ---\u003e |no| D[x:=2]\n    B ---\u003e |yes| C[y:=y-1]\n    C --\u003e B\n```\n\nA Control-Flow Graph (CFG) is a list of blocks. Blocks can be either assignments or conditional. In this\nimplementation, we use the following data structures:\n\n```hs\ntype CFG = [Block]\n\ndata BlockType\n  = Skip\n  | Assignment String E.AExpression\n  | Conditional E.BExpression\n```\n\nFor instance, the assignment `x = 1` can be represented as: `Assignment (Add (E.Variable \"x\") (E.Literal 1)`\n\nA block from the CFG is represented as a record than contains a block (block type), an outLink (exit blocks) and the label. In this implementation, each block is represented according to the following data structure:\n\n```hs\ndata Block = Block\n  { block :: BlockType,\n    label :: Int,\n    outLink :: [Int]\n  }\n```\n\nFor instance, the block \"1\" can be represented as the following record:\n\n```\n---------\n| x = 1 |---\u003e Block 3\n---------\n   |\nBlock 2\n```\n\nThe block \"1\" can be represented as the following record:\n\n```hs\nBlock\n  { block: Assignment (Add (E.Variable \"x\") (E.Literal 1))\n    label: 1\n    outLink: [2, 3]\n  }\n```\n\n## Data Flow Equations\n\nFor this analysis, we compute the following set of variables:\n\n- $LVIn_n$: Live variables at the entry of block n. For this, we use the transfer function:\n\n  $VIn_n = (LVOut_n − Kill_n) \\cup Gen_n$\n\n  where $Gen_n$ are variables that are read in block n, and $Kill_n$: are variables that are written to in block n.\n\n- $LVOut_n$: Live variables at the exit of block n. A variable is live at the exit of a block if it is live\n  at the entrance of any of the blocks following it. For instance, the block 1:\n\n  ```\n  ---------\n  | x = 1 |---\u003e Block 3\n  ---------\n    |\n  Block 2\n  ```\n\n  The $LVout_1$ equation is: $LVOut_1 = LVIn_2 \\cup LVIn_3$\n\n### Solution of the Equation System\n\nThe result of this analysis is a system of equations with unknown variables\n$(LVOut_1, LVOut_2, ...LVIn_n)$. These variables represent the fixed points of $F$, which is defined\nas the supremum of the ascending\n[Kleene chain](https://en.wikipedia.org/wiki/Kleene_fixed-point_theorem). Here, $F$ is the vector:\n\n$$\nF =\n\\begin{pmatrix}\nLVout_1 \\\\\n... \\\\\nLVout_1 \\\\\nLVIn_1 \\\\\n... \\\\\nLVIn_n \\\\\n\\end{pmatrix}\n$$\n\nThe solutions to this system can be found by repeating the following steps until the variables\nconverge to a stable solution:\n\n1. Solving the data flow equations starts with initializing all LVIn and LVOut to the empty set:\n\n   ```hs\n   LV' = Map (1, LV { LVIn=empty, LVOut=empty })\n   ```\n\n2. We get the new variable using this point\n\n   ```hs\n   LV'' = getLV LV' ...\n   ```\n\nWe repeat (2) until the LV of the previous point is equal to the LV of the current point. This is the solution to our equation system!\n\n## Example\n\nComplete example using the [While](https://www.cs.cmu.edu/~aldrich/courses/15-819O-13sp/resources/while-language.pdf) language:\n\n```while\nx := 1\nwhile y \u003e 0 do\n    y := y - 1;\n    x := 2;\n```\n\nGraphical representation of the control flow graph:\n\n```mermaid\ngraph TD\n    A[x:=1] --\u003e B[y\u003e0]\n    B ---\u003e |no| D[x:=2]\n    B ---\u003e |yes| C[y:=y-1]\n    C --\u003e B\n```\n\nRepresentation of the control flow graph in this implementation:\n\n```hs\nlet block1 = G.Assignment \"x\" (E.Literal 1)\nlet block2 = G.Conditional (E.Leq (E.Literal 1) (E.Variable \"y\"))\nlet block3 = G.Assignment \"x\" (E.Sub (E.Variable \"x\") (E.Literal 1))\nlet block4 = G.Assignment \"x\" (E.Literal 2)\nlet graph =\n  [\n    G.Block {G.label = 1, G.outLink = [2], G.block = block1},\n    G.Block {G.label = 2, G.outLink = [3, 4], G.block = block2},\n    G.Block {G.label = 3, G.outLink = [2], G.block = block3},\n    G.Block {G.label = 4, G.outLink = [], G.block = block4}\n  ] :: G.CFG\n```\n\nLive Variable Analysis result:\n\n```\nLVIn1=[\"y\"] LVOut1=[\"x\",\"y\"]\nLVIn2=[\"x\",\"y\"] LVOut2=[\"x\",\"y\"]\nLVIn3=[\"x\",\"y\"] LVOut3=[\"x\",\"y\"]\nLVIn4=[] LVOut4=[]\n```\n\n## Acknowledgment\n\nThis implementation was a project assigned in the course \"Static Program Analysis and Constraint Solving\" at the Universidad Complutense de Madrid, taught by Professor Manuel Montenegro.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflandrade%2Flive-variable-analysis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflandrade%2Flive-variable-analysis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflandrade%2Flive-variable-analysis/lists"}