ruka_mir/instr.rs
1use crate::{MirAggregateArg, MirCallArg, MirFuncId, MirIntrinsic, MirLocalId};
2
3/// Source position metadata captured for MIR instructions.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct MirSourcePos {
6 /// Source file identifier assigned during parsing.
7 pub file_id: u32,
8 /// 1-based source line number.
9 pub line: u32,
10 /// 1-based source column number.
11 pub column: u32,
12}
13
14/// MIR instruction set used by lowering and codegen.
15///
16/// This is the canonical instruction representation stored in blocks.
17#[derive(Debug, Clone)]
18pub enum MirInstr {
19 /// Write unit constant into `dst`.
20 ConstUnit {
21 /// Destination local receiving the unit constant.
22 /// Destination local receiving the result.
23 dst: MirLocalId,
24 },
25 /// Write integer constant into `dst`.
26 ConstInt {
27 /// Destination local receiving the integer constant.
28 /// Destination local receiving the result.
29 dst: MirLocalId,
30 /// Constant integer value.
31 value: i64,
32 },
33 /// Write floating-point constant into `dst`.
34 ConstFloat {
35 /// Destination local receiving the floating-point constant.
36 dst: MirLocalId,
37 /// Constant floating-point value.
38 value: f64,
39 },
40 /// Write string constant into `dst`.
41 ConstString {
42 /// Destination local receiving the string constant.
43 /// Destination local receiving the result.
44 dst: MirLocalId,
45 /// Constant string contents.
46 value: String,
47 },
48 /// Write boolean constant into `dst`.
49 ConstBool {
50 /// Destination local receiving the boolean constant.
51 /// Destination local receiving the result.
52 dst: MirLocalId,
53 /// Constant boolean value.
54 value: bool,
55 },
56 /// Write null pointer constant into `dst`.
57 ConstNull {
58 /// Destination local receiving the null pointer value.
59 /// Destination local receiving the result.
60 dst: MirLocalId,
61 },
62 /// Allocate pointer payload and wrap in nullable handle.
63 PointerNew {
64 /// Source local providing the pointee value.
65 /// Source local supplying the stored value.
66 src: MirLocalId,
67 /// Destination local receiving the pointer handle.
68 /// Destination local receiving the result.
69 dst: MirLocalId,
70 },
71 /// Build array literal from `items` into `dst`.
72 MakeArray {
73 /// Aggregate arguments used to build the array.
74 items: Vec<MirAggregateArg>,
75 /// Destination local receiving the result.
76 dst: MirLocalId,
77 /// Optional source position for the allocation site.
78 source_pos: Option<MirSourcePos>,
79 },
80 /// Build tuple literal from `items` into `dst`.
81 MakeTuple {
82 /// Aggregate arguments used to build the tuple.
83 items: Vec<MirAggregateArg>,
84 /// Destination local receiving the result.
85 dst: MirLocalId,
86 /// Optional source position for the allocation site.
87 source_pos: Option<MirSourcePos>,
88 },
89 /// Build struct literal value.
90 MakeStruct {
91 /// Struct constructor name to instantiate.
92 name: String,
93 /// Field values keyed by field name.
94 fields: Vec<(String, MirLocalId)>,
95 /// Destination local receiving the result.
96 dst: MirLocalId,
97 /// Optional source position for the allocation site.
98 source_pos: Option<MirSourcePos>,
99 },
100 /// Build enum literal value.
101 MakeEnum {
102 /// Enum constructor name to instantiate.
103 enum_name: String,
104 /// Variant constructor name to instantiate.
105 variant: String,
106 /// Variant payload argument values.
107 payload: Vec<MirAggregateArg>,
108 /// Destination local receiving the result.
109 dst: MirLocalId,
110 /// Optional source position for the allocation site.
111 source_pos: Option<MirSourcePos>,
112 },
113 /// Read field from struct value.
114 ReadField {
115 /// Base local supplying the aggregate value.
116 base: MirLocalId,
117 /// Field name being read from the aggregate.
118 field: String,
119 /// Destination local receiving the result.
120 dst: MirLocalId,
121 },
122 /// Borrow struct/tuple field read-only.
123 FieldBorrowRo {
124 /// Base local supplying the aggregate value.
125 base: MirLocalId,
126 /// Field name being borrowed from the aggregate.
127 field: String,
128 /// Destination local receiving the result.
129 dst: MirLocalId,
130 },
131 /// Borrow struct/tuple field mutably.
132 FieldBorrowMut {
133 /// Base local supplying the aggregate value.
134 base: MirLocalId,
135 /// Field name being borrowed from the aggregate.
136 field: String,
137 /// Destination local receiving the result.
138 dst: MirLocalId,
139 },
140 /// Test whether enum value currently stores a specific variant.
141 EnumIsVariant {
142 /// Enum local being inspected.
143 value: MirLocalId,
144 /// Enum constructor name being tested.
145 enum_name: String,
146 /// Variant constructor name being tested.
147 variant: String,
148 /// Number of payload fields declared on the tested variant.
149 payload_len: usize,
150 /// Destination local receiving the result.
151 dst: MirLocalId,
152 },
153 /// Extract one enum payload field by variant/index.
154 EnumGetField {
155 /// Enum local being inspected.
156 value: MirLocalId,
157 /// Enum constructor name being extracted from.
158 enum_name: String,
159 /// Variant constructor name being extracted from.
160 variant: String,
161 /// Payload field index within the variant.
162 index: usize,
163 /// Destination local receiving the extracted field.
164 dst: MirLocalId,
165 },
166 /// Logical copy from `src` into `dst`.
167 Copy {
168 /// Source local being copied.
169 /// Source local supplying the stored value.
170 src: MirLocalId,
171 /// Destination local receiving the copied value.
172 dst: MirLocalId,
173 },
174 /// Ownership move from `src` into `dst`.
175 Move {
176 /// Source local being moved.
177 /// Source local supplying the stored value.
178 src: MirLocalId,
179 /// Destination local receiving the moved value.
180 dst: MirLocalId,
181 },
182 /// Assign local storage from `src` into `dst`.
183 AssignLocal {
184 /// Source local being assigned from.
185 /// Source local supplying the stored value.
186 src: MirLocalId,
187 /// Destination local being assigned to.
188 dst: MirLocalId,
189 },
190 /// Store value through mutable reference local.
191 StoreRef {
192 /// Source local supplying the stored value.
193 src: MirLocalId,
194 /// Destination mutable reference local.
195 dst_ref: MirLocalId,
196 },
197 /// Assign through a struct field path rooted at `base`.
198 AssignFieldPath {
199 /// Base local supplying the aggregate value.
200 base: MirLocalId,
201 /// Field path traversed from the base local.
202 fields: Vec<String>,
203 /// Source local supplying the stored value.
204 src: MirLocalId,
205 },
206 /// Release one retained heap ownership for `local`.
207 ///
208 /// Lowering defines this instruction now so later ownership passes can
209 /// place releases explicitly without changing MIR shape again.
210 ReleaseHeap {
211 /// Local whose heap ownership should be released.
212 local: MirLocalId,
213 },
214 /// Internal function call.
215 Call {
216 /// Function id of the callee.
217 callee: MirFuncId,
218 /// Positional call arguments.
219 args: Vec<MirCallArg>,
220 /// Destination local receiving the result.
221 dst: MirLocalId,
222 },
223 /// Extern/runtime symbol call.
224 CallExtern {
225 /// Canonical symbol name of the extern/runtime function.
226 symbol: String,
227 /// Positional call arguments.
228 args: Vec<MirCallArg>,
229 /// Destination local receiving the result.
230 dst: MirLocalId,
231 },
232 /// Builtin intrinsic call.
233 CallIntrinsic {
234 /// Intrinsic to invoke.
235 intrinsic: MirIntrinsic,
236 /// Positional call arguments.
237 args: Vec<MirCallArg>,
238 /// Destination local receiving the result.
239 dst: MirLocalId,
240 /// Optional source position for the call site.
241 source_pos: Option<MirSourcePos>,
242 },
243 /// Collection length query.
244 CollectionLen {
245 /// Collection local being queried or borrowed from.
246 collection: MirLocalId,
247 /// Destination local receiving the result.
248 dst: MirLocalId,
249 },
250 /// Borrow collection element read-only.
251 IndexBorrowRo {
252 /// Collection local being queried or borrowed from.
253 collection: MirLocalId,
254 /// Index local selecting an element.
255 index: MirLocalId,
256 /// Destination local receiving the result.
257 dst: MirLocalId,
258 },
259 /// Borrow collection element mutably.
260 IndexBorrowMut {
261 /// Collection local being queried or borrowed from.
262 collection: MirLocalId,
263 /// Index local selecting an element.
264 index: MirLocalId,
265 /// Destination local receiving the result.
266 dst: MirLocalId,
267 },
268 /// Borrow collection range read-only as a slice.
269 SliceBorrowRo {
270 /// Collection local being queried or borrowed from.
271 collection: MirLocalId,
272 /// Optional start bound local.
273 start: Option<MirLocalId>,
274 /// Optional end bound local.
275 end: Option<MirLocalId>,
276 /// Destination local receiving the result.
277 dst: MirLocalId,
278 },
279 /// Borrow collection range mutably as a slice.
280 SliceBorrowMut {
281 /// Collection local being queried or borrowed from.
282 collection: MirLocalId,
283 /// Optional start bound local.
284 start: Option<MirLocalId>,
285 /// Optional end bound local.
286 end: Option<MirLocalId>,
287 /// Destination local receiving the result.
288 dst: MirLocalId,
289 },
290 /// Test whether nullable pointer is non-null.
291 PointerIsSome {
292 /// Pointer local being inspected or borrowed from.
293 pointer: MirLocalId,
294 /// Destination local receiving the result.
295 dst: MirLocalId,
296 },
297 /// Borrow nullable pointer payload read-only.
298 PointerBorrowRo {
299 /// Pointer local being inspected or borrowed from.
300 pointer: MirLocalId,
301 /// Destination local receiving the result.
302 dst: MirLocalId,
303 },
304 /// Borrow nullable pointer payload mutably.
305 PointerBorrowMut {
306 /// Pointer local being inspected or borrowed from.
307 pointer: MirLocalId,
308 /// Destination local receiving the result.
309 dst: MirLocalId,
310 },
311 /// Copy value from a reference local.
312 DerefCopy {
313 /// Source reference local being dereferenced.
314 src: MirLocalId,
315 /// Destination local receiving the copied value.
316 dst: MirLocalId,
317 },
318 /// Numeric value cast to another scalar numeric type.
319 NumCast {
320 /// Source local supplying the input value.
321 src: MirLocalId,
322 /// Destination local receiving the cast result.
323 dst: MirLocalId,
324 },
325 /// Checked integer cast that traps when value does not fit destination range.
326 CheckedIntCast {
327 /// Source local supplying the input value.
328 src: MirLocalId,
329 /// Destination local receiving the cast result.
330 dst: MirLocalId,
331 },
332 /// Integer less-than comparison.
333 IntLt {
334 /// Left-hand operand local.
335 lhs: MirLocalId,
336 /// Right-hand operand local.
337 rhs: MirLocalId,
338 /// Destination local receiving the result.
339 dst: MirLocalId,
340 },
341 /// Integer greater-than comparison.
342 IntGt {
343 /// Left-hand operand local.
344 lhs: MirLocalId,
345 /// Right-hand operand local.
346 rhs: MirLocalId,
347 /// Destination local receiving the result.
348 dst: MirLocalId,
349 },
350 /// Integer less-than-or-equal comparison.
351 IntLtEq {
352 /// Left-hand operand local.
353 lhs: MirLocalId,
354 /// Right-hand operand local.
355 rhs: MirLocalId,
356 /// Destination local receiving the result.
357 dst: MirLocalId,
358 },
359 /// Integer greater-than-or-equal comparison.
360 IntGtEq {
361 /// Left-hand operand local.
362 lhs: MirLocalId,
363 /// Right-hand operand local.
364 rhs: MirLocalId,
365 /// Destination local receiving the result.
366 dst: MirLocalId,
367 },
368 /// Integer equality comparison.
369 IntEq {
370 /// Left-hand operand local.
371 lhs: MirLocalId,
372 /// Right-hand operand local.
373 rhs: MirLocalId,
374 /// Destination local receiving the result.
375 dst: MirLocalId,
376 },
377 /// Integer inequality comparison.
378 IntNeq {
379 /// Left-hand operand local.
380 lhs: MirLocalId,
381 /// Right-hand operand local.
382 rhs: MirLocalId,
383 /// Destination local receiving the result.
384 dst: MirLocalId,
385 },
386 /// Integer addition.
387 IntAdd {
388 /// Left-hand operand local.
389 lhs: MirLocalId,
390 /// Right-hand operand local.
391 rhs: MirLocalId,
392 /// Destination local receiving the result.
393 dst: MirLocalId,
394 },
395 /// Integer subtraction.
396 IntSub {
397 /// Left-hand operand local.
398 lhs: MirLocalId,
399 /// Right-hand operand local.
400 rhs: MirLocalId,
401 /// Destination local receiving the result.
402 dst: MirLocalId,
403 },
404 /// Integer multiplication.
405 IntMul {
406 /// Left-hand operand local.
407 lhs: MirLocalId,
408 /// Right-hand operand local.
409 rhs: MirLocalId,
410 /// Destination local receiving the result.
411 dst: MirLocalId,
412 },
413 /// Integer division.
414 IntDiv {
415 /// Left-hand operand local.
416 lhs: MirLocalId,
417 /// Right-hand operand local.
418 rhs: MirLocalId,
419 /// Destination local receiving the result.
420 dst: MirLocalId,
421 },
422 /// Integer modulo.
423 IntMod {
424 /// Left-hand operand local.
425 lhs: MirLocalId,
426 /// Right-hand operand local.
427 rhs: MirLocalId,
428 /// Destination local receiving the result.
429 dst: MirLocalId,
430 },
431}
432
433/// Structured lowering helper form.
434///
435/// This is used while constructing CFG and is not stored as the
436/// canonical body representation in [`MirFunction`](crate::MirFunction).
437#[derive(Debug, Clone)]
438pub enum MirStmt {
439 /// Plain instruction embedded in structured lowering output.
440 Instr(MirInstr),
441 /// Structured conditional used during CFG construction.
442 If {
443 /// Local id holding the branch condition.
444 cond: MirLocalId,
445 /// Structured statements executed on the then path.
446 then_body: Vec<MirStmt>,
447 /// Structured statements executed on the else path.
448 else_body: Vec<MirStmt>,
449 },
450 /// Structured loop used during CFG construction.
451 While {
452 /// Loop-carried parameter locals.
453 loop_params: Vec<MirLocalId>,
454 /// Initial arguments supplied to the loop.
455 init_args: Vec<MirLocalId>,
456 /// Structured statements computing the loop condition.
457 cond_body: Vec<MirStmt>,
458 /// Local id holding the branch condition.
459 cond: MirLocalId,
460 /// Structured statements in the loop body.
461 body: Vec<MirStmt>,
462 /// Updated loop arguments supplied to the next iteration.
463 step_args: Vec<MirLocalId>,
464 },
465 /// Structured return used during CFG construction.
466 Return {
467 /// Local id returned from the surrounding function.
468 value: MirLocalId,
469 },
470}