-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mir_find_adt
, mir_struct_value
, and friends
This adds supports for MIR struct types, struct values, and ADT definitions in the MIR backend, piggybacking on the existing support for struct `SetupValue`s. MIR structs are a fair bit more involved than LLVM structs: * Unlike in the LLVM backend, where structs are only identified up to their field types, MIR structs each have a distinct name. This means that two structs with the same field types can still be distinct, and SAW must be aware of this difference. As a result, the `XSetupStruct` instance for `MIR` uses an `Adt` (algebraic data type) to encode the information about the struct name, as well as the types of its fields. * Building an ADT is somewhat tricky, since each monomorphic instantiation of a struct in MIR has its own distinct, autogenerated identifier. The new `mir_find_adt` command allows users to look up these autogenerated names by supplying a human-readable name for the struct, along with the types used to instantiate the type parameters of the struct. * The `mir_adt` function builds a struct type from an ADT, and the `mir_struct_value` function builds a struct value from an ADT and the field values. These behave much like `llvm_struct` and `llvm_struct_value` in the LLVM backend. Note that we call it "`mir_adt`" rather than "`mir_struct`" to be forward-compatible with enums, another type of ADT that we will add support for in a future patch. Some careful handling of `#[repr(transparent)]` structs is required, as they have a different `TypeShape` than other structs. See the `TransparentShape` code added in this patch, as well as the `test_mir_verify_struct` test case which includes a transparent struct example. This checks off one box in #1859.
- Loading branch information
1 parent
4c0985c
commit 04b0de5
Showing
36 changed files
with
1,134 additions
and
229 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
all: test.linked-mir.json | ||
|
||
test.linked-mir.json: test.rs | ||
saw-rustc $< | ||
$(MAKE) remove-unused-build-artifacts | ||
|
||
.PHONY: remove-unused-build-artifacts | ||
remove-unused-build-artifacts: | ||
rm -f test libtest.mir libtest.rlib | ||
|
||
.PHONY: clean | ||
clean: remove-unused-build-artifacts | ||
rm -f test.linked-mir.json |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
pub struct S1 { | ||
pub x1: u32, | ||
pub y1: u32, | ||
} | ||
|
||
pub fn f1(s: S1) -> S1 { | ||
S1 { | ||
x1: s.y1.wrapping_add(1), | ||
y1: s.x1.wrapping_add(2), | ||
} | ||
} | ||
|
||
pub fn g(s: &S1) -> S1 { | ||
S1 { | ||
x1: s.y1.wrapping_add(1), | ||
y1: s.x1.wrapping_add(2), | ||
} | ||
} | ||
|
||
pub fn h(s: &mut S1) { | ||
let x1 = s.x1; | ||
let y1 = s.y1; | ||
s.x1 = y1.wrapping_add(1); | ||
s.y1 = x1.wrapping_add(2); | ||
} | ||
|
||
// Polymorphism | ||
|
||
pub struct S2<A, B> { | ||
pub x2: A, | ||
pub y2: B, | ||
} | ||
|
||
pub fn f2(s: S2<u32, u32>) -> S2<u32, u32> { | ||
S2 { | ||
x2: s.y2.wrapping_add(1), | ||
y2: s.x2.wrapping_add(2), | ||
} | ||
} | ||
|
||
pub struct S3(u32, u32); | ||
|
||
pub fn f3(s: S3) -> S3 { | ||
match s { | ||
S3(x3, y3) => S3(y3.wrapping_add(1), x3.wrapping_add(2)), | ||
} | ||
} | ||
|
||
#[repr(transparent)] | ||
pub struct S4(u32); | ||
|
||
pub fn f4(s: S4) -> S4 { | ||
match s { | ||
S4(x4) => S4(x4.wrapping_add(2)), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
enable_experimental; | ||
|
||
m <- mir_load_module "test.linked-mir.json"; | ||
|
||
let s1_adt = mir_find_adt m "test::S1" []; | ||
let s2_adt = mir_find_adt m "test::S2" [mir_u32, mir_u32]; | ||
let s3_adt = mir_find_adt m "test::S3" []; | ||
let s4_adt = mir_find_adt m "test::S4" []; | ||
|
||
let f_spec adt = do { | ||
x1 <- mir_fresh_var "x1" mir_u32; | ||
y1 <- mir_fresh_var "y1" mir_u32; | ||
let s = mir_struct_value | ||
adt | ||
[ mir_term x1 | ||
, mir_term y1 | ||
]; | ||
|
||
mir_execute_func [s]; | ||
|
||
let s' = mir_struct_value | ||
adt | ||
[ mir_term {{ y1 + 1 }} | ||
, mir_term {{ x1 + 2 }} | ||
]; | ||
mir_return s'; | ||
}; | ||
|
||
|
||
let f1_spec = f_spec s1_adt; | ||
let f2_spec = f_spec s2_adt; | ||
let f3_spec = f_spec s3_adt; | ||
|
||
let f4_spec = do { | ||
x4 <- mir_fresh_var "x4" mir_u32; | ||
let s = mir_struct_value s4_adt [mir_term x4]; | ||
|
||
mir_execute_func [s]; | ||
|
||
let s' = mir_struct_value s4_adt [mir_term {{ x4 + 2 }}]; | ||
mir_return s'; | ||
}; | ||
|
||
let g_spec = do { | ||
s_ptr <- mir_alloc (mir_adt s1_adt); | ||
x1 <- mir_fresh_var "x1" mir_u32; | ||
y1 <- mir_fresh_var "y1" mir_u32; | ||
let s = mir_struct_value | ||
s1_adt | ||
[ mir_term x1 | ||
, mir_term y1 | ||
]; | ||
mir_points_to s_ptr s; | ||
|
||
mir_execute_func [s_ptr]; | ||
|
||
let s' = mir_struct_value | ||
s1_adt | ||
[ mir_term {{ y1 + 1 }} | ||
, mir_term {{ x1 + 2 }} | ||
]; | ||
mir_return s'; | ||
}; | ||
|
||
let h_spec = do { | ||
s_ptr <- mir_alloc_mut (mir_adt s1_adt); | ||
x1 <- mir_fresh_var "x1" mir_u32; | ||
y1 <- mir_fresh_var "y1" mir_u32; | ||
let s = mir_struct_value | ||
s1_adt | ||
[ mir_term x1 | ||
, mir_term y1 | ||
]; | ||
mir_points_to s_ptr s; | ||
|
||
mir_execute_func [s_ptr]; | ||
|
||
let s' = mir_struct_value | ||
s1_adt | ||
[ mir_term {{ y1 + 1 }} | ||
, mir_term {{ x1 + 2 }} | ||
]; | ||
mir_points_to s_ptr s'; | ||
}; | ||
|
||
mir_verify m "test::f1" [] false f1_spec z3; | ||
mir_verify m "test::f2" [] false f2_spec z3; | ||
mir_verify m "test::f3" [] false f3_spec z3; | ||
mir_verify m "test::f4" [] false f4_spec z3; | ||
mir_verify m "test::g" [] false g_spec z3; | ||
mir_verify m "test::h" [] false h_spec z3; | ||
|
||
fails ( | ||
mir_verify m "test::f1" [] false f2_spec z3 | ||
); | ||
fails ( | ||
mir_verify m "test::f2" [] false f1_spec z3 | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
set -e | ||
|
||
$SAW test.saw |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.