Skip to main content

koopa/ir/
values.rs

1//! Definitions of Koopa IR values, including constants and instructions.
2
3use crate::ir::entities::{BasicBlock, Function, Value, ValueData, ValueKind};
4use crate::ir::types::Type;
5use std::fmt;
6
7/// Integer constant.
8#[derive(Clone, Debug)]
9pub struct Integer {
10  value: i32,
11}
12
13impl Integer {
14  pub(in crate::ir) fn new_data(value: i32) -> ValueData {
15    ValueData::new(Type::get_i32(), ValueKind::Integer(Self { value }))
16  }
17
18  /// Returns the integer value.
19  pub fn value(&self) -> i32 {
20    self.value
21  }
22
23  /// Returns a mutable reference to the integer value.
24  pub fn value_mut(&mut self) -> &mut i32 {
25    &mut self.value
26  }
27}
28
29/// Zero initializer.
30#[derive(Clone, Debug)]
31pub struct ZeroInit;
32
33impl ZeroInit {
34  pub(in crate::ir) fn new_data(ty: Type) -> ValueData {
35    ValueData::new(ty, ValueKind::ZeroInit(Self))
36  }
37}
38
39/// Undefined value.
40#[derive(Clone, Debug)]
41pub struct Undef;
42
43impl Undef {
44  pub(in crate::ir) fn new_data(ty: Type) -> ValueData {
45    ValueData::new(ty, ValueKind::Undef(Self))
46  }
47}
48
49/// Aggregate constant.
50#[derive(Clone, Debug)]
51pub struct Aggregate {
52  elems: Vec<Value>,
53}
54
55impl Aggregate {
56  pub(in crate::ir) fn new_data(elems: Vec<Value>, ty: Type) -> ValueData {
57    ValueData::new(ty, ValueKind::Aggregate(Self { elems }))
58  }
59
60  /// Returns a reference to the aggregate elements.
61  pub fn elems(&self) -> &[Value] {
62    &self.elems
63  }
64
65  /// Returns a mutable reference to the aggregate elements.
66  pub fn elems_mut(&mut self) -> &mut Vec<Value> {
67    &mut self.elems
68  }
69}
70
71/// Function argument reference.
72#[derive(Clone, Debug)]
73pub struct FuncArgRef {
74  index: usize,
75}
76
77impl FuncArgRef {
78  pub(in crate::ir) fn new_data(index: usize, ty: Type) -> ValueData {
79    ValueData::new(ty, ValueKind::FuncArgRef(Self { index }))
80  }
81
82  /// Returns the argument index.
83  pub fn index(&self) -> usize {
84    self.index
85  }
86
87  /// Returns a mutable reference to the argument index.
88  pub fn index_mut(&mut self) -> &mut usize {
89    &mut self.index
90  }
91}
92
93/// Basic block argument reference.
94#[derive(Clone, Debug)]
95pub struct BlockArgRef {
96  index: usize,
97}
98
99impl BlockArgRef {
100  pub(in crate::ir) fn new_data(index: usize, ty: Type) -> ValueData {
101    ValueData::new(ty, ValueKind::BlockArgRef(Self { index }))
102  }
103
104  /// Returns the argument index.
105  pub fn index(&self) -> usize {
106    self.index
107  }
108
109  /// Returns a mutable reference to the argument index.
110  pub fn index_mut(&mut self) -> &mut usize {
111    &mut self.index
112  }
113}
114
115/// Local memory allocation.
116#[derive(Clone, Debug)]
117pub struct Alloc;
118
119impl Alloc {
120  pub(in crate::ir) fn new_data(ty: Type) -> ValueData {
121    assert!(!ty.is_unit(), "`ty` can not be unit");
122    ValueData::new(ty, ValueKind::Alloc(Self))
123  }
124}
125
126/// Global memory allocation.
127#[derive(Clone, Debug)]
128pub struct GlobalAlloc {
129  init: Value,
130}
131
132impl GlobalAlloc {
133  pub(in crate::ir) fn new_data(init: Value, ty: Type) -> ValueData {
134    ValueData::new(ty, ValueKind::GlobalAlloc(Self { init }))
135  }
136
137  /// Returns the initializer.
138  pub fn init(&self) -> Value {
139    self.init
140  }
141
142  /// Returns a mutable reference to the initializer.
143  pub fn init_mut(&mut self) -> &mut Value {
144    &mut self.init
145  }
146}
147
148/// Memory load.
149#[derive(Clone, Debug)]
150pub struct Load {
151  src: Value,
152}
153
154impl Load {
155  pub(in crate::ir) fn new_data(src: Value, ty: Type) -> ValueData {
156    ValueData::new(ty, ValueKind::Load(Self { src }))
157  }
158
159  /// Returns the source memory location.
160  pub fn src(&self) -> Value {
161    self.src
162  }
163
164  /// Returns a mutable reference to the source memory location.
165  pub fn src_mut(&mut self) -> &mut Value {
166    &mut self.src
167  }
168}
169
170/// Memory store.
171#[derive(Clone, Debug)]
172pub struct Store {
173  value: Value,
174  dest: Value,
175}
176
177impl Store {
178  pub(in crate::ir) fn new_data(value: Value, dest: Value) -> ValueData {
179    ValueData::new(Type::get_unit(), ValueKind::Store(Self { value, dest }))
180  }
181
182  /// Returns the value of the memory store.
183  pub fn value(&self) -> Value {
184    self.value
185  }
186
187  /// Returns a mutable reference to the value of the memory store.
188  pub fn value_mut(&mut self) -> &mut Value {
189    &mut self.value
190  }
191
192  /// Returns the destination of the memory store.
193  pub fn dest(&self) -> Value {
194    self.dest
195  }
196
197  /// Returns a mutable reference to the destination of the memory store.
198  pub fn dest_mut(&mut self) -> &mut Value {
199    &mut self.dest
200  }
201}
202
203/// Pointer calculation.
204#[derive(Clone, Debug)]
205pub struct GetPtr {
206  src: Value,
207  index: Value,
208}
209
210impl GetPtr {
211  pub(in crate::ir) fn new_data(src: Value, index: Value, ty: Type) -> ValueData {
212    ValueData::new(ty, ValueKind::GetPtr(Self { src, index }))
213  }
214
215  /// Returns the source memory location.
216  pub fn src(&self) -> Value {
217    self.src
218  }
219
220  /// Returns a mutable reference to the source memory location.
221  pub fn src_mut(&mut self) -> &mut Value {
222    &mut self.src
223  }
224
225  /// Returns the index of pointer calculation.
226  pub fn index(&self) -> Value {
227    self.index
228  }
229
230  /// Returns a mutable reference to the index of pointer calculation.
231  pub fn index_mut(&mut self) -> &mut Value {
232    &mut self.index
233  }
234}
235
236/// Element pointer calculation.
237#[derive(Clone, Debug)]
238pub struct GetElemPtr {
239  src: Value,
240  index: Value,
241}
242
243impl GetElemPtr {
244  pub(in crate::ir) fn new_data(src: Value, index: Value, ty: Type) -> ValueData {
245    ValueData::new(ty, ValueKind::GetElemPtr(Self { src, index }))
246  }
247
248  /// Returns the source memory location.
249  pub fn src(&self) -> Value {
250    self.src
251  }
252
253  /// Returns a mutable reference to the source memory location.
254  pub fn src_mut(&mut self) -> &mut Value {
255    &mut self.src
256  }
257
258  /// Returns the index of element pointer calculation.
259  pub fn index(&self) -> Value {
260    self.index
261  }
262
263  /// Returns a mutable reference to the index of element pointer calculation.
264  pub fn index_mut(&mut self) -> &mut Value {
265    &mut self.index
266  }
267}
268
269/// Binary operation.
270#[derive(Clone, Debug)]
271pub struct Binary {
272  op: BinaryOp,
273  lhs: Value,
274  rhs: Value,
275}
276
277impl Binary {
278  pub(in crate::ir) fn new_data(op: BinaryOp, lhs: Value, rhs: Value, ty: Type) -> ValueData {
279    ValueData::new(ty, ValueKind::Binary(Self { op, lhs, rhs }))
280  }
281
282  /// Returns the binary operator.
283  pub fn op(&self) -> BinaryOp {
284    self.op
285  }
286
287  /// Returns a mutable reference to the binary operator.
288  pub fn op_mut(&mut self) -> &mut BinaryOp {
289    &mut self.op
290  }
291
292  /// Returns the left-hand side use.
293  pub fn lhs(&self) -> Value {
294    self.lhs
295  }
296
297  /// Returns a mutable reference to the left-hand side use.
298  pub fn lhs_mut(&mut self) -> &mut Value {
299    &mut self.lhs
300  }
301
302  /// Returns the right-hand side use.
303  pub fn rhs(&self) -> Value {
304    self.rhs
305  }
306
307  /// Returns a mutable reference to the right-hand side use.
308  pub fn rhs_mut(&mut self) -> &mut Value {
309    &mut self.rhs
310  }
311}
312
313/// Supported binary operators.
314#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
315pub enum BinaryOp {
316  /// Not equal to.
317  NotEq,
318  /// Equal to.
319  Eq,
320  /// Greater than.
321  Gt,
322  /// Less than.
323  Lt,
324  /// Greater than or equal to.
325  Ge,
326  /// Less than or equal to.
327  Le,
328  /// Addition.
329  Add,
330  /// Subtraction.
331  Sub,
332  /// Multiplication.
333  Mul,
334  /// Division.
335  Div,
336  /// Modulo.
337  Mod,
338  /// Bitwise AND.
339  And,
340  /// Bitwise OR.
341  Or,
342  /// Bitwise XOR.
343  Xor,
344  /// Shift left logical.
345  Shl,
346  /// Shift right logical.
347  Shr,
348  /// Shift right arithmetic.
349  Sar,
350}
351
352impl fmt::Display for BinaryOp {
353  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
354    match self {
355      BinaryOp::NotEq => f.write_str("ne"),
356      BinaryOp::Eq => f.write_str("eq"),
357      BinaryOp::Gt => f.write_str("gt"),
358      BinaryOp::Lt => f.write_str("lt"),
359      BinaryOp::Ge => f.write_str("ge"),
360      BinaryOp::Le => f.write_str("le"),
361      BinaryOp::Add => f.write_str("add"),
362      BinaryOp::Sub => f.write_str("sub"),
363      BinaryOp::Mul => f.write_str("mul"),
364      BinaryOp::Div => f.write_str("div"),
365      BinaryOp::Mod => f.write_str("mod"),
366      BinaryOp::And => f.write_str("and"),
367      BinaryOp::Or => f.write_str("or"),
368      BinaryOp::Xor => f.write_str("xor"),
369      BinaryOp::Shl => f.write_str("shl"),
370      BinaryOp::Shr => f.write_str("shr"),
371      BinaryOp::Sar => f.write_str("sar"),
372    }
373  }
374}
375
376/// Conditional branch.
377#[derive(Clone, Debug)]
378pub struct Branch {
379  cond: Value,
380  true_bb: BasicBlock,
381  false_bb: BasicBlock,
382  true_args: Vec<Value>,
383  false_args: Vec<Value>,
384}
385
386impl Branch {
387  pub(in crate::ir) fn new_data(
388    cond: Value,
389    true_bb: BasicBlock,
390    false_bb: BasicBlock,
391  ) -> ValueData {
392    ValueData::new(
393      Type::get_unit(),
394      ValueKind::Branch(Self {
395        cond,
396        true_bb,
397        false_bb,
398        true_args: Vec::new(),
399        false_args: Vec::new(),
400      }),
401    )
402  }
403
404  pub(in crate::ir) fn with_args(
405    cond: Value,
406    true_bb: BasicBlock,
407    false_bb: BasicBlock,
408    true_args: Vec<Value>,
409    false_args: Vec<Value>,
410  ) -> ValueData {
411    ValueData::new(
412      Type::get_unit(),
413      ValueKind::Branch(Self {
414        cond,
415        true_bb,
416        false_bb,
417        true_args,
418        false_args,
419      }),
420    )
421  }
422
423  /// Returns the branch condition.
424  pub fn cond(&self) -> Value {
425    self.cond
426  }
427
428  /// Returns a mutable reference to the branch condition.
429  pub fn cond_mut(&mut self) -> &mut Value {
430    &mut self.cond
431  }
432
433  /// Returns the true target basic block.
434  pub fn true_bb(&self) -> BasicBlock {
435    self.true_bb
436  }
437
438  /// Returns a mutable reference to the true target basic block.
439  pub fn true_bb_mut(&mut self) -> &mut BasicBlock {
440    &mut self.true_bb
441  }
442
443  /// Returns the false target basic block.
444  pub fn false_bb(&self) -> BasicBlock {
445    self.false_bb
446  }
447
448  /// Returns a mutable reference to the false target basic block.
449  pub fn false_bb_mut(&mut self) -> &mut BasicBlock {
450    &mut self.false_bb
451  }
452
453  /// Returns a reference to the arguments passed to
454  /// the true target basic block.
455  pub fn true_args(&self) -> &[Value] {
456    &self.true_args
457  }
458
459  /// Returns a mutable reference to the arguments passed to
460  /// the true target basic block.
461  pub fn true_args_mut(&mut self) -> &mut Vec<Value> {
462    &mut self.true_args
463  }
464
465  /// Returns a reference to the arguments passed to
466  /// the false target basic block.
467  pub fn false_args(&self) -> &[Value] {
468    &self.false_args
469  }
470
471  /// Returns a mutable reference to the arguments passed to
472  /// the false target basic block.
473  pub fn false_args_mut(&mut self) -> &mut Vec<Value> {
474    &mut self.false_args
475  }
476}
477
478/// Unconditional jump.
479#[derive(Clone, Debug)]
480pub struct Jump {
481  target: BasicBlock,
482  args: Vec<Value>,
483}
484
485impl Jump {
486  pub(in crate::ir) fn new_data(target: BasicBlock) -> ValueData {
487    ValueData::new(
488      Type::get_unit(),
489      ValueKind::Jump(Self {
490        target,
491        args: Vec::new(),
492      }),
493    )
494  }
495
496  pub(in crate::ir) fn with_args(target: BasicBlock, args: Vec<Value>) -> ValueData {
497    ValueData::new(Type::get_unit(), ValueKind::Jump(Self { target, args }))
498  }
499
500  /// Returns the target basic block.
501  pub fn target(&self) -> BasicBlock {
502    self.target
503  }
504
505  /// Returns a mutable reference to the target basic block.
506  pub fn target_mut(&mut self) -> &mut BasicBlock {
507    &mut self.target
508  }
509
510  /// Returns a reference to the arguments passed to the target basic block.
511  pub fn args(&self) -> &[Value] {
512    &self.args
513  }
514
515  /// Returns a mutable reference to the arguments passed to the target basic block.
516  pub fn args_mut(&mut self) -> &mut Vec<Value> {
517    &mut self.args
518  }
519}
520
521/// Function call.
522#[derive(Clone, Debug)]
523pub struct Call {
524  callee: Function,
525  args: Vec<Value>,
526}
527
528impl Call {
529  pub(in crate::ir) fn new_data(callee: Function, args: Vec<Value>, ty: Type) -> ValueData {
530    ValueData::new(ty, ValueKind::Call(Self { callee, args }))
531  }
532
533  /// Returns the callee.
534  pub fn callee(&self) -> Function {
535    self.callee
536  }
537
538  /// Returns a mutable reference to the callee.
539  pub fn callee_mut(&mut self) -> &mut Function {
540    &mut self.callee
541  }
542
543  /// Returns a reference to the argument list.
544  pub fn args(&self) -> &[Value] {
545    &self.args
546  }
547
548  /// Returns a mutable reference to the argument list.
549  pub fn args_mut(&mut self) -> &mut Vec<Value> {
550    &mut self.args
551  }
552}
553
554/// Function return.
555#[derive(Clone, Debug)]
556pub struct Return {
557  value: Option<Value>,
558}
559
560impl Return {
561  pub(in crate::ir) fn new_data(value: Option<Value>) -> ValueData {
562    ValueData::new(Type::get_unit(), ValueKind::Return(Self { value }))
563  }
564
565  /// Returns the return value.
566  pub fn value(&self) -> Option<Value> {
567    self.value
568  }
569
570  /// Returns a mutable reference to the return value.
571  pub fn value_mut(&mut self) -> &mut Option<Value> {
572    &mut self.value
573  }
574}