Path: blob/main/winch/codegen/src/constant_pool.rs
1691 views
//! An ISA-independent constant pool.12use cranelift_codegen::{3MachBuffer, VCodeConstant, VCodeConstantData, VCodeConstants, VCodeInst, ir,4};56pub(crate) struct ConstantPool {7inner: ir::ConstantPool,8constants: VCodeConstants,9}1011impl ConstantPool {12pub fn new() -> Self {13Self {14inner: ir::ConstantPool::new(),15constants: Default::default(),16}17}1819/// Register a constant and return a handle, ready for emission.20pub fn register<I: VCodeInst>(21&mut self,22data: &[u8],23buffer: &mut MachBuffer<I>,24) -> VCodeConstant {25let constant_handle = self.inner.insert(data.into());26let constant_data = self.inner.get(constant_handle);2728// NB: The insertion will only happen if the pool doesn't already use the constant data.29// The reason why the order of operations is apparently inversed is to be sure to insert30// the `VCodeConstantData` in the `MachBuffer` only once, as no deduplication happens at31// such layer.32let vcode_constant_data = VCodeConstantData::Pool(constant_handle, constant_data.clone());33let must_register = !self.constants.pool_uses(&vcode_constant_data);34let vcode_constant = self.constants.insert(VCodeConstantData::Pool(35constant_handle,36constant_data.clone(),37));3839if must_register {40buffer.register_constant(&vcode_constant, &vcode_constant_data);41}42vcode_constant43}4445/// Get the finalized constants.46pub fn constants(self) -> VCodeConstants {47self.constants48}49}505152