/src/wasmtime/winch/codegen/src/constant_pool.rs
Line | Count | Source |
1 | | //! An ISA-independent constant pool. |
2 | | |
3 | | use cranelift_codegen::{ |
4 | | MachBuffer, VCodeConstant, VCodeConstantData, VCodeConstants, VCodeInst, ir, |
5 | | }; |
6 | | |
7 | | pub(crate) struct ConstantPool { |
8 | | inner: ir::ConstantPool, |
9 | | constants: VCodeConstants, |
10 | | } |
11 | | |
12 | | impl ConstantPool { |
13 | 86.9k | pub fn new() -> Self { |
14 | 86.9k | Self { |
15 | 86.9k | inner: ir::ConstantPool::new(), |
16 | 86.9k | constants: Default::default(), |
17 | 86.9k | } |
18 | 86.9k | } |
19 | | |
20 | | /// Register a constant and return a handle, ready for emission. |
21 | 466k | pub fn register<I: VCodeInst>( |
22 | 466k | &mut self, |
23 | 466k | data: &[u8], |
24 | 466k | buffer: &mut MachBuffer<I>, |
25 | 466k | ) -> VCodeConstant { |
26 | 466k | let constant_handle = self.inner.insert(data.into()); |
27 | 466k | let constant_data = self.inner.get(constant_handle); |
28 | | |
29 | | // NB: The insertion will only happen if the pool doesn't already use the constant data. |
30 | | // The reason why the order of operations is apparently inversed is to be sure to insert |
31 | | // the `VCodeConstantData` in the `MachBuffer` only once, as no deduplication happens at |
32 | | // such layer. |
33 | 466k | let vcode_constant_data = VCodeConstantData::Pool(constant_handle, constant_data.clone()); |
34 | 466k | let must_register = !self.constants.pool_uses(&vcode_constant_data); |
35 | 466k | let vcode_constant = self.constants.insert(VCodeConstantData::Pool( |
36 | 466k | constant_handle, |
37 | 466k | constant_data.clone(), |
38 | 466k | )); |
39 | | |
40 | 466k | if must_register { |
41 | 87.7k | buffer.register_constant(&vcode_constant, &vcode_constant_data); |
42 | 378k | } |
43 | 466k | vcode_constant |
44 | 466k | } |
45 | | |
46 | | /// Get the finalized constants. |
47 | 85.7k | pub fn constants(self) -> VCodeConstants { |
48 | 85.7k | self.constants |
49 | 85.7k | } |
50 | | } |