📄 gen_segment.c
字号:
piece_size = cur_elmp->curblock * dtype_size; break; case DLOOP_KIND_VECTOR: /* TODO: RECOGNIZE ABILITY TO DO STRIDED COPIES -- * ONLY GOOD FOR THE NON-VECTOR CASES... */ piece_size = cur_elmp->curblock * dtype_size; break; default: assert(0); }#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\thit leaf; cur_sp=%d, elmp=%x, piece_sz=%d\n", cur_sp, (unsigned) cur_elmp, piece_size);#endif /* ??? SHOULD THIS BE >= FOR SOME REASON ??? */ if (stream_off + piece_size > (unsigned long) last) { /* Cannot process the entire "piece" -- round down */ piece_size = ((last - stream_off) / basic_size) * basic_size;#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\tpartial piece_size=%d\n", piece_size);#endif partial_flag = 1; } else { partial_flag = 0; /* handling everything left for this type */ } if (piecefn) piecefn_indicated_exit = piecefn((DLOOP_Handle) 0, cur_elmp->curoffset, piece_size, segp->ptr, pieceparams); else { piecefn_indicated_exit = 0;#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\tNULL piecefn for this piece\n");#endif } stream_off += piece_size; /* TODO: MAYBE REORGANIZE? */ if (partial_flag) { cur_elmp->curoffset += piece_size; /* definitely didn't process everything in this contig. region */ /* NOTE: THIS CODE ASSUMES THAT WE'RE WORKING IN WHOLE DTYPE SIZES!!! */ switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) { case DLOOP_KIND_CONTIG: cur_elmp->curcount -= piece_size / dtype_size; break; case DLOOP_KIND_BLOCKINDEXED: case DLOOP_KIND_INDEXED: cur_elmp->curblock -= piece_size / dtype_size; break; case DLOOP_KIND_VECTOR: /* TODO: RECOGNIZE ABILITY TO DO STRIDED COPIES -- * ONLY GOOD FOR THE NON-VECTOR CASES... */ cur_elmp->curblock -= piece_size / dtype_size; break; default: assert(0); }#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("partial flag, returning sooner than expected.\n");#endif DLOOP_SEGMENT_SAVE_LOCAL_VALUES; return; } else { /* we at least finished a whole block */ /* Update the stack elements. Either we're done with the count, * in which case it is time to pop off, or we need to reset the * block value (because we just handled an entire block). * * Note that this will get more complicated as I add the ability * to handle more of the partial processing cases. ??? */ switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) { case DLOOP_KIND_CONTIG: cur_elmp->curoffset += piece_size; DLOOP_SEGMENT_POP_AND_MAYBE_EXIT; /* currently always handling the whole contig */ break; case DLOOP_KIND_BLOCKINDEXED: assert(0); break; case DLOOP_KIND_INDEXED: cur_elmp->curcount--; if (cur_elmp->curcount == 0) DLOOP_SEGMENT_POP_AND_MAYBE_EXIT; else { int count_index = cur_elmp->orig_count - cur_elmp->curcount; cur_elmp->orig_block = DLOOP_STACKELM_INDEXED_BLOCKSIZE(cur_elmp, count_index); cur_elmp->curblock = cur_elmp->orig_block; cur_elmp->curoffset = cur_elmp->orig_offset + DLOOP_STACKELM_INDEXED_OFFSET(cur_elmp, count_index); } break; case DLOOP_KIND_VECTOR: cur_elmp->curcount--; if (cur_elmp->curcount == 0) DLOOP_SEGMENT_POP_AND_MAYBE_EXIT; else { cur_elmp->curblock = cur_elmp->orig_block; /* NOTE: stride is in bytes */ /* TODO: CLEAN THIS ONE UP */ cur_elmp->curoffset += piece_size; cur_elmp->curoffset += cur_elmp->loop_p->loop_params.v_t.stride - (cur_elmp->orig_block * cur_elmp->loop_p->el_extent); } break; default: assert(0); } } if (piecefn_indicated_exit) { /* The piece function indicated that we should quit processing */ DLOOP_SEGMENT_SAVE_LOCAL_VALUES; return; } } /* end of if leaf */ else if (cur_elmp->curblock == 0) { /* This section is testing to see if we hit the end of the count * for this type (which is not a leaf). The first test is that we * hit end of block. */#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\thit end of block; elmp=%x [%d]\n", (unsigned) cur_elmp, cur_sp);#endif cur_elmp->curcount--; if (cur_elmp->curcount == 0) { /* We also hit end of count; pop this type. */#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\talso hit end of count; elmp=%x [%d]\n", (unsigned) cur_elmp, cur_sp);#endif DLOOP_SEGMENT_POP_AND_MAYBE_EXIT; } else { /* Otherwise we just have a new block. Reset block value. */ if ((cur_elmp->loop_p->kind & DLOOP_KIND_MASK) == DLOOP_KIND_INDEXED) { /* indexed and struct are the only ones for which this can change * during processing. and this code doesn't do structs... */ cur_elmp->orig_block = DLOOP_STACKELM_INDEXED_BLOCKSIZE(cur_elmp, cur_elmp->orig_count - cur_elmp->curcount); } cur_elmp->curblock = cur_elmp->orig_block; /* TODO: COMBINE INTO NEXT BIG ELSE; WE'RE PROBABLY MAKING AN EXTRA PASS THROUGH OUR LOOPS */ } } /* end of "hit end of a block, maybe hit end of loop (count)" */ else { DLOOP_Dataloop_stackelm *next_elmp; int count_index, block_index; /* Push the datatype. * * Recall that all the stack elements have been filled in at init * time. However, the offset must be filled in at each iteration. */ next_elmp = &(segp->stackelm[cur_sp + 1]); count_index = cur_elmp->orig_count - cur_elmp->curcount; block_index = cur_elmp->orig_block - cur_elmp->curblock;#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\tpushing type, elmp=%x [%d], count=%d, block=%d\n", (unsigned) cur_elmp, cur_sp, count_index, block_index);#endif /* This is a two-step process; some items are dependent on * the current type, while others are dependent on the next * type. * * First step: set up the orig_offset of next type based on * the current type. * * If we weren't doing indexed, we could simpify this quite a bit. */ switch (cur_elmp->loop_p->kind & DLOOP_KIND_MASK) { case DLOOP_KIND_CONTIG: next_elmp->orig_offset = cur_elmp->curoffset + count_index * cur_elmp->loop_p->el_extent; break; case DLOOP_KIND_VECTOR: /* NOTE: stride is in bytes */ next_elmp->orig_offset = cur_elmp->orig_offset + count_index * cur_elmp->loop_p->loop_params.v_t.stride + block_index * cur_elmp->loop_p->el_extent; break; case DLOOP_KIND_BLOCKINDEXED: next_elmp->orig_offset = cur_elmp->orig_offset + block_index * cur_elmp->loop_p->el_extent + DLOOP_STACKELM_BLOCKINDEXED_OFFSET(cur_elmp, count_index); assert(0); break; case DLOOP_KIND_INDEXED: /* Accounting for additional offset from being partway * through a collection of blocks, plus the displacement * for this count. */ next_elmp->orig_offset = cur_elmp->orig_offset + block_index * cur_elmp->loop_p->el_extent + DLOOP_STACKELM_INDEXED_OFFSET(cur_elmp, count_index); break; default: assert(0); } /* end of switch */#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\tstep 1: next orig_offset = %d (0x%x)\n", next_elmp->orig_offset, next_elmp->orig_offset);#endif /* now we update the curoffset based on the next type */ switch (next_elmp->loop_p->kind & DLOOP_KIND_MASK) { case DLOOP_KIND_CONTIG: next_elmp->curcount = next_elmp->orig_count; next_elmp->curblock = next_elmp->orig_block; next_elmp->curoffset = next_elmp->orig_offset; break; case DLOOP_KIND_VECTOR: next_elmp->curcount = next_elmp->orig_count; next_elmp->curblock = next_elmp->orig_block; next_elmp->curoffset = next_elmp->orig_offset; break; case DLOOP_KIND_BLOCKINDEXED: next_elmp->curcount = next_elmp->orig_count; next_elmp->curblock = next_elmp->orig_block; next_elmp->curoffset = next_elmp->orig_offset + DLOOP_STACKELM_BLOCKINDEXED_OFFSET(next_elmp, 0); break; case DLOOP_KIND_INDEXED: next_elmp->curcount = next_elmp->orig_count; next_elmp->curblock = DLOOP_STACKELM_INDEXED_BLOCKSIZE(next_elmp, 0); next_elmp->curoffset = next_elmp->orig_offset + DLOOP_STACKELM_INDEXED_OFFSET(next_elmp, 0); break; default: assert(0); } /* end of switch */ /* TODO: HANDLE NON-ZERO OFFSETS IN NEXT_ELMP HERE? */#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("\tstep 2: next curoffset = %d (0x%x)\n", next_elmp->curoffset, next_elmp->curoffset);#endif cur_elmp->curblock--; DLOOP_SEGMENT_PUSH; } /* end of else push the datatype */ } /* end of while cur_sp >= 0 */#ifdef DLOOP_M_VERBOSE DLOOP_dbg_printf("hit end of datatype\n");#endif DLOOP_SEGMENT_SAVE_LOCAL_VALUES; return;}/* DLOOP_Stackelm_blocksize - returns block size for stackelm based on current * count in stackelm. * * NOTE: loop_p, orig_count, and curcount members of stackelm MUST be correct * before this is called! * */static inline int DLOOP_Stackelm_blocksize(struct DLOOP_Dataloop_stackelm *elmp){ struct DLOOP_Dataloop *dlp = elmp->loop_p; switch(dlp->kind & DLOOP_KIND_MASK) { case DLOOP_KIND_CONTIG: return 1; break; case DLOOP_KIND_VECTOR: return dlp->loop_params.v_t.blocksize; break; case DLOOP_KIND_BLOCKINDEXED: return dlp->loop_params.bi_t.blocksize; break; case DLOOP_KIND_INDEXED: return dlp->loop_params.i_t.blocksize_array[elmp->orig_count - elmp->curcount]; break; case DLOOP_KIND_STRUCT: return dlp->loop_params.s_t.blocksize_array[elmp->orig_count - elmp->curcount]; break; default: assert(0); break; } return -1;}/* DLOOP_Stackelm_offset - returns starting offset (displacement) for stackelm * based on current count in stackelm. * * NOTE: loop_p, orig_count, and curcount members of stackelm MUST be correct * before this is called! * * also, this really is only good at init time for vectors and contigs * (all the time for indexed) at the moment. * */static inline int DLOOP_Stackelm_offset(struct DLOOP_Dataloop_stackelm *elmp){ struct DLOOP_Dataloop *dlp = elmp->loop_p; switch(dlp->kind & DLOOP_KIND_MASK) { case DLOOP_KIND_VECTOR: case DLOOP_KIND_CONTIG: return 0; break; case DLOOP_KIND_BLOCKINDEXED: return dlp->loop_params.bi_t.offset_array[elmp->orig_count - elmp->curcount]; break; case DLOOP_KIND_INDEXED: return dlp->loop_params.i_t.offset_array[elmp->orig_count - elmp->curcount]; break; case DLOOP_KIND_STRUCT: return dlp->loop_params.s_t.offset_array[elmp->orig_count - elmp->curcount]; break; default: assert(0); break; } return -1;}/* * Local variables: * c-indent-tabs-mode: nil * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -