fn estimate_riscv_event_counts(
        event_counts: &mut EnumMap<RiscvAirId, u64>,
        cpu_cycles: u64,
        local_counts: &LocalCounts,
    ) {
        let touched_addresses: u64 = local_counts.local_mem as u64;
        let syscalls_sent: u64 = local_counts.syscalls_sent as u64;
        let opcode_counts: &EnumMap<Opcode, u64> = &local_counts.event_counts;

        // Compute the number of events in the cpu chip.
        event_counts[RiscvAirId::Cpu] = cpu_cycles;

        // Compute the number of events in the add sub chip.
        event_counts[RiscvAirId::AddSub] = opcode_counts[Opcode::ADD] + opcode_counts[Opcode::SUB];

        // Compute the number of events in the mul chip.
        event_counts[RiscvAirId::Mul] = opcode_counts[Opcode::MUL] +
            opcode_counts[Opcode::MULH] +
            opcode_counts[Opcode::MULHU] +
            opcode_counts[Opcode::MULHSU];

        // Compute the number of events in the bitwise chip.
        event_counts[RiscvAirId::Bitwise] =
            opcode_counts[Opcode::XOR] + opcode_counts[Opcode::OR] + opcode_counts[Opcode::AND];

        // Compute the number of events in the shift left chip.
        event_counts[RiscvAirId::ShiftLeft] = opcode_counts[Opcode::SLL];

        // Compute the number of events in the shift right chip.
        event_counts[RiscvAirId::ShiftRight] =
            opcode_counts[Opcode::SRL] + opcode_counts[Opcode::SRA];

        // Compute the number of events in the divrem chip.
        event_counts[RiscvAirId::DivRem] = opcode_counts[Opcode::DIV] +
            opcode_counts[Opcode::DIVU] +
            opcode_counts[Opcode::REM] +
            opcode_counts[Opcode::REMU];

        // Compute the number of events in the lt chip.
        event_counts[RiscvAirId::Lt] = opcode_counts[Opcode::SLT] + opcode_counts[Opcode::SLTU];

        // Compute the number of events in the memory local chip.
        event_counts[RiscvAirId::MemoryLocal] =
            touched_addresses.div_ceil(NUM_LOCAL_MEMORY_ENTRIES_PER_ROW_EXEC as u64);

        // Compute the number of events in the branch chip.
        event_counts[RiscvAirId::Branch] = opcode_counts[Opcode::BEQ] +
            opcode_counts[Opcode::BNE] +
            opcode_counts[Opcode::BLT] +
            opcode_counts[Opcode::BGE] +
            opcode_counts[Opcode::BLTU] +
            opcode_counts[Opcode::BGEU];

        // Compute the number of events in the jump chip.
        event_counts[RiscvAirId::Jump] = opcode_counts[Opcode::JAL] + opcode_counts[Opcode::JALR];

        // Compute the number of events in the auipc chip.
        event_counts[RiscvAirId::Auipc] = opcode_counts[Opcode::AUIPC] +
            opcode_counts[Opcode::UNIMP] +
            opcode_counts[Opcode::EBREAK];

        // Compute the number of events in the memory instruction chip.
        event_counts[RiscvAirId::MemoryInstrs] = opcode_counts[Opcode::LB] +
            opcode_counts[Opcode::LH] +
            opcode_counts[Opcode::LW] +
            opcode_counts[Opcode::LBU] +
            opcode_counts[Opcode::LHU] +
            opcode_counts[Opcode::SB] +
            opcode_counts[Opcode::SH] +
            opcode_counts[Opcode::SW];

        // Compute the number of events in the syscall instruction chip.b
        event_counts[RiscvAirId::SyscallInstrs] = opcode_counts[Opcode::ECALL];

        // Compute the number of events in the syscall core chip.
        event_counts[RiscvAirId::SyscallCore] = syscalls_sent;

        // Compute the number of events in the global chip.
        event_counts[RiscvAirId::Global] =
            2 * touched_addresses + event_counts[RiscvAirId::SyscallInstrs];

        // Adjust for divrem dependencies.
        event_counts[RiscvAirId::Mul] += event_counts[RiscvAirId::DivRem];
        event_counts[RiscvAirId::Lt] += event_counts[RiscvAirId::DivRem];

        // Note: we ignore the additional dependencies for addsub, since they are accounted for in
        // the maximal shapes.
    }
Maps the opcode counts to the number of events in each air.
crates/core/executor/src/executor.rs