Skip to main content

luaur_code_gen/records/
ir_inst_hash.rs

1use crate::records::ir_inst::IrInst;
2use crate::records::ir_op::IrOp;
3
4#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
5#[repr(C)]
6pub struct IrInstHash;
7
8impl IrInstHash {
9    pub fn mix_u32_u32(h: u32, k: u32) -> u32 {
10        let m: u32 = 0x5bd1e995;
11        let r: u32 = 24;
12
13        let mut k: u32 = k;
14        k = k.wrapping_mul(m);
15        k ^= k >> r;
16        k = k.wrapping_mul(m);
17
18        let mut h: u32 = h;
19        h = h.wrapping_mul(m);
20        h ^= k;
21
22        h
23    }
24
25    pub fn mix_u32_ir_op(h: u32, op: IrOp) -> u32 {
26        let k: u32 = op.kind_and_index;
27        Self::mix_u32_u32(h, k)
28    }
29
30    pub fn ir_inst_hash_operator_call(&self, key: &IrInst) -> usize {
31        let mut h: u32 = 25;
32
33        h = Self::mix_u32_u32(h, key.cmd as u32);
34
35        let ops_size = key.ops.size() as u32;
36        for i in 0..7 {
37            let op = if i < ops_size {
38                key.ops[i as usize]
39            } else {
40                IrOp { kind_and_index: 0 }
41            };
42            h = Self::mix_u32_ir_op(h, op);
43        }
44
45        h ^= h >> 13;
46        h = h.wrapping_mul(0x5bd1e995);
47        h ^= h >> 15;
48
49        h as usize
50    }
51}
52
53impl luaur_common::records::dense_hash_table::DenseHasher<crate::records::ir_inst::IrInst>
54    for IrInstHash
55{
56    fn hash(&self, key: &crate::records::ir_inst::IrInst) -> usize {
57        self.ir_inst_hash_operator_call(key)
58    }
59}