diff --git a/README.md b/README.md index 4bc2f39..b64cbf3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![CI Status](https://github.com/ethanuppal/cs3110_compiler/actions/workflows/ci.yaml/badge.svg) > "x86 is simple trust me bro" -> Last updated: 2024-05-08 23:06:31.747043 +> Last updated: 2024-05-09 01:08:34.998129 ``` $ ./main -h @@ -34,16 +34,19 @@ Written by: Utku Melemeti, Ethan Uppal, Jeffrey Huang, Jason Klein, Vijay Shanmu - Utku Melemetci (um44) - IR generation - Register allocation + - Data structures + - Randomized testing - Ethan Uppal (eu55) - Static analysis - Types and type checking - Control flow - Live variable analysis - - Abstraction for x86 assembly + - IR representation and abstraction for x86 assembly - CLI/user interface - Jeffrey Huang (jrh382) - Parser and lexer - Abstract syntax tree + - Type checking With some contributions from - Vijay Shanmugam (vrs29) diff --git a/README.md.template b/README.md.template index e61af93..898b29e 100644 --- a/README.md.template +++ b/README.md.template @@ -17,16 +17,19 @@ $ ./main -v - Utku Melemetci (um44) - IR generation - Register allocation + - Data structures + - Randomized testing - Ethan Uppal (eu55) - Static analysis - Types and type checking - Control flow - Live variable analysis - - Abstraction for x86 assembly + - IR representation and abstraction for x86 assembly - CLI/user interface - Jeffrey Huang (jrh382) - Parser and lexer - Abstract syntax tree + - Type checking With some contributions from - Vijay Shanmugam (vrs29) diff --git a/docs/introduction.md b/docs/introduction.md deleted file mode 100644 index bdd8f10..0000000 --- a/docs/introduction.md +++ /dev/null @@ -1,114 +0,0 @@ -# x86ISTMB Programming Language - Introduction and Tutorial - -> [!NOTE] -> This document is outdated. - -## Overview - -x86ISTMB is a minimalistic, strongly typed programming language designed for simplicity and clarity. It focuses on providing a straightforward approach to programming by limiting its features to the core essentials. This document serves as an introductory guide and tutorial to the x86ISTMB programming language. - -## Variables and Types - -### Declaring Variables - -In x86ISTMB, variables are declared using the `let` keyword followed by the variable name and an initial value. Currently, x86ISTMB supports only integer data types for variables. - -Syntax: - -```swift -let variableName = value -``` - -Example: - -```swift -let x = 5 -``` - -This statement declares a variable named `x` and initializes it with the value `5`. - -## Operators - -x86ISTMB supports three basic operators for performing arithmetic and assignment operations on integer values. These operators are: - -1. `+` (Addition): Adds two integer values. -2. `=` (Assignment): Assigns a value to a variable. -3. `*` (Multiplication): Multiplies two integer values. - -### Using Operators - -Operators can be used in expressions to perform operations on variables and integer literals. - -#### Addition (+) - -Syntax: - -```swift -let variableName = operand_A + operand_B -``` - -Example: - -```swift -let x = 5 -let y = x + 3 // y is now 8 -``` - -#### Assignment (=) - -Syntax: - -```swift -variableName = newValue -``` - -Example: - -```swift -let x = 5 -x = 10 // x is now 10 -``` - -#### Multiplication (*) - -Syntax: - -```swift -let variableName = operand_A * operand_B -``` - -Example: - -```swift -let x = 5 -let y = x * 2 // y is now 10 -``` - -## Examples - -Below are examples that demonstrate the use of variables and operators in x86ISTMB. - -### Example 1: Simple Arithmetic - -```swift -let a = 10 -let b = 5 -let sum = a + b // sum is now 15 -let product = a * b // product is now 50 -``` - -This example demonstrates declaring variables and performing basic arithmetic operations. - -### Example 2: Reassignment - -```swift -let x = 10 -x = x + 5 // x is now 15 -x = x * 2 // x is now 30 -``` - -In this example, we see how a variable's value can be reassigned using the result of an arithmetic operation involving its current value. - -## Conclusion - -This document provides an introduction to the x86ISTMB programming language, detailing the syntax for declaring variables and using operators for arithmetic and assignment. With its minimalist design, x86ISTMB aims to offer a straightforward approach to programming, focusing on the core concepts of variable manipulation and basic operations. diff --git a/docs/testing.md b/docs/testing.md index 4a18099..d22c3d9 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -5,6 +5,9 @@ By permission (and interest) of Professor Clarkson, we are using the framework A ## Snapshot Testing +> [!NOTE] +> This section is slightly outdated. + To ensure that internal workings are correct between edits, we have a system of snapshot testing. Based on the version in [`Meta.get.version`](../lib/meta.ml), a different suite of input-output tests will be read from the [`test/snapshots`](../test/snapshots/). The snapshot tester will run the interpreter on all the `*.in` files and compare the standard output resulting from the execution to the corresponding `.out` file. diff --git a/docs/user_manual.md b/docs/user_manual.md index a890acf..16bce62 100644 --- a/docs/user_manual.md +++ b/docs/user_manual.md @@ -18,5 +18,5 @@ Here are some other commands. | `make clean` | Removes all build and executable files | | `make docs` | Generates documentation | | `make serve PORT=8003` | Hosts the documentation website at `localhost:8003` | -| `make bisect` | Runs `make test` and outputs the percentage of coverage | +| `make bisect` | Runs `make test` and outputs the percentage of coverage (requires `pup` to be installed) | | `make cloc` | Counts the lines of code in the project. diff --git a/lib/backend/liveliness.ml b/lib/backend/liveliness.ml index 534a567..0cc7745 100644 --- a/lib/backend/liveliness.ml +++ b/lib/backend/liveliness.ml @@ -145,12 +145,11 @@ let apply_rules liveliness analysis cfg bb ir ir_idx ~is_final = let pass work_list liveliness cfg bb = let result = ref false in let analysis = IdMap.find liveliness (Basic_block.id_of bb) in - let ir_view = Basic_block.as_view bb in let ir_count = Basic_block.length_of bb in for rev_i = 1 to ir_count do let i = ir_count - rev_i in result := - apply_rules liveliness analysis cfg bb (ArrayView.get ir_view i) i + apply_rules liveliness analysis cfg bb (Basic_block.get_ir bb i) i ~is_final:(rev_i = 1) || !result done; diff --git a/lib/ir/basic_block.ml b/lib/ir/basic_block.ml index 7aeb656..fe73fc2 100644 --- a/lib/ir/basic_block.ml +++ b/lib/ir/basic_block.ml @@ -4,7 +4,7 @@ let bb_gen = Id.Gen.make () type t = { id : Id.id; - contents : Ir.t BatDynArray.t; + contents : (Ir.t * int) BatDynArray.t; mutable condition : Branch_condition.t; } @@ -15,23 +15,27 @@ let make () = condition = Branch_condition.Never; } -let id_of basic_block = basic_block.id +let id_of bb = bb.id let length_of bb = BatDynArray.length bb.contents let condition_of bb = bb.condition let set_condition bb cond = bb.condition <- cond -let add_ir basic_block ir = BatDynArray.add basic_block.contents ir -let get_ir basic_block index = BatDynArray.get basic_block.contents index -let set_ir basic_block index ir = BatDynArray.set basic_block.contents index ir -let rem_ir basic_block index = BatDynArray.remove_at index basic_block.contents -let to_list basic_block = BatDynArray.to_list basic_block.contents -let equal bb1 bb2 = bb1.id = bb2.id + +let add_ir bb ir = + let i = length_of bb in + BatDynArray.add bb.contents (ir, i) + +let get_ir bb idx = BatDynArray.get bb.contents idx |> fst +let get_orig_idx bb idx = BatDynArray.get bb.contents idx |> snd +let set_ir bb idx ir = BatDynArray.set bb.contents idx (ir, get_orig_idx bb idx) +let rem_ir bb idx = BatDynArray.remove_at idx bb.contents +let to_list bb = BatDynArray.to_list bb.contents |> List.map fst +let equal bb1 bb2 = Id.equal bb1.id bb2.id let hash bb = Id.int_of bb.id |> Int.hash -let as_view bb = Util.ArrayView.from_bat_dyn_arr bb.contents let to_string bb = Printf.sprintf ".L%d:" (id_of bb |> Id.int_of) ^ BatDynArray.fold_left - (fun acc ir -> acc ^ "\n " ^ Ir.to_string ir) + (fun acc (ir, _) -> acc ^ "\n " ^ Ir.to_string ir) "" bb.contents ^ "\n br " ^ Branch_condition.to_string bb.condition diff --git a/lib/ir/basic_block.mli b/lib/ir/basic_block.mli index d13ba29..91f60a3 100644 --- a/lib/ir/basic_block.mli +++ b/lib/ir/basic_block.mli @@ -4,20 +4,20 @@ type t (** [make ()] is a new basic block with a random [id] and a condition of [Never] *) val make : unit -> t -(** [id_of basic_block] is the id of [basic_block]. *) +(** [id_of bb] is the id of [bb]. *) val id_of : t -> Id.id -(** [length_of basic_block] is the number of instructions in [basic_block]. *) +(** [length_of bb] is the number of instructions in [bb]. *) val length_of : t -> int -(** [condition_of basic_block] is the condition associated with branching away - from this basic block. *) +(** [condition_of bb] is the condition associated with branching away from this + basic block. *) val condition_of : t -> Branch_condition.t (** [set_condition bb cond] sets the condition of [bb] to [cond]. *) val set_condition : t -> Branch_condition.t -> unit -(** [add_ir basic_block ir] adds [ir] to the end of [basic_block]. *) +(** [add_ir bb ir] adds [ir] to the end of [bb]. *) val add_ir : t -> Ir.t -> unit (** [get_ir bb idx] is the IR instruction at index [idx] in [bb]. @@ -25,6 +25,12 @@ val add_ir : t -> Ir.t -> unit Requires: [Basic_block.length_of bb > idx]. *) val get_ir : t -> int -> Ir.t +(** [get_orig_idx bb idx] is the original index of the IR instruction at index + [idx] in [bb]; this original index will never changed. + + Requires: [Basic_block.length_of bb > idx]. *) +val get_orig_idx : t -> int -> int + (** [set_ir bb idx ir] replaces the IR instruction at index [idx] in [bb] with [ir]. @@ -37,13 +43,9 @@ val set_ir : t -> int -> Ir.t -> unit Requires: [Basic_block.length_of bb > idx]. *) val rem_ir : t -> int -> unit -(** [to_list basic_block] are the IR operations in [basic_block] in order as a - list. *) +(** [to_list bb] are the IR operations in [bb] in order as a list. *) val to_list : t -> Ir.t list -(** [as_view bb] is a *) -val as_view : t -> Ir.t Util.ArrayView.t - (** [equal bb1 bb2] is whether bb1 and bb2 have the same id. *) val equal : t -> t -> bool diff --git a/lib/ir/passes.ml b/lib/ir/passes.ml index 05f2c2f..173e9b6 100644 --- a/lib/ir/passes.ml +++ b/lib/ir/passes.ml @@ -49,7 +49,8 @@ module DeadCode : Pass.PASS = struct for rev_i = 0 to Basic_block.length_of bb - 1 do let i = length - rev_i - 1 in let live_out = - Liveliness.BasicBlockAnalysis.live_after_instr analysis i + Liveliness.BasicBlockAnalysis.live_after_instr analysis + (Basic_block.get_orig_idx bb i) in match Basic_block.get_ir bb i |> Ir.kill_of with | Some var -> diff --git a/source/README.txt b/source/README.txt new file mode 100644 index 0000000..2f7b435 --- /dev/null +++ b/source/README.txt @@ -0,0 +1 @@ +The syntax in these files is outdated.