diff options
| author | Tor Aamodt <[email protected]> | 2010-07-18 02:20:50 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-07-18 02:20:50 -0800 |
| commit | cc404275f9226185e436e1da483ee58ee85c38ca (patch) | |
| tree | e133be6f3a1bb897593328e438196a04dc88b47d | |
| parent | 7e755bb656b68cfb628fcc0424b1325c32cb5d61 (diff) | |
- simple device printf support added (supports %u, %d, %f)
- add support to call_impl for passing values in through local param space (need to add support for return)
- track local framesize during ptx parsing / update local stack-pointer during call/return
- detect appropriate param space for ld.param (and st.param) depending upon address symbol's scope
- putting back the crazy math for local mem allocation (seems to be required)
- bug fix for global byte array initialization
- force ld and st w/o space specifier to be generic_space
- make type_decode method of type_info_key
- adjust debug printing so listing of code and CFG information requires higher numbers (100 and 50)
- local param ld/st accesses treated like local ld/st for timing model
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6878]
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 53 | ||||
| -rw-r--r-- | src/cuda-sim/instructions.cc | 244 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.cc | 62 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 37 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_sim.cc | 13 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_sim.h | 5 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 9 |
7 files changed, 277 insertions, 146 deletions
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 2f66d51..1326ccd 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -417,6 +417,9 @@ ptx_instruction::ptx_instruction( int opcode, } m_scalar_type = scalar_type; m_space_spec = space_spec; + if( ( opcode == ST_OP || opcode == LD_OP ) && (space_spec == undefined_space) ) { + m_space_spec = generic_space; + } m_source_file = file?file:"<unknown>"; m_source_line = line; m_source = source; @@ -459,7 +462,7 @@ function_info::function_info(int entry_point ) m_kernel_info.lmem = 0; m_kernel_info.regs = 0; m_kernel_info.smem = 0; - m_local_mem_framesize = (unsigned)-1; + m_local_mem_framesize = 0; } void function_info::print_insn( unsigned pc, FILE * fp ) const @@ -531,14 +534,14 @@ void function_info::ptx_assemble() create_basic_blocks(); connect_basic_blocks(); - if ( g_debug_execution>=2 ) { + if ( g_debug_execution>=50 ) { print_basic_blocks(); print_basic_block_links(); print_basic_block_dot(); } find_postdominators(); find_ipostdominators(); - if ( g_debug_execution>=2 ) { + if ( g_debug_execution>=50 ) { print_postdominators(); print_ipostdominators(); } @@ -561,37 +564,36 @@ void gpgpu_ptx_sim_init_memory() int load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsigned max_gaddr) { - printf( "GPGPU-Sim PTX: loading global with explicit initializers... " ); + printf( "GPGPU-Sim PTX: loading globals with explicit initializers... \n" ); fflush(stdout); int ng_bytes=0; symbol_table::iterator g=symtab->global_iterator_begin(); - bool below_image=true; for ( ; g!=symtab->global_iterator_end(); g++) { symbol *global = *g; if ( global->has_initializer() ) { + printf( "GPGPU-Sim PTX: initializing '%s' ... ", global->name().c_str() ); + unsigned addr=global->get_address(); + const type_info *type = global->type(); + type_info_key ti=type->get_key(); + size_t size; + int t; + ti.type_decode(size,t); + int nbytes = size/8; + int offset=0; std::list<operand_info> init_list = global->get_initializer(); for ( std::list<operand_info>::iterator i=init_list.begin(); i!=init_list.end(); i++ ) { operand_info op = *i; ptx_reg_t value = op.get_literal_value(); - int nbytes = 0; - switch ( op.get_type() ) { - case int_t: nbytes = 4; break; - case float_op_t: nbytes = 4; break; - case double_op_t: nbytes = 8; break; - default: - abort(); - } - unsigned addr=global->get_address(); - - assert( below_image && addr+nbytes < min_gaddr ); // min_gaddr is start of "heap" for cudaMalloc - - g_global_mem->write(addr,nbytes,&value); + assert( (addr+offset+nbytes) < min_gaddr ); // min_gaddr is start of "heap" for cudaMalloc + g_global_mem->write(addr+offset,nbytes,&value); // assuming little endian here + offset+=nbytes; ng_bytes+=nbytes; } + printf(" wrote %u bytes\n", offset ); } } - printf( " done.\n"); + printf( "GPGPU-Sim PTX: finished loading globals (%u bytes total).\n", ng_bytes ); fflush(stdout); return ng_bytes; } @@ -610,7 +612,7 @@ int load_constants( symbol_table *symtab, addr_t min_gaddr ) // get the constant element data size int basic_type; size_t num_bits; - type_decode(constant->type()->get_key().scalar_type(),num_bits,basic_type); + constant->type()->get_key().type_decode(num_bits,basic_type); std::list<operand_info> init_list = constant->get_initializer(); int nbytes_written = 0; @@ -1378,20 +1380,23 @@ unsigned ptx_sim_init_thread( ptx_thread_info** thread_info,int sid,unsigned tid } std::map<unsigned,memory_space*> &local_mem_lookup = g_local_memory_lookup[sid]; + unsigned new_tid; for ( unsigned tz=0; tz < g_cudaBlockDim.z; tz++ ) { for ( unsigned ty=0; ty < g_cudaBlockDim.y; ty++ ) { for ( unsigned tx=0; tx < g_cudaBlockDim.x; tx++ ) { + new_tid = tx + g_cudaBlockDim.x*ty + g_cudaBlockDim.x*g_cudaBlockDim.y*tz; + new_tid += tid; ptx_thread_info *thd = new ptx_thread_info(); memory_space *local_mem = NULL; - std::map<unsigned,memory_space*>::iterator l = local_mem_lookup.find(tid); + std::map<unsigned,memory_space*>::iterator l = local_mem_lookup.find(new_tid); if ( l != local_mem_lookup.end() ) { local_mem = l->second; } else { char buf[512]; - snprintf(buf,512,"local_%u_%u", sid, tid); + snprintf(buf,512,"local_%u_%u", sid, new_tid); local_mem = new memory_space_impl<32>(buf,32); - local_mem_lookup[tid] = local_mem; + local_mem_lookup[new_tid] = local_mem; } thd->set_info(g_entrypoint_symbol_table,g_entrypoint_func_info); thd->set_nctaid(g_cudaGridDim.x,g_cudaGridDim.y,g_cudaGridDim.z); @@ -1835,7 +1840,7 @@ void gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ) exit(40); } - if ( g_debug_execution >= 1 ) + if ( g_debug_execution >= 100 ) print_ptx_file(p,source_num,g_filename); printf("GPGPU-Sim PTX: finished parsing EMBEDDED .ptx file %s\n",g_filename); diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 7606686..75dc072 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -74,6 +74,7 @@ #include "cuda-math.h" #include "../abstract_hardware_model.h" +#include <stdarg.h> unsigned g_num_ptx_inst_uid=0; unsigned cudasim_n_tex_insn=0; @@ -390,7 +391,7 @@ void atom_callback( void* ptx_inst, void* thd ) unsigned to_type = pI->get_type(); size_t size; int t; - type_decode(to_type, size, t); + type_info_key::type_decode(to_type, size, t); // Set up operand variables ptx_reg_t data, // d @@ -684,6 +685,45 @@ void brkpt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not extern int gpgpu_simd_model; #define POST_DOMINATOR 1 /* must match enum value in shader.h */ void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *npc, unsigned *rpc ); +void decode_space( memory_space_t &space, ptx_thread_info *thread, const operand_info &op, memory_space *&mem, addr_t &addr); + +void my_cuda_printf(const char *fmtstr,const char *arg_list) +{ + FILE *fp = stdout; + unsigned i=0,j=0; + unsigned arg_offset=0; + char buf[64]; + bool in_fmt=false; + while( fmtstr[i] ) { + char c = fmtstr[i++]; + if( !in_fmt ) { + if( c != '%' ) { + fprintf(fp,"%c",c); + } else { + in_fmt=true; + buf[0] = c; + j=1; + } + } else { + if(!( c == 'u' || c == 'f' || c == 'd' )) { + printf("GPGPU-Sim PTX: ERROR ** printf parsing support is limited to %%u, %%f, %%d at present"); + abort(); + } + buf[j] = c; + buf[j+1] = 0; + unsigned long long value = ((unsigned long long*)arg_list)[arg_offset]; + if( c == 'u' || c == 'd' ) { + fprintf(fp,buf,value); + } else if( c == 'f' ) { + double tmp = *(double*)(void*)&value; + fprintf(fp,buf,tmp); + } + arg_offset++; + in_fmt=false; + } + } +} + void call_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { @@ -709,51 +749,114 @@ void call_impl( const ptx_instruction *pI, ptx_thread_info *thread ) " call instruction and function declaration\n"); abort(); } - // read source arguements into register specified in declaration of function std::list< std::pair<const symbol*, ptx_reg_t> > arg_values; for( unsigned arg=0; arg < n_args; arg ++ ) { - const operand_info &op_info = pI->operand_lookup(n_return+1+arg); - if( !op_info.is_reg() ) { - printf("GPGPU-Sim PTX: Execution error - no support for non-register opernands for call/return\n"); - abort(); - } - const symbol *dst_reg = target_func->get_arg(arg); - - ptx_reg_t src_value = thread->get_operand_value(op_info); - arg_values.push_back( std::make_pair(dst_reg,src_value) ); - } - - // note register for corresponding return instruction to place result into - const symbol *return_var_src = NULL; - const symbol *return_var_dst = NULL; - if( target_func->has_return() ) { - if( !pI->dst().is_reg() ) { - printf("GPGPU-Sim PTX: Execution error - no support for non-register dst reg for call\n"); - abort(); - } - return_var_dst = pI->dst().get_symbol(); - return_var_src = target_func->get_return_var(); - } - - unsigned sid = thread->get_hw_sid(); - unsigned tid = thread->get_hw_tid(); - unsigned callee_pc=0, callee_rpc=0; - if( gpgpu_simd_model == POST_DOMINATOR ) { - get_pdom_stack_top_info(sid,tid,&callee_pc,&callee_rpc); - assert( callee_pc == thread->get_pc() ); + const operand_info &actual_param_op = pI->operand_lookup(n_return+1+arg); + const symbol *formal_param = target_func->get_arg(arg); + unsigned size=formal_param->get_size_in_bytes(); + if( formal_param->is_reg() ) { + ptx_reg_t value; + if( actual_param_op.is_reg() ) + value = thread->get_operand_value(actual_param_op); + else { + assert( actual_param_op.is_param_local() ); + const symbol *actual_param = actual_param_op.get_symbol(); + addr_t from_addr = thread->get_local_mem_stack_pointer() + actual_param->get_address(); + assert(size<=sizeof(value.u64)); + thread->m_local_mem->read(from_addr,size,&value.u64); + } + arg_values.push_back( std::make_pair(formal_param,value) ); + } else { + assert( formal_param->is_param_local() ); + // copy values to location in callee frame + addr_t to_addr = thread->get_local_mem_stack_pointer() + + thread->func_info()->local_mem_framesize() + + formal_param->get_address(); + if( actual_param_op.is_reg() ) { + ptx_reg_t value = thread->get_operand_value(actual_param_op); + thread->m_local_mem->write(to_addr,size,&value.u64); + } else { + addr_t from_addr = actual_param_op.get_symbol()->get_address(); + char buffer[1024]; + assert(size<1024); + thread->m_local_mem->read(from_addr,size,buffer); + thread->m_local_mem->write(to_addr,size,buffer); + } + } } - thread->callstack_push(callee_pc+1,callee_rpc,return_var_src,return_var_dst,call_uid_next++); - std::list< std::pair<const symbol*, ptx_reg_t> >::iterator a; - for( a=arg_values.begin(); a != arg_values.end(); a++ ) { - const symbol *dst_reg = a->first; - ptx_reg_t value = a->second; - thread->set_operand_value(dst_reg,value); + std::string fname = target_func->get_name(); + if( fname == "vprintf" ) { + char *fmtstr = NULL; + char *arg_list = NULL; + assert( n_args == 2 ); + for( unsigned arg=0; arg < n_args; arg ++ ) { + const operand_info &actual_param_op = pI->operand_lookup(n_return+1+arg); + const symbol *formal_param = target_func->get_arg(arg); + unsigned size=formal_param->get_size_in_bytes(); + assert( formal_param->is_param_local() ); + assert( actual_param_op.is_param_local() ); + addr_t from_addr = actual_param_op.get_symbol()->get_address(); + char buffer[1024]; + assert(size<1024); + thread->m_local_mem->read(from_addr,size,buffer); + addr_t addr = (addr_t)*(unsigned long long*)((void*)buffer); // should be pointer to generic memory location + memory_space *mem=NULL; + memory_space_t space = generic_space; + decode_space(space,thread,actual_param_op,mem,addr); // figure out which space + if( arg == 0 ) { + unsigned len = 0; + char b = 0; + do { // figure out length + mem->read(addr+len,1,&b); + len++; + } while(b); + fmtstr = (char*)malloc(len+64); + for( int i=0; i < len; i++ ) + mem->read(addr+i,1,fmtstr+i); + //mem->read(addr,len,fmtstr); + } else { + unsigned len = thread->get_finfo()->local_mem_framesize(); + arg_list = (char*)malloc(len+64); + for( int i=0; i < len; i++ ) + mem->read(addr+i,1,arg_list+i); + //mem->read(addr,len,arg_list); + } + } + my_cuda_printf(fmtstr,arg_list); + free(fmtstr); + free(arg_list); + } else { + // note register for corresponding return instruction to place result into + const symbol *return_var_src = NULL; + const symbol *return_var_dst = NULL; + if( target_func->has_return() ) { + if( pI->dst().is_reg() ) { + return_var_dst = pI->dst().get_symbol(); + return_var_src = target_func->get_return_var(); + } + } + + unsigned sid = thread->get_hw_sid(); + unsigned tid = thread->get_hw_tid(); + unsigned callee_pc=0, callee_rpc=0; + if( gpgpu_simd_model == POST_DOMINATOR ) { + get_pdom_stack_top_info(sid,tid,&callee_pc,&callee_rpc); + assert( callee_pc == thread->get_pc() ); + } + + thread->callstack_push(callee_pc+1,callee_rpc,return_var_src,return_var_dst,call_uid_next++); + + for( a=arg_values.begin(); a != arg_values.end(); a++ ) { + const symbol *dst_reg = a->first; + ptx_reg_t value = a->second; + thread->set_operand_value(dst_reg,value); + } + + thread->set_npc(target_func); } - - thread->set_npc(target_func); } void clz_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } @@ -1133,32 +1236,6 @@ ptx_reg_t (*g_cvt_fn[11][11])( ptx_reg_t x, unsigned from_width, unsigned to_wid { d2x , d2x , d2x , d2x , d2x , d2x , d2x , d2x , d2x, d2x, d2d} }; -unsigned type_decode( unsigned type, size_t &size, int &basic_type ) -{ - switch ( type ) { - case S8_TYPE: size=8; basic_type=1; return 0; - case S16_TYPE: size=16; basic_type=1; return 1; - case S32_TYPE: size=32; basic_type=1; return 2; - case S64_TYPE: size=64; basic_type=1; return 3; - case U8_TYPE: size=8; basic_type=0; return 4; - case U16_TYPE: size=16; basic_type=0; return 5; - case U32_TYPE: size=32; basic_type=0; return 6; - case U64_TYPE: size=64; basic_type=0; return 7; - case F16_TYPE: size=16; basic_type=-1; return 8; - case F32_TYPE: size=32; basic_type=-1; return 9; - case F64_TYPE: size=64; basic_type=-1; return 10; - case PRED_TYPE: size=1; basic_type=2; return 11; - case B8_TYPE: size=8; basic_type=0; return 12; - case B16_TYPE: size=16; basic_type=0; return 13; - case B32_TYPE: size=32; basic_type=0; return 14; - case B64_TYPE: size=64; basic_type=0; return 15; - default: - printf("ERROR ** type_decode() does not know about \"%s\"\n", g_ptx_token_decode[type].c_str() ); - assert(0); - return 0xDEADBEEF; - } -} - void ptx_round(ptx_reg_t& data, int rounding_mode, int type) { if (rounding_mode == RN_OPTION) { @@ -1309,8 +1386,8 @@ void cvt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) int to_sign, from_sign; size_t from_width, to_width; - unsigned src_fmt = type_decode(from_type, from_width, from_sign); - unsigned dst_fmt = type_decode(to_type, to_width, to_sign); + unsigned src_fmt = type_info_key::type_decode(from_type, from_width, from_sign); + unsigned dst_fmt = type_info_key::type_decode(to_type, to_width, to_sign); ptx_reg_t data = thread->get_operand_value(src1); if ( g_cvt_fn[src_fmt][dst_fmt] != NULL ) { @@ -1458,10 +1535,25 @@ void isspacep_impl( const ptx_instruction *pI, ptx_thread_info *thread ) thread->set_operand_value(dst,p); } -void decode_space( memory_space_t &space, ptx_thread_info *thread, memory_space *&mem, addr_t &addr) +void decode_space( memory_space_t &space, ptx_thread_info *thread, const operand_info &op, memory_space *&mem, addr_t &addr) { unsigned smid = thread->get_hw_sid(); unsigned hwtid = thread->get_hw_tid(); + + if( space == param_space_unclassified ) { + // need to op to determine whether it refers to a kernel param or local param + const symbol *s = op.get_symbol(); + const type_info *t = s->type(); + type_info_key ti = t->get_key(); + if( ti.is_param_kernel() ) + space = param_space_kernel; + else if( ti.is_param_local() ) { + space = param_space_local; + } else { + printf("GPGPU-Sim PTX: ERROR ** cannot resolve .param space for '%s'\n", s->name().c_str() ); + abort(); + } + } switch ( space ) { case global_space: mem = g_global_mem; break; case param_space_local: @@ -1474,7 +1566,7 @@ void decode_space( memory_space_t &space, ptx_thread_info *thread, memory_space case param_space_kernel: mem = g_param_mem; break; case shared_space: mem = thread->m_shared_mem; break; case const_space: mem = g_global_mem; break; - default: + case generic_space: if( thread->get_ptx_version().ver() >= 2.0 ) { // convert generic address to memory space address space = whichspace(addr); @@ -1488,6 +1580,10 @@ void decode_space( memory_space_t &space, ptx_thread_info *thread, memory_space abort(); } break; + case param_space_unclassified: + case undefined_space: + default: + abort(); } } @@ -1503,12 +1599,12 @@ void ld_impl( const ptx_instruction *pI, ptx_thread_info *thread ) memory_space *mem = NULL; addr_t addr = src1_data.u32; - decode_space(space,thread,mem,addr); + decode_space(space,thread,src1,mem,addr); size_t size; int t; data.u64=0; - type_decode(type,size,t); + type_info_key::type_decode(type,size,t); if (!vector_spec) { mem->read(addr,size/8,&data.s64); if( type == S16_TYPE || type == S32_TYPE ) @@ -2640,11 +2736,11 @@ void st_impl( const ptx_instruction *pI, ptx_thread_info *thread ) memory_space *mem = NULL; addr_t addr = addr_reg.u32; - decode_space(space,thread,mem,addr); + decode_space(space,thread,dst,mem,addr); size_t size; int t; - type_decode(type,size,t); + type_info_key::type_decode(type,size,t); if (!vector_spec) { data = thread->get_operand_value(src1); @@ -2815,7 +2911,7 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) unsigned tex_array_index; float alpha=0, beta=0; - type_decode(to_type,size,t); + type_info_key::type_decode(to_type,size,t); tex_array_base = cuArray->devPtr32; switch (dimension) { diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index 2597ac5..1bf9c95 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -364,7 +364,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident int regnum; size_t num_bits; unsigned addr, addr_pad; - type_decode(ti.scalar_type(),num_bits,basic_type); + ti.type_decode(num_bits,basic_type); bool duplicates = check_for_duplicates( identifier ); if( duplicates ) { @@ -389,7 +389,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident default: break; } - g_last_symbol = g_current_symbol_table->add_variable(identifier,type,g_filename,ptx_lineno); + g_last_symbol = g_current_symbol_table->add_variable(identifier,type,num_bits/8,g_filename,ptx_lineno); switch ( ti.get_memory_space() ) { case reg_space: { regnum = g_current_symbol_table->next_reg_num(); @@ -463,6 +463,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident assert( (num_bits%8) == 0 ); g_last_symbol->set_address( g_current_symbol_table->get_local_next() ); g_current_symbol_table->alloc_local( num_bits/8 ); + g_func_info->set_framesize( g_current_symbol_table->get_local_next() ); break; case tex_space: printf("GPGPU-Sim PTX: encountered texture directive %s.\n", identifier); @@ -476,6 +477,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident assert( (num_bits%8) == 0 ); g_last_symbol->set_address( g_current_symbol_table->get_local_next() ); g_current_symbol_table->alloc_local( num_bits/8 ); + g_func_info->set_framesize( g_current_symbol_table->get_local_next() ); break; case param_space_kernel: break; @@ -488,16 +490,6 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident if ( ti.is_param_kernel() ) { g_func_info->add_param_name_type_size(g_entry_func_param_index,identifier, ti.scalar_type(), num_bits ); g_entry_func_param_index++; - } else if ( ti.is_param_local() ) { - printf("GPGPU-Sim PTX: allocating stack frame region for input/output .param \"%s\" from 0x%x to 0x%lx\n", - identifier, - g_current_symbol_table->get_local_next(), - g_current_symbol_table->get_local_next() + num_bits/8 ); - fflush(stdout); - assert( (num_bits%8) == 0 ); - addr_t addr = g_current_symbol_table->get_local_next(); - g_last_symbol->set_address( addr ); - g_current_symbol_table->alloc_local( num_bits/8 ); } } @@ -564,7 +556,7 @@ void add_label( const char *identifier ) if ( s != NULL ) { g_label = s; } else { - g_label = g_current_symbol_table->add_variable(identifier,NULL,g_filename,ptx_lineno); + g_label = g_current_symbol_table->add_variable(identifier,NULL,0,g_filename,ptx_lineno); } } @@ -659,7 +651,7 @@ void add_scalar_operand( const char *identifier ) if ( s == NULL ) { if ( g_opcode == BRA_OP ) { // forward branch target... - s = g_current_symbol_table->add_variable(identifier,NULL,g_filename,ptx_lineno); + s = g_current_symbol_table->add_variable(identifier,NULL,0,g_filename,ptx_lineno); } else { std::string msg = std::string("operand \"") + identifier + "\" has no declaration."; parse_error( msg.c_str() ); @@ -673,7 +665,7 @@ void add_neg_pred_operand( const char *identifier ) DPRINTF("add_neg_pred_operand"); const symbol *s = g_current_symbol_table->lookup(identifier); if ( s == NULL ) { - s = g_current_symbol_table->add_variable(identifier,NULL,g_filename,ptx_lineno); + s = g_current_symbol_table->add_variable(identifier,NULL,1,g_filename,ptx_lineno); } operand_info op(s); op.set_neg_pred(); @@ -777,13 +769,13 @@ symbol *symbol_table::lookup( const char *identifier ) return NULL; } -symbol *symbol_table::add_variable( const char *identifier, const type_info *type, const char *filename, unsigned line ) +symbol *symbol_table::add_variable( const char *identifier, const type_info *type, unsigned size, const char *filename, unsigned line ) { char buf[1024]; std::string key(identifier); assert( m_symbols.find(key) == m_symbols.end() ); snprintf(buf,1024,"%s:%u",filename,line); - symbol *s = new symbol(identifier,type,buf); + symbol *s = new symbol(identifier,type,buf,size); m_symbols[ key ] = s; if ( type != NULL && type->get_key().is_global() ) { @@ -804,7 +796,7 @@ void symbol_table::add_function( function_info *func ) char buf[1024]; snprintf(buf,1024,"%s:%u",g_filename,ptx_lineno); type_info *type = add_type( func ); - symbol *s = new symbol(func->get_name().c_str(),type,buf); + symbol *s = new symbol(func->get_name().c_str(),type,buf,0); s->set_function(func); m_symbols[ func->get_name() ] = s; } @@ -828,7 +820,7 @@ bool symbol_table::add_function_decl( const char *name, int entry_point, functio } else { assert( !prior_decl ); *sym_table = new symbol_table( "", entry_point, g_global_symbol_table ); - symbol *null_reg = (*sym_table)->add_variable("_",NULL,"",0); + symbol *null_reg = (*sym_table)->add_variable("_",NULL,0,"",0); null_reg->set_regno(0, 0); (*sym_table)->set_name(name); (*func_info)->set_symtab(*sym_table); @@ -1336,3 +1328,35 @@ unsigned ptx_kernel_nregs( void *kernel_impl ) const struct gpgpu_ptx_sim_kernel_info *kernel_info = f->get_kernel_info(); return kernel_info->regs; } + +unsigned type_info_key::type_decode( size_t &size, int &basic_type ) const +{ + int type = scalar_type(); + return type_decode(type,size,basic_type); +} + +unsigned type_info_key::type_decode( int type, size_t &size, int &basic_type ) +{ + switch ( type ) { + case S8_TYPE: size=8; basic_type=1; return 0; + case S16_TYPE: size=16; basic_type=1; return 1; + case S32_TYPE: size=32; basic_type=1; return 2; + case S64_TYPE: size=64; basic_type=1; return 3; + case U8_TYPE: size=8; basic_type=0; return 4; + case U16_TYPE: size=16; basic_type=0; return 5; + case U32_TYPE: size=32; basic_type=0; return 6; + case U64_TYPE: size=64; basic_type=0; return 7; + case F16_TYPE: size=16; basic_type=-1; return 8; + case F32_TYPE: size=32; basic_type=-1; return 9; + case F64_TYPE: size=64; basic_type=-1; return 10; + case PRED_TYPE: size=1; basic_type=2; return 11; + case B8_TYPE: size=8; basic_type=0; return 12; + case B16_TYPE: size=16; basic_type=0; return 13; + case B32_TYPE: size=32; basic_type=0; return 14; + case B64_TYPE: size=64; basic_type=0; return 15; + default: + printf("ERROR ** type_decode() does not know about \"%s\"\n", g_ptx_token_decode[type].c_str() ); + assert(0); + return 0xDEADBEEF; + } +} diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 8f3d48e..4361cb0 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -113,10 +113,8 @@ public: m_is_function = 1; } - void set_array_dim( int array_dim ) - { - m_array_dim = array_dim; - } + void set_array_dim( int array_dim ) { m_array_dim = array_dim; } + int get_array_dim() const { assert(m_init); return m_array_dim; } bool is_reg() const { return m_space_spec == reg_space;} bool is_param_kernel() const { return m_space_spec == param_space_kernel;} @@ -129,6 +127,8 @@ public: bool is_tex() const { return m_space_spec == tex_space;} bool is_func_addr() const { return m_is_function?true:false; } int scalar_type() const { return m_scalar_type_spec;} + unsigned type_decode( size_t &size, int &t ) const; + static unsigned type_decode( int type, size_t &size, int &t ); memory_space_t get_memory_space() const { return m_space_spec; } private: bool m_init; @@ -184,12 +184,13 @@ class operand_info; class symbol { public: - symbol( const char *name, const type_info *type, const char *location ) + symbol( const char *name, const type_info *type, const char *location, unsigned size ) { m_uid = get_uid(); m_name = name; m_decl_location = location; m_type = type; + m_size = size; m_address_valid = false; m_is_label = false; m_is_shared = false; @@ -209,6 +210,10 @@ public: if ( type ) m_is_tex = type->get_key().is_tex(); if ( type ) m_is_func_addr = type->get_key().is_func_addr(); } + unsigned get_size_in_bytes() const + { + return m_size; + } const std::string &name() const { return m_name;} const std::string &decl_location() const { return m_decl_location;} const type_info *type() const { return m_type;} @@ -254,6 +259,11 @@ public: bool is_param_local() const { return m_is_param_local; } bool is_tex() const { return m_is_tex;} bool is_func_addr() const { return m_is_func_addr; } + bool is_reg() const { + if( m_type == NULL ) + return false; + return m_type->get_key().is_reg(); + } void add_initializer( const std::list<operand_info> &init ); bool has_initializer() const @@ -280,6 +290,7 @@ private: unsigned get_uid(); unsigned m_uid; const type_info *m_type; + unsigned m_size; // in bytes std::string m_name; std::string m_decl_location; @@ -312,7 +323,7 @@ public: void set_ptx_version( float ver, unsigned ext ); symbol* lookup( const char *identifier ); std::string get_scope_name() const { return m_scope_name; } - symbol *add_variable( const char *identifier, const type_info *type, const char *filename, unsigned line ); + symbol *add_variable( const char *identifier, const type_info *type, unsigned size, const char *filename, unsigned line ); void add_function( function_info *func ); bool add_function_decl( const char *name, int entry_point, function_info **func_info, symbol_table **symbol_table ); type_info *add_type( memory_space_t space_spec, int scalar_type_spec, int vector_spec, int alignment_spec, int extern_spec ); @@ -534,6 +545,12 @@ public: } return m_value.m_symbolic->type()->get_key().is_reg(); } + bool is_param_local() const + { + if ( m_type != symbolic_t ) + return false; + return m_value.m_symbolic->type()->get_key().is_param_local(); + } bool is_vector() const { @@ -891,7 +908,7 @@ public: { m_symtab = symtab; } - std::string get_name() + std::string get_name() const { return m_name; } @@ -1016,9 +1033,13 @@ public: } unsigned local_mem_framesize() const { - assert( m_local_mem_framesize != (unsigned) -1 ); return m_local_mem_framesize; } + void set_framesize( unsigned sz ) + { + m_local_mem_framesize = sz; + } + bool is_entry_point() const { return m_entry_point; } private: unsigned m_uid; diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc index 85e6185..dffc128 100644 --- a/src/cuda-sim/ptx_sim.cc +++ b/src/cuda-sim/ptx_sim.cc @@ -358,6 +358,7 @@ void ptx_thread_info::callstack_push( unsigned pc, unsigned rpc, const symbol *r m_last_was_call = true; m_callstack.push_back( stack_entry(m_symbol_table,m_func_info,pc,rpc,return_var_src,return_var_dst,call_uid) ); m_regs.push_back( reg_map_t() ); + m_local_mem_stack_pointer += m_func_info->local_mem_framesize(); } #define POST_DOMINATOR 1 /* must match definition in shader.h */ @@ -368,7 +369,9 @@ extern void set_operand_value( const symbol *dst, const ptx_reg_t &data ); bool ptx_thread_info::callstack_pop() { assert( !m_callstack.empty() ); + assert( m_local_mem_stack_pointer >= m_func_info->local_mem_framesize() ); m_func_info = m_callstack.back().m_func_info; + m_local_mem_stack_pointer -= m_func_info->local_mem_framesize(); m_symbol_table = m_callstack.back().m_symbol_table; m_NPC = m_callstack.back().m_PC; m_RPC_updated = true; @@ -448,16 +451,6 @@ void ptx_thread_info::dump_modifiedregs() } } -void ptx_thread_info::push_local_mem_stack() -{ - m_local_mem_stack_pointer += m_func_info->local_mem_framesize(); -} - -void ptx_thread_info::pop_local_mem_stack() -{ - m_local_mem_stack_pointer -= m_func_info->local_mem_framesize(); -} - void ptx_thread_info::set_npc( const function_info *f ) { m_NPC = f->get_start_PC(); diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h index d4bdf48..db38ced 100644 --- a/src/cuda-sim/ptx_sim.h +++ b/src/cuda-sim/ptx_sim.h @@ -423,10 +423,7 @@ public: function_info *get_finfo() { return m_func_info; } void enable_debug_trace() { m_enable_debug_trace = true; } - unsigned get_local_mem_stack_pointer() const { return m_local_mem_stack_pointer; } - void push_local_mem_stack(); - void pop_local_mem_stack(); public: addr_t m_last_effective_address; @@ -477,8 +474,6 @@ private: reg_map_t m_debug_trace_regs_modified; // track the modified register for each executed insn }; -unsigned type_decode( unsigned type, size_t &size, int &t ); - addr_t generic_to_local( unsigned smid, unsigned hwtid, addr_t addr ); addr_t generic_to_shared( unsigned smid, addr_t addr ); addr_t generic_to_global( addr_t addr ); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 3f084f8..05a8b0e 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1659,8 +1659,7 @@ inline int is_const ( memory_space_t space ) { } inline int is_local ( memory_space_t space ) { - assert( space != param_space_local ); // todo: map local param memory to linear address space - return((space) == local_space); + return (space == local_space) || (space == param_space_local); } inline int is_param ( memory_space_t space ) { @@ -2481,12 +2480,10 @@ mem_stage_stall_type send_mem_request(shader_core_ctx_t *shader, mem_access_t &a access_type = (access.iswrite)? GLOBAL_ACC_W: GLOBAL_ACC_R; break; case local_space: + case param_space_local: code = DCACHE; access_type = (access.iswrite)? LOCAL_ACC_W: LOCAL_ACC_R; break; - case param_space_local: - abort(); // todo: define mapping of local param space to linear memory ? - break; default: assert(0); // NOT A MEM SPACE; break; @@ -2837,10 +2834,10 @@ void shader_memory_queue(shader_core_ctx_t *shader, shader_queues_t *accessqs) break; case global_space: case local_space: + case param_space_local: path[i] = GLOBAL_MEM_PATH; type_counts[GLOBAL_MEM_PATH]++; break; - case param_space_local: case param_space_unclassified: abort(); // todo: define access details break; |
