pub unsafe fn gen_to_vec(
        &mut self,
        builder: LLVMBuilderRef,
        intrinsics: &mut Intrinsics,
        kv_vector: &mut Vector,
        dict: LLVMValueRef,
        run: LLVMValueRef,
    ) -> WeldResult<LLVMValueRef> {
        if self.to_vec.is_none() {
            let mut arg_tys = [self.dict_ty, self.run_handle_type()];
            let ret_ty = kv_vector.vector_ty;

            let name = format!("{}.tovec", self.name);
            let (function, builder, entry_block) = self.define_function(ret_ty, &mut arg_tys, name);

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

            let dict = LLVMGetParam(function, 0);
            let run = LLVMGetParam(function, 1);

            // Generated Code:
            //
            // size = dict.size
            // size_nonzero = size > 0
            // br size_nonzero, makekvvec, return0
            //
            // makekvvec:
            // vec = vec.new(size)
            // capacity = dict.capacity
            // br top
            //
            // top:
            // i = [makkvvec, 0], [other, i2]
            // j = [makkvvec, 0], [other, j3]
            // slot = getslot(i)
            // br slot.filled ? tokv : bot
            //
            // tokv:
            // vec_ptr = gep vec, j
            // key_ptr = gep vecptr, 0
            // store slot.key into key_ptr
            // val_ptr = gep vecptr, 1
            // store slot.val into val_ptr
            // j2 = j+1
            // br bot
            //
            // bot:
            // j3 = phi [tokv, j2], [top, j]
            // i++
            // finished = i == capacity
            // br finished ? top : done
            //
            // done:
            // ret = phi [ bot, vec ], [ entry, zeroinitializer]
            //

            // A constant zero-vector.
            let mut zero_vector = LLVMGetUndef(kv_vector.vector_ty);
            zero_vector = LLVMConstInsertValue(
                zero_vector,
                self.null_ptr(kv_vector.elem_ty),
                [vector::POINTER_INDEX].as_mut_ptr(),
                1,
            );
            zero_vector = LLVMConstInsertValue(
                zero_vector,
                self.i64(0),
                [vector::SIZE_INDEX].as_mut_ptr(),
                1,
            );

            let after_nullcheck_block =
                LLVMAppendBasicBlockInContext(self.context(), function, c_str!("after.nullcheck"));
            let start_convert_block =
                LLVMAppendBasicBlockInContext(self.context(), function, c_str!("start.convert"));
            let top_block =
                LLVMAppendBasicBlockInContext(self.context(), function, c_str!("loop.top"));
            let copy_kv_block =
                LLVMAppendBasicBlockInContext(self.context(), function, c_str!("copy.kv"));
            let bot_block =
                LLVMAppendBasicBlockInContext(self.context(), function, c_str!("loop.bot"));
            let return_block =
                LLVMAppendBasicBlockInContext(self.context(), function, c_str!("return"));

            // Hack: For uninitalized dictionaries (which *must* be null pointers), return a
            // zero-vector.
            let is_null = LLVMBuildICmp(
                builder,
                LLVMIntEQ,
                dict,
                self.null_ptr(self.dict_inner_ty),
                c_str!("isNull"),
            );
            LLVMBuildCondBr(builder, is_null, return_block, after_nullcheck_block);

            LLVMPositionBuilderAtEnd(builder, after_nullcheck_block);
            let size = self.size(builder, dict);

            let size_nonzero = LLVMBuildICmp(builder, LLVMIntSGT, size, self.i64(0), c_str!(""));
            LLVMBuildCondBr(builder, size_nonzero, start_convert_block, return_block);

            LLVMPositionBuilderAtEnd(builder, start_convert_block);
            let capacity = self.capacity(builder, dict);
            let slot_array = self.slot_array(builder, dict);
            let vec = kv_vector.gen_new(builder, intrinsics, run, size)?;
            LLVMBuildBr(builder, top_block);

            LLVMPositionBuilderAtEnd(builder, top_block);
            // Index into the dictionary slot array.
            let slot_arr_index = LLVMBuildPhi(builder, self.i64_type(), c_str!(""));
            // Index into the vector.
            let kv_vec_index = LLVMBuildPhi(builder, self.i64_type(), c_str!(""));

            let slot = self.slot_at_index(builder, slot_array, slot_arr_index);
            let filled = self.slot_ty.filled(builder, slot);
            LLVMBuildCondBr(builder, filled, copy_kv_block, bot_block);

            // Copy block - copy the key/value into the vector.
            LLVMPositionBuilderAtEnd(builder, copy_kv_block);
            // Pointer to KV struct at the correct index.
            let vector_ptr = kv_vector.gen_at(builder, vec, kv_vec_index)?;

            // Copy the key.
            let vec_key_ptr = LLVMBuildStructGEP(builder, vector_ptr, 0, c_str!(""));
            let slot_key_ptr = self.slot_ty.key(builder, slot);
            let slot_key = self.load(builder, slot_key_ptr).unwrap();
            LLVMBuildStore(builder, slot_key, vec_key_ptr);

            // Copy the value.
            let vec_val_ptr = LLVMBuildStructGEP(builder, vector_ptr, 1, c_str!(""));
            let slot_val_ptr = self.slot_ty.value(builder, slot);
            let slot_val = self.load(builder, slot_val_ptr).unwrap();
            LLVMBuildStore(builder, slot_val, vec_val_ptr);

            let inc_kv_vec_index = LLVMBuildNSWAdd(builder, kv_vec_index, self.i64(1), c_str!(""));
            LLVMBuildBr(builder, bot_block);

            // Bottom of loop -- increment induction variables and loop or exit.
            LLVMPositionBuilderAtEnd(builder, bot_block);
            let new_kv_vec_index = LLVMBuildPhi(builder, self.i64_type(), c_str!(""));
            let new_slot_arr_index =
                LLVMBuildNSWAdd(builder, slot_arr_index, self.i64(1), c_str!(""));
            let finished =
                LLVMBuildICmp(builder, LLVMIntEQ, new_slot_arr_index, capacity, c_str!(""));
            LLVMBuildCondBr(builder, finished, return_block, top_block);

            // Return Block.
            LLVMPositionBuilderAtEnd(builder, return_block);
            let ret = LLVMBuildPhi(builder, kv_vector.vector_ty, c_str!(""));
            LLVMBuildRet(builder, ret);

            // Set the PHI value for the return value.
            let mut blocks = [entry_block, after_nullcheck_block, bot_block];
            let mut values = [zero_vector, zero_vector, vec];
            LLVMAddIncoming(
                ret,
                values.as_mut_ptr(),
                blocks.as_mut_ptr(),
                values.len() as u32,
            );

            // Set the PHI value for the slot array induction variable.
            let mut blocks = [start_convert_block, bot_block];
            let mut values = [self.i64(0), new_slot_arr_index];
            LLVMAddIncoming(
                slot_arr_index,
                values.as_mut_ptr(),
                blocks.as_mut_ptr(),
                values.len() as u32,
            );

            // Set the PHI value for the offset into the KV vector.
            let mut blocks = [start_convert_block, bot_block];
            let mut values = [self.i64(0), new_kv_vec_index];
            LLVMAddIncoming(
                kv_vec_index,
                values.as_mut_ptr(),
                blocks.as_mut_ptr(),
                values.len() as u32,
            );

            // Set the PHI value for the intermediate KV vector offset in bot_block.
            let mut blocks = [top_block, copy_kv_block];
            let mut values = [kv_vec_index, inc_kv_vec_index];
            LLVMAddIncoming(
                new_kv_vec_index,
                values.as_mut_ptr(),
                blocks.as_mut_ptr(),
                values.len() as u32,
            );

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

        let mut args = [dict, run];
        Ok(LLVMBuildCall(
            builder,
            self.to_vec.unwrap(),
            args.as_mut_ptr(),
            args.len() as u32,
            c_str!(""),
        ))
    }
Converts this dictionary to a vector of key/value pairs.
weld/src/codegen/llvm2/dict.rs