pub struct ConstantPool { /* private fields */ }
Expand description

Maintains the mapping between a constant handle (i.e. Constant) and its constant data (i.e. ConstantData).

Implementations§

Create a new constant pool instance.

Examples found in repository?
src/ir/dfg.rs (line 106)
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    pub fn new() -> Self {
        Self {
            insts: PrimaryMap::new(),
            results: SecondaryMap::new(),
            blocks: PrimaryMap::new(),
            dynamic_types: DynamicTypes::new(),
            value_lists: ValueListPool::new(),
            values: PrimaryMap::new(),
            signatures: PrimaryMap::new(),
            old_signatures: SecondaryMap::new(),
            ext_funcs: PrimaryMap::new(),
            values_labels: None,
            constants: ConstantPool::new(),
            immediates: PrimaryMap::new(),
            heap_imms: PrimaryMap::new(),
        }
    }

Empty the constant pool of all data.

Examples found in repository?
src/ir/dfg.rs (line 124)
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    pub fn clear(&mut self) {
        self.insts.clear();
        self.results.clear();
        self.blocks.clear();
        self.dynamic_types.clear();
        self.value_lists.clear();
        self.values.clear();
        self.signatures.clear();
        self.old_signatures.clear();
        self.ext_funcs.clear();
        self.values_labels = None;
        self.constants.clear();
        self.immediates.clear();
    }

Insert constant data into the pool, returning a handle for later referencing; when constant data is inserted that is a duplicate of previous constant data, the existing handle will be returned.

Retrieve the constant data given a handle.

Examples found in repository?
src/machinst/lower.rs (line 1353)
1352
1353
1354
    pub fn get_constant_data(&self, constant_handle: Constant) -> &ConstantData {
        self.f.dfg.constants.get(constant_handle)
    }
More examples
Hide additional examples
src/verifier/mod.rs (line 1121)
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
    fn verify_constant_size(
        &self,
        inst: Inst,
        constant: Constant,
        errors: &mut VerifierErrors,
    ) -> VerifierStepResult<()> {
        let type_size = self.func.dfg.ctrl_typevar(inst).bytes() as usize;
        let constant_size = self.func.dfg.constants.get(constant).len();
        if type_size != constant_size {
            errors.fatal((
                inst,
                format!(
                    "The instruction expects {} to have a size of {} bytes but it has {}",
                    constant, type_size, constant_size
                ),
            ))
        } else {
            Ok(())
        }
    }

Link a constant handle to its value. This does not de-duplicate data but does avoid replacing any existing constant values. use set to tie a specific const42 to its value; use insert to add a value and return the next available const entity.

Examples found in repository?
src/ir/constant.rs (line 211)
205
206
207
208
209
210
211
212
213
    pub fn insert(&mut self, constant_value: ConstantData) -> Constant {
        if let Some(cst) = self.values_to_handles.get(&constant_value) {
            return *cst;
        }

        let constant_handle = Constant::new(self.len());
        self.set(constant_handle, constant_value);
        constant_handle
    }

Iterate over the constants in insertion order.

Examples found in repository?
src/write.rs (line 98)
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    fn super_preamble(&mut self, w: &mut dyn Write, func: &Function) -> Result<bool, fmt::Error> {
        let mut any = false;

        for (ss, slot) in func.dynamic_stack_slots.iter() {
            any = true;
            self.write_entity_definition(w, func, ss.into(), slot)?;
        }

        for (ss, slot) in func.sized_stack_slots.iter() {
            any = true;
            self.write_entity_definition(w, func, ss.into(), slot)?;
        }

        for (gv, gv_data) in &func.global_values {
            any = true;
            self.write_entity_definition(w, func, gv.into(), gv_data)?;
        }

        for (heap, heap_data) in &func.heaps {
            if !heap_data.index_type.is_invalid() {
                any = true;
                self.write_entity_definition(w, func, heap.into(), heap_data)?;
            }
        }

        for (table, table_data) in &func.tables {
            if !table_data.index_type.is_invalid() {
                any = true;
                self.write_entity_definition(w, func, table.into(), table_data)?;
            }
        }

        // Write out all signatures before functions since function declarations can refer to
        // signatures.
        for (sig, sig_data) in &func.dfg.signatures {
            any = true;
            self.write_entity_definition(w, func, sig.into(), &sig_data)?;
        }

        for (fnref, ext_func) in &func.dfg.ext_funcs {
            if ext_func.signature != SigRef::reserved_value() {
                any = true;
                self.write_entity_definition(
                    w,
                    func,
                    fnref.into(),
                    &ext_func.display(Some(&func.params)),
                )?;
            }
        }

        for (jt, jt_data) in &func.jump_tables {
            any = true;
            self.write_entity_definition(w, func, jt.into(), jt_data)?;
        }

        for (&cref, cval) in func.dfg.constants.iter() {
            any = true;
            self.write_entity_definition(w, func, cref.into(), cval)?;
        }

        if let Some(limit) = func.stack_limit {
            any = true;
            self.write_entity_definition(w, func, AnyEntity::StackLimit, &limit)?;
        }

        Ok(any)
    }

Iterate over mutable entries in the constant pool in insertion order.

Return the number of constants in the pool.

Examples found in repository?
src/ir/constant.rs (line 210)
205
206
207
208
209
210
211
212
213
    pub fn insert(&mut self, constant_value: ConstantData) -> Constant {
        if let Some(cst) = self.values_to_handles.get(&constant_value) {
            return *cst;
        }

        let constant_handle = Constant::new(self.len());
        self.set(constant_handle, constant_value);
        constant_handle
    }
More examples
Hide additional examples
src/machinst/lower.rs (line 335)
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    pub fn new(
        f: &'func Function,
        flags: crate::settings::Flags,
        machine_env: &MachineEnv,
        abi: Callee<I::ABIMachineSpec>,
        emit_info: I::Info,
        block_order: BlockLoweringOrder,
        sigs: SigSet,
    ) -> CodegenResult<Self> {
        let constants = VCodeConstants::with_capacity(f.dfg.constants.len());
        let vcode = VCodeBuilder::new(
            sigs,
            abi,
            emit_info,
            block_order,
            constants,
            VCodeBuildDirection::Backward,
        );

        let mut vregs = VRegAllocator::new();

        let mut value_regs = SecondaryMap::with_default(ValueRegs::invalid());

        // Assign a vreg to each block param and each inst result.
        for bb in f.layout.blocks() {
            for &param in f.dfg.block_params(bb) {
                let ty = f.dfg.value_type(param);
                if value_regs[param].is_invalid() {
                    let regs = vregs.alloc(ty)?;
                    value_regs[param] = regs;
                    trace!("bb {} param {}: regs {:?}", bb, param, regs);
                }
            }
            for inst in f.layout.block_insts(bb) {
                for &result in f.dfg.inst_results(inst) {
                    let ty = f.dfg.value_type(result);
                    if value_regs[result].is_invalid() && !ty.is_invalid() {
                        let regs = vregs.alloc(ty)?;
                        value_regs[result] = regs;
                        trace!(
                            "bb {} inst {} ({:?}): result {} regs {:?}",
                            bb,
                            inst,
                            f.dfg[inst],
                            result,
                            regs,
                        );
                    }
                }
            }
        }

        // Make a sret register, if one is needed.
        let mut sret_reg = None;
        for ret in &vcode.abi().signature().returns.clone() {
            if ret.purpose == ArgumentPurpose::StructReturn {
                assert!(sret_reg.is_none());
                sret_reg = Some(vregs.alloc(ret.value_type)?);
            }
        }

        // Compute instruction colors, find constant instructions, and find instructions with
        // side-effects, in one combined pass.
        let mut cur_color = 0;
        let mut block_end_colors = SecondaryMap::with_default(InstColor::new(0));
        let mut side_effect_inst_entry_colors = FxHashMap::default();
        let mut inst_constants = FxHashMap::default();
        for bb in f.layout.blocks() {
            cur_color += 1;
            for inst in f.layout.block_insts(bb) {
                let side_effect = has_lowering_side_effect(f, inst);

                trace!("bb {} inst {} has color {}", bb, inst, cur_color);
                if side_effect {
                    side_effect_inst_entry_colors.insert(inst, InstColor::new(cur_color));
                    trace!(" -> side-effecting; incrementing color for next inst");
                    cur_color += 1;
                }

                // Determine if this is a constant; if so, add to the table.
                if let Some(c) = is_constant_64bit(f, inst) {
                    trace!(" -> constant: {}", c);
                    inst_constants.insert(inst, c);
                }
            }

            block_end_colors[bb] = InstColor::new(cur_color);
        }

        let value_ir_uses = Self::compute_use_states(f);

        Ok(Lower {
            f,
            flags,
            allocatable: PRegSet::from(machine_env),
            vcode,
            vregs,
            value_regs,
            sret_reg,
            block_end_colors,
            side_effect_inst_entry_colors,
            inst_constants,
            value_ir_uses,
            value_lowered_uses: SecondaryMap::default(),
            inst_sunk: FxHashSet::default(),
            cur_scan_entry_color: None,
            cur_inst: None,
            ir_insts: vec![],
            pinned_reg: None,
        })
    }

Return the combined size of all of the constant values in the pool.

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
This method tests for self and other values to be equal, and is used by ==.
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.