Skip to content

Commit 6a04bf7

Browse files
committed
Refactor rvalue processing (improves field access and adds support for array/slice element access, supports more rvalues), new OOMIR instructions, improved sized (u)int handling.
Introduces a two-stage process for MIR assignments (`_X = Rvalue`): 1. Evaluate the Rvalue into a temporary OOMIR operand using a refactored `convert_rvalue_to_operand`. 2. Generate instructions to store this operand into the destination Place using `emit_instructions_to_set_value`. This separates concerns, simplifying Rvalue handling and Place access (fields, indices, etc.) which is now managed by dedicated helpers (`emit_instructions_to_get_on_own`, `emit_instructions_to_set_value`). Also includes support for new OOMIR instructions (`Not`, `Neg`, `ArrayGet`, `Length`) in lower1 and lower2, and improves `isize`/`usize` handling. Also makes a new test `primes` to test this functionality which is passed in both debug and release mode.
1 parent 3079333 commit 6a04bf7

File tree

13 files changed

+1240
-748
lines changed

13 files changed

+1240
-748
lines changed

src/lower1/control_flow.rs

Lines changed: 63 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use super::{
22
operand::convert_operand,
3-
place::{extract_base_and_field, get_place_type, make_jvm_safe, place_to_string},
4-
types::{get_field_name_from_index, mir_int_to_oomir_const, ty_to_oomir_type},
3+
place::{
4+
emit_instructions_to_get_on_own, emit_instructions_to_set_value, make_jvm_safe,
5+
place_to_string,
6+
},
7+
types::mir_int_to_oomir_const,
58
};
69
use crate::oomir;
710

@@ -33,9 +36,56 @@ pub fn convert_basic_block<'tcx>(
3336

3437
// Convert each MIR statement in the block.
3538
for stmt in &bb_data.statements {
36-
if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind {
37-
let dest = place_to_string(place, tcx);
38-
rvalue::handle_rvalue(rvalue, mir, tcx, data_types, place, dest, &mut instructions);
39+
match &stmt.kind {
40+
StatementKind::Assign(box (place, rvalue)) => {
41+
// 1. Evaluate the Rvalue to get the source operand and temp instructions
42+
let (rvalue_instructions, source_operand) = rvalue::convert_rvalue_to_operand(
43+
// Call the refactored function
44+
rvalue, place, // Pass original destination for temp naming hints
45+
mir, tcx, data_types,
46+
);
47+
48+
// Add instructions needed to calculate the Rvalue
49+
instructions.extend(rvalue_instructions);
50+
51+
// 2. Generate instructions to store the computed value into the destination place
52+
let assignment_instructions = emit_instructions_to_set_value(
53+
place, // The actual destination Place
54+
source_operand, // The OOMIR operand holding the value from the Rvalue
55+
tcx,
56+
mir,
57+
data_types,
58+
);
59+
60+
// Add the final assignment instructions (Move, SetField, ArrayStore)
61+
instructions.extend(assignment_instructions);
62+
}
63+
StatementKind::StorageLive(_)
64+
| StatementKind::StorageDead(_)
65+
| StatementKind::Retag(_, _) => {
66+
// no-op, currently
67+
}
68+
StatementKind::Nop => {
69+
// Literally a no-op
70+
}
71+
StatementKind::SetDiscriminant {
72+
place,
73+
variant_index,
74+
} => {
75+
println!(
76+
"Warning: StatementKind::SetDiscriminant NYI. Place: {:?}, Index: {:?}",
77+
place, variant_index
78+
);
79+
// TODO: Need logic similar to emit_instructions_to_set_value but for discriminants
80+
}
81+
StatementKind::Deinit(place) => {
82+
println!("Warning: StatementKind::Deinit NYI. Place: {:?}", place);
83+
// Often a no-op in GC'd languages unless specific resource cleanup needed
84+
}
85+
// Handle other StatementKind variants if necessary
86+
_ => {
87+
println!("Warning: Unhandled StatementKind: {:?}", stmt.kind);
88+
}
3989
}
4090
}
4191

@@ -145,7 +195,6 @@ pub fn convert_basic_block<'tcx>(
145195
unwind: _,
146196
} => {
147197
let condition_operand: oomir::Operand;
148-
let temp_condition_value_var; // To store the name if GetField is used
149198

150199
// Check if the condition operand is a direct use of a place (Copy or Move)
151200
let condition_place_opt = match cond {
@@ -155,76 +204,14 @@ pub fn convert_basic_block<'tcx>(
155204

156205
if let Some(place) = condition_place_opt {
157206
// Now, check if this place has a field projection
158-
if let Some((base_place, field_index, field_mir_ty)) =
159-
extract_base_and_field(tcx, place)
160-
{
161-
// It's a field access (e.g., _7.1)! Generate GetField
162-
let object_var_name = place_to_string(&base_place, tcx); // e.g., "_7"
163-
let owner_oomir_type = get_place_type(&base_place, mir, tcx, data_types);
164-
let owner_class_name = match &owner_oomir_type {
165-
oomir::Type::Class(name) => name.clone(),
166-
oomir::Type::Reference(inner) => {
167-
// Handle if base is &Tuple
168-
if let oomir::Type::Class(name) = inner.as_ref() {
169-
name.clone()
170-
} else {
171-
panic!(
172-
"Assert cond field source's inner type is not a Class: {:?}",
173-
inner
174-
);
175-
}
176-
}
177-
_ => panic!(
178-
"Assert cond field source base '{}' is not a class type: {:?}",
179-
object_var_name, owner_oomir_type
180-
),
181-
};
182-
183-
let field_name = match get_field_name_from_index(
184-
&owner_class_name,
185-
field_index.index(),
186-
data_types,
187-
) {
188-
Ok(name) => name,
189-
Err(e) => {
190-
panic!("Error getting field name for assert condition: {}", e)
191-
}
192-
};
193-
194-
let field_oomir_type = ty_to_oomir_type(field_mir_ty, tcx, data_types);
195-
196-
// Generate a temporary variable to hold the result of GetField
197-
let temp_dest = format!("assert_cond_val_{}", bb.index());
198-
instructions.push(oomir::Instruction::GetField {
199-
dest: temp_dest.clone(),
200-
object_var: object_var_name,
201-
field_name,
202-
field_ty: field_oomir_type.clone(),
203-
owner_class: owner_class_name,
204-
});
205-
206-
// Use the temporary variable as the condition operand
207-
condition_operand = oomir::Operand::Variable {
208-
name: temp_dest.clone(),
209-
ty: field_oomir_type,
210-
};
211-
temp_condition_value_var = Some(temp_dest); // Store for potential negation
212-
213-
println!(
214-
// Log the GetField generation
215-
"Info: Assert condition uses field access {:?}. Emitted GetField to temp '{}'",
216-
place_to_string(place, tcx),
217-
temp_condition_value_var.as_ref().unwrap()
218-
);
219-
} else {
220-
// It's a simple place (e.g., _3), convert normally
221-
println!(
222-
// Log simple case
223-
"Info: Assert condition uses simple place {:?}",
224-
place_to_string(place, tcx)
225-
);
226-
condition_operand = convert_operand(cond, tcx, mir, data_types);
227-
}
207+
let (temp_dest, instrs, field_oomir_type) =
208+
emit_instructions_to_get_on_own(place, tcx, mir, data_types);
209+
instructions.extend(instrs);
210+
// Use the temporary variable as the condition operand
211+
condition_operand = oomir::Operand::Variable {
212+
name: temp_dest.clone(),
213+
ty: field_oomir_type,
214+
};
228215
} else {
229216
println!(
230217
// Log constant case

0 commit comments

Comments
 (0)