void si_uop_list_free(struct list_t *uop_list) { struct si_uop_t *uop; while (list_count(uop_list)) { uop = list_head(uop_list); list_remove(uop_list, uop); si_uop_free(uop); } }
void si_uop_list_free(struct linked_list_t *gpu_uop_list) { struct si_uop_t *uop; while (linked_list_count(gpu_uop_list)) { linked_list_head(gpu_uop_list); uop = linked_list_get(gpu_uop_list); si_uop_free(uop); linked_list_remove(gpu_uop_list); } }
void si_gpu_uop_trash_empty(void) { struct si_uop_t *uop; while (si_gpu->trash_uop_list->count) { linked_list_head(si_gpu->trash_uop_list); uop = linked_list_get(si_gpu->trash_uop_list); linked_list_remove(si_gpu->trash_uop_list); si_trace("si.end_inst id=%lld cu=%d\n", uop->id_in_compute_unit, uop->compute_unit->id); si_uop_free(uop); } }
void si_simd_complete(struct si_simd_t *simd) { struct si_uop_t *uop; int list_entries; int list_index = 0; int i; list_entries = list_count(simd->exec_buffer); assert(list_entries <= si_gpu_simd_exec_buffer_size); for (i = 0; i < list_entries; i++) { uop = list_get(simd->exec_buffer, list_index); assert(uop); if (asTiming(si_gpu)->cycle < uop->execute_ready) { list_index++; continue; } /* Access complete, remove the uop from the queue */ list_remove(simd->exec_buffer, uop); si_trace("si.end_inst id=%lld cu=%d\n", uop->id_in_compute_unit, uop->compute_unit->id); /* Free uop */ si_uop_free(uop); /* Statistics */ simd->inst_count++; si_gpu->last_complete_cycle = asTiming(si_gpu)->cycle; } }
void si_scalar_unit_writeback(struct si_scalar_unit_t *scalar_unit) { struct si_uop_t *uop = NULL; struct si_wavefront_t *wavefront; struct si_work_group_t *work_group; struct si_ndrange_t *ndrange; int i; int list_count; int wavefront_id; /* Process completed memory instructions */ list_count = linked_list_count(scalar_unit->mem_out_buffer); linked_list_head(scalar_unit->mem_out_buffer); for (i = 0; i < list_count; i++) { uop = linked_list_get(scalar_unit->mem_out_buffer); assert(uop); if (!uop->global_mem_witness) { /* Access complete, remove the uop from the queue */ linked_list_remove(scalar_unit->mem_out_buffer); si_trace("si.inst id=%lld cu=%d stg=\"su-w\"\n", uop->id_in_compute_unit, scalar_unit->compute_unit->id); /* Make the wavefront active again */ wavefront = uop->wavefront; wavefront->ready = 1; /* Free uop */ if (si_tracing()) si_gpu_uop_trash_add(uop); else si_uop_free(uop); } else { linked_list_next(scalar_unit->mem_out_buffer); } } /* Process completed ALU instructions */ list_count = linked_list_count(scalar_unit->alu_out_buffer); linked_list_head(scalar_unit->alu_out_buffer); for (i = 0; i < list_count; i++) { uop = linked_list_get(scalar_unit->alu_out_buffer); assert(uop); if (uop->execute_ready <= si_gpu->cycle) { /* Access complete, remove the uop from the queue */ linked_list_remove(scalar_unit->alu_out_buffer); si_trace("si.inst id=%lld cu=%d stg=\"su-w\"\n", uop->id_in_compute_unit, scalar_unit->compute_unit->id); /* Make the wavefront active again */ wavefront = uop->wavefront; work_group = wavefront->work_group; ndrange = work_group->ndrange; if (wavefront->finished) { work_group->compute_unit_finished_count++; } else if (wavefront->barrier) { if (wavefront->barrier_cleared) { /* All wavefronts have hit barrier */ wavefront->barrier_cleared = 0; SI_FOREACH_WAVEFRONT_IN_WORK_GROUP(work_group, wavefront_id) { wavefront = ndrange->wavefronts[wavefront_id]; wavefront->barrier = 0; wavefront->ready = 1; } } else { /* Wavefront is waiting at barrier */ } } else {