unsafe fn gen_slot_for_key(
        &mut self,
        builder: LLVMBuilderRef,
        slot_array: LLVMValueRef,
        capacity: LLVMValueRef,
        hash: LLVMValueRef,
        key: LLVMValueRef,
    ) -> LLVMValueRef {
        if self.slot_for_key.is_none() {
            let mut arg_tys = [
                LLVMPointerType(self.slot_ty.slot_ty, 0),
                self.i64_type(),
                self.i32_type(),
                LLVMPointerType(self.slot_ty.key_ty, 0),
            ];
            let ret_ty = LLVMPointerType(self.slot_ty.slot_ty, 0);
            let name = format!("{}.slot_for_key", self.name);

            let (function, builder, entry_block) = self.define_function(ret_ty, &mut arg_tys, name);

            LLVMExtAddAttrsOnParameter(self.context, function, &[NoAlias, NoCapture, ReadOnly], 0);
            LLVMExtAddAttrsOnParameter(self.context, function, &[NoAlias, NoCapture, ReadOnly], 3);

            let slot_array = LLVMGetParam(function, 0);
            let capacity = LLVMGetParam(function, 1);
            let hash = LLVMGetParam(function, 2);
            let key = LLVMGetParam(function, 3);

            let top_block = LLVMAppendBasicBlockInContext(self.context(), function, c_str!(""));
            let check_key_block =
                LLVMAppendBasicBlockInContext(self.context(), function, c_str!(""));
            let return_block = LLVMAppendBasicBlockInContext(self.context(), function, c_str!(""));

            let slot = self.gen_probe_loop(
                builder,
                slot_array,
                capacity,
                hash,
                (entry_block, top_block, check_key_block, return_block),
                Some(key),
            );

            LLVMBuildRet(builder, slot);

            self.slot_for_key = Some(function);
            LLVMDisposeBuilder(builder);
        }

        let mut args = [slot_array, capacity, hash, key];
        LLVMBuildCall(
            builder,
            self.slot_for_key.unwrap(),
            args.as_mut_ptr(),
            args.len() as u32,
            c_str!(""),
        )
    }
Return the slot for a given key. The returned slot may be uninitialized if the key does not
exist in the dictionary.

The current algorithm assumes a power-of-two hash table and performs standard linear
probing.
weld/src/codegen/llvm2/dict.rs