From dac99ef22b4d0e238782731398626fdcf6e5a3a6 Mon Sep 17 00:00:00 2001 From: Tim Rogers Date: Wed, 20 Feb 2013 22:19:30 -0800 Subject: Merging //depot/gpgpu_sim_research/fermi_tim/... to //depot/gpgpu_sim_research/fermi/... Integrating CLs up to 15295. Descriptions of these CL's are included. *** A couple changes to aeriel-vision for warp issue plot support *** More arielvision changes to support the variable-entry length stacked bar chart *** Properly printing the right resolution of dynamic warp ids ***. Generalized the scheduler code and added detailed statistics for which warps issue each cycle. Verified the execution of the LRR scheduler - still have to get the two level scheduler to work. *** Implementing the 2lvl scehduler has it has been originally coded. LRR on both the inner and outer levels *** Adding in a debug tracing system to GPGPU-Sim. I am sick of writing debug code - then having to comment out, ifdef out or delete it to checkin. This also allows for print streams so the user can decided which traces they would like to see. Every print in GPGPU-Sim should go through this system - then it will be really easy to only get the information you want and more importantly people will (a) write and (b) checkin code that actually profiles what they are building. Reading tracefiles is superiour in many ways to single stepping since you can print the world and just vet the logfile for what you need. This also fascilitates advice from the Debugging Rules! book which states that you should never throw away a debugging tool. Having debug prints that don't get thrown away is big. *** Allowing the trace to be specified in the Make. Run Make TRACE=0 to compile the code without any traces *** Allowing prints from the performance sim to get the actual ptx instruction text *** Getting the two level scheduler to actaully work... What is released in fermi does not work at all - it effectively performs "static warp limit" from my CCWS paper. Warps are never demoted from the active list since the functionality checking to see if they are waiting on a longop is completly broken. Maybe if the original author had access to the tracing functions this would not have happened. The islongop test was completely broken. It did not mark the register as used, it marked the register number in the instruction as used. For example if this instruction was creating a long op: ld r6 [r1] It would mark register 0 as waiting for a long op (since it is register 0 of the two registers in this instruction), not register 6. Additionally, whenever ANY instruction from a warp releases registers, ALL the longops being tracked for this warp get cleared.... The only way anyone ever thought this worked is if they did not test it.... *** Reworking the warp schedulers to share common code. Making the GTX480 use gto by default. I am not sure wht they really use, but it really can't be LRR. Also adding in a new file for custom shared trace defines. These are useful when you want a print that has some additional criteria or information printed. Verified that the schedulers all work to a first order based on traces. *** Making it so you can run the stats collection scripts from any directory. Also allow the caller to specify a stats file instead of just assume its always the same one [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 15296] --- Makefile | 2 + aerialvision/guiclasses.py | 13 + aerialvision/lexyacc.py | 2 + aerialvision/organizedata.py | 9 +- configs/GTX480/gpgpusim.config | 13 +- configs/QuadroFX5800/gpgpusim.config | 5 + configs/TeslaC2050/gpgpusim.config | 12 +- cuobjdump_to_ptxplus/ptx_parser.h | 103 +++-- src/Makefile | 5 + src/cuda-sim/Makefile | 5 + src/cuda-sim/cuda-sim.cc | 16 + src/cuda-sim/cuda-sim.h | 1 + src/cuda-sim/ptx_ir.cc | 51 ++- src/cuda-sim/ptx_ir.h | 2 + src/cuda-sim/ptx_parser.cc | 82 ++-- src/gpgpu-sim/Makefile | 5 + src/gpgpu-sim/gpu-sim.cc | 25 +- src/gpgpu-sim/gpu-sim.h | 3 + src/gpgpu-sim/scoreboard.cc | 40 +- src/gpgpu-sim/scoreboard.h | 1 + src/gpgpu-sim/shader.cc | 808 ++++++++++++++++++++++------------- src/gpgpu-sim/shader.h | 206 +++++++-- src/gpgpu-sim/shader_trace.h | 74 ++++ src/trace.cc | 55 +++ src/trace.h | 79 ++++ src/trace_streams.tup | 32 ++ 26 files changed, 1203 insertions(+), 446 deletions(-) create mode 100644 src/gpgpu-sim/shader_trace.h create mode 100644 src/trace.cc create mode 100644 src/trace.h create mode 100644 src/trace_streams.tup diff --git a/Makefile b/Makefile index aa80c9f..7a9c9bd 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,8 @@ else export DEBUG=0 endif +export TRACE?=1 + NVCC_PATH=$(shellwhich nvcc) ifneq ($(shell which nvcc), "") ifeq ($(DEBUG), 1) diff --git a/aerialvision/guiclasses.py b/aerialvision/guiclasses.py index 7e2379b..0a7013b 100644 --- a/aerialvision/guiclasses.py +++ b/aerialvision/guiclasses.py @@ -1049,6 +1049,19 @@ class graphManager: Legendname.append('W' + `4*(c-2)+1` + ':' + `4*(c-1)`) BarSequence = range(0,numRows) + if yAxis == 'WarpIssueSlotBreakdown': + Legendname = [] + for c in range(0, numRows): + Legendname.append('W' + `c`) + BarSequence = range(0,numRows) + + dynamic_warp_resolution = 32 + if yAxis == 'WarpIssueDynamicIdBreakdown': + Legendname = [] + for c in range(0, numRows): + Legendname.append('W' + `dynamic_warp_resolution*c` + ":" + `dynamic_warp_resolution*(c+1)`) + BarSequence = range(0,numRows) + yoff_max = numpy.array([0.0] * numCols) for row in range(numRows-1,-1,-1): yoff_max += y[row] diff --git a/aerialvision/lexyacc.py b/aerialvision/lexyacc.py index c434619..de4e732 100644 --- a/aerialvision/lexyacc.py +++ b/aerialvision/lexyacc.py @@ -176,6 +176,8 @@ def parseMe(filename): 'LDmemlatdist':vc.variable('', 3, 0, 'stackbar'), 'STmemlatdist':vc.variable('', 3, 0, 'stackbar'), 'WarpDivergenceBreakdown':vc.variable('', 3, 0, 'stackbar'), + 'WarpIssueSlotBreakdown':vc.variable('', 3, 0, 'stackbar'), + 'WarpIssueDynamicIdBreakdown':vc.variable('', 3, 0, 'stackbar'), 'dram_writes_per_cycle':vc.variable('', 1, 0, 'scalar', float), 'dram_reads_per_cycle' :vc.variable('', 1, 0, 'scalar', float), 'gpu_stall_by_MSHRwb':vc.variable('', 1, 0, 'scalar'), diff --git a/aerialvision/organizedata.py b/aerialvision/organizedata.py index 0b547b3..090b90f 100644 --- a/aerialvision/organizedata.py +++ b/aerialvision/organizedata.py @@ -193,12 +193,12 @@ def nullOrganizedShader(nullVar, datatype_c): organized = [] #determining how many shader cores are present - for x in nullVar: + for x in reversed(nullVar): if x != 'NULL': count += 1 - else: - numPlots = count + elif count != 0: break + numPlots = count count = 0 #initializing 2D list @@ -208,6 +208,9 @@ def nullOrganizedShader(nullVar, datatype_c): #filling up list appropriately for x in range(0,(len(nullVar))): if nullVar[x] == 'NULL': + while count < numPlots: + organized[count].append(0) + count += 1 count=0 else: organized[count].append(nullVar[x]) diff --git a/configs/GTX480/gpgpusim.config b/configs/GTX480/gpgpusim.config index 9a295a3..62dd078 100644 --- a/configs/GTX480/gpgpusim.config +++ b/configs/GTX480/gpgpusim.config @@ -103,10 +103,12 @@ # Fermi has two schedulers per core -gpgpu_num_sched_per_core 2 -# Two Level Scheduler -#-gpgpu_scheduler tl:16 +# Two Level Scheduler with active and pending pools +#-gpgpu_scheduler two_level_active:6:0:1 # Loose round robbin scheduler --gpgpu_scheduler lrr +#-gpgpu_scheduler lrr +# Greedy then oldest scheduler +-gpgpu_scheduler gto # stat collection -gpgpu_memlatency_stat 14 @@ -117,3 +119,8 @@ # power model configs -power_simulation_enabled 1 -gpuwattch_xml_file gpuwattch_gtx480.xml + +# tracing functionality +#-trace_enabled 1 +#-trace_components WARP_SCHEDULER,SCOREBOARD +#-trace_sampling_core 0 diff --git a/configs/QuadroFX5800/gpgpusim.config b/configs/QuadroFX5800/gpgpusim.config index 7a2a151..81a5f1f 100644 --- a/configs/QuadroFX5800/gpgpusim.config +++ b/configs/QuadroFX5800/gpgpusim.config @@ -72,3 +72,8 @@ -gpgpu_operand_collector_num_units_sfu 8 -visualizer_enabled 0 + +# tracing functionality +#-trace_enabled 1 +#-trace_components WARP_SCHEDULER,SCOREBOARD +#-trace_sampling_core 0 diff --git a/configs/TeslaC2050/gpgpusim.config b/configs/TeslaC2050/gpgpusim.config index e161b43..3100cbc 100644 --- a/configs/TeslaC2050/gpgpusim.config +++ b/configs/TeslaC2050/gpgpusim.config @@ -106,10 +106,12 @@ # Fermi has two schedulers per core -gpgpu_num_sched_per_core 2 -# Two Level Scheduler -#-gpgpu_scheduler tl:16 +# Two Level Scheduler with active and pending pools +#-gpgpu_scheduler two_level_active:6:0:1 # Loose round robbin scheduler --gpgpu_scheduler lrr +#-gpgpu_scheduler lrr +# Greedy then oldest scheduler +-gpgpu_scheduler gto # stat collection -gpgpu_memlatency_stat 14 @@ -117,3 +119,7 @@ -enable_ptx_file_line_stats 1 -visualizer_enabled 0 +# tracing functionality +#-trace_enabled 1 +#-trace_components WARP_SCHEDULER,SCOREBOARD +#-trace_sampling_core 0 diff --git a/cuobjdump_to_ptxplus/ptx_parser.h b/cuobjdump_to_ptxplus/ptx_parser.h index f8b922b..1c96b46 100644 --- a/cuobjdump_to_ptxplus/ptx_parser.h +++ b/cuobjdump_to_ptxplus/ptx_parser.h @@ -45,7 +45,7 @@ #define ARRAY_IDENTIFIER_NO_DIM 2 #define ARRAY_IDENTIFIER 3 #define P_DEBUG 0 -#define DPRINTF(...) \ +#define PTX_PARSE_DPRINTF(...) \ if(P_DEBUG) { \ printf("(%s:%s:%u) ", __FILE__, __FUNCTION__, __LINE__); \ printf(__VA_ARGS__); \ @@ -53,7 +53,6 @@ fflush(stdout); \ } - enum _memory_space_t { undefined_space=0, reg_space, @@ -73,43 +72,43 @@ int g_error_detected; const char *g_filename = ""; int g_func_decl; -void set_symtab( void* a ) {DPRINTF(" ");} -void end_function() {DPRINTF(" ");} -void add_directive() {DPRINTF(" ");} -void add_function_arg() {DPRINTF(" ");} -void add_instruction() {DPRINTF(" ");} -void add_file( unsigned a, const char *b ) {DPRINTF(" ");} -void add_variables() {DPRINTF(" ");} -void set_variable_type() {DPRINTF(" ");} -void add_option(int a ) {DPRINTF(" ");} -void add_array_initializer() {DPRINTF(" ");} -void add_label( const char *a ) {DPRINTF(" ");} -void set_return() {DPRINTF(" ");} -void add_opcode( int a ) {DPRINTF(" ");} -void add_pred( const char *a, int b, int c ) {DPRINTF(" ");} -void add_scalar_operand( const char *a ) {DPRINTF("%s", a);} -void add_neg_pred_operand( const char *a ) {DPRINTF(" ");} -void add_address_operand( const char *a, int b ) {DPRINTF("%s", a);} -void add_address_operand2( int b ) {DPRINTF(" ");} -void change_operand_lohi( int a ) {DPRINTF(" ");} -void change_double_operand_type( int a ) {DPRINTF(" ");} -void change_operand_neg( ) {DPRINTF(" ");} -void add_double_operand( const char *a, const char *b ) {DPRINTF(" ");} -void add_1vector_operand( const char *a ) {DPRINTF(" ");} -void add_2vector_operand( const char *a, const char *b ) {DPRINTF(" ");} -void add_3vector_operand( const char *a, const char *b, const char *c ) {DPRINTF(" ");} -void add_4vector_operand( const char *a, const char *b, const char *c, const char *d ) {DPRINTF(" ");} -void add_builtin_operand( int a, int b ) {DPRINTF(" ");} -void add_memory_operand() {DPRINTF(" ");} -void change_memory_addr_space( const char *a ) {DPRINTF(" ");} -void add_literal_int( int a ) {DPRINTF(" ");} -void add_literal_float( float a ) {DPRINTF(" ");} -void add_literal_double( double a ) {DPRINTF(" ");} -void add_ptr_spec( enum _memory_space_t spec ) {DPRINTF(" ");} -void add_extern_spec() {DPRINTF(" ");} -void add_alignment_spec( int ) {DPRINTF(" ");} -void add_pragma( const char *a ) {DPRINTF(" ");} -void add_constptr(const char* identifier1, const char* identifier2, int offset) {DPRINTF(" ");} +void set_symtab( void* a ) {PTX_PARSE_DPRINTF(" ");} +void end_function() {PTX_PARSE_DPRINTF(" ");} +void add_directive() {PTX_PARSE_DPRINTF(" ");} +void add_function_arg() {PTX_PARSE_DPRINTF(" ");} +void add_instruction() {PTX_PARSE_DPRINTF(" ");} +void add_file( unsigned a, const char *b ) {PTX_PARSE_DPRINTF(" ");} +void add_variables() {PTX_PARSE_DPRINTF(" ");} +void set_variable_type() {PTX_PARSE_DPRINTF(" ");} +void add_option(int a ) {PTX_PARSE_DPRINTF(" ");} +void add_array_initializer() {PTX_PARSE_DPRINTF(" ");} +void add_label( const char *a ) {PTX_PARSE_DPRINTF(" ");} +void set_return() {PTX_PARSE_DPRINTF(" ");} +void add_opcode( int a ) {PTX_PARSE_DPRINTF(" ");} +void add_pred( const char *a, int b, int c ) {PTX_PARSE_DPRINTF(" ");} +void add_scalar_operand( const char *a ) {PTX_PARSE_DPRINTF("%s", a);} +void add_neg_pred_operand( const char *a ) {PTX_PARSE_DPRINTF(" ");} +void add_address_operand( const char *a, int b ) {PTX_PARSE_DPRINTF("%s", a);} +void add_address_operand2( int b ) {PTX_PARSE_DPRINTF(" ");} +void change_operand_lohi( int a ) {PTX_PARSE_DPRINTF(" ");} +void change_double_operand_type( int a ) {PTX_PARSE_DPRINTF(" ");} +void change_operand_neg( ) {PTX_PARSE_DPRINTF(" ");} +void add_double_operand( const char *a, const char *b ) {PTX_PARSE_DPRINTF(" ");} +void add_1vector_operand( const char *a ) {PTX_PARSE_DPRINTF(" ");} +void add_2vector_operand( const char *a, const char *b ) {PTX_PARSE_DPRINTF(" ");} +void add_3vector_operand( const char *a, const char *b, const char *c ) {PTX_PARSE_DPRINTF(" ");} +void add_4vector_operand( const char *a, const char *b, const char *c, const char *d ) {PTX_PARSE_DPRINTF(" ");} +void add_builtin_operand( int a, int b ) {PTX_PARSE_DPRINTF(" ");} +void add_memory_operand() {PTX_PARSE_DPRINTF(" ");} +void change_memory_addr_space( const char *a ) {PTX_PARSE_DPRINTF(" ");} +void add_literal_int( int a ) {PTX_PARSE_DPRINTF(" ");} +void add_literal_float( float a ) {PTX_PARSE_DPRINTF(" ");} +void add_literal_double( double a ) {PTX_PARSE_DPRINTF(" ");} +void add_ptr_spec( enum _memory_space_t spec ) {PTX_PARSE_DPRINTF(" ");} +void add_extern_spec() {PTX_PARSE_DPRINTF(" ");} +void add_alignment_spec( int ) {PTX_PARSE_DPRINTF(" ");} +void add_pragma( const char *a ) {PTX_PARSE_DPRINTF(" ");} +void add_constptr(const char* identifier1, const char* identifier2, int offset) {PTX_PARSE_DPRINTF(" ");} /*non-dummy stuff below this point*/ @@ -127,7 +126,7 @@ bool inTexDirective = false; void add_identifier( const char *a, int b, unsigned c ) { - DPRINTF("name=%s", a); + PTX_PARSE_DPRINTF("name=%s", a); if(inConstDirective){ //g_headerList->getListEnd() } @@ -135,7 +134,7 @@ void add_identifier( const char *a, int b, unsigned c ) { void add_function_name( const char *headerInput ) { - DPRINTF("name=%s", headerInput); + PTX_PARSE_DPRINTF("name=%s", headerInput); char* headerInfo = (char*) headerInput; std::string compareString = g_headerList->getListEnd().getBase(); @@ -149,7 +148,7 @@ void add_function_name( const char *headerInput ) //void add_space_spec(int headerInput) void add_space_spec( enum _memory_space_t spec, int value ) { - DPRINTF("spec=%u", spec); + PTX_PARSE_DPRINTF("spec=%u", spec); cuobjdumpInst *instEntry; //static int constmemindex=1; switch(spec) @@ -187,7 +186,7 @@ void add_space_spec( enum _memory_space_t spec, int value ) void add_scalar_type_spec( int headerInput ) { - DPRINTF(" "); + PTX_PARSE_DPRINTF(" "); //const char* compareString = g_headerList->getListEnd().getBase(); if( (inEntryDirective && inParamDirective) || inTexDirective || inConstDirective) @@ -252,7 +251,7 @@ void add_scalar_type_spec( int headerInput ) //void version_header(double versionNumber) void add_version_info( float versionNumber, unsigned ext) { - DPRINTF(" "); + PTX_PARSE_DPRINTF(" "); cuobjdumpInst *instEntry = new cuobjdumpInst(); instEntry->setBase(".version"); g_headerList->add(instEntry); @@ -269,7 +268,7 @@ void add_version_info( float versionNumber, unsigned ext) void target_header(char* firstTarget) { - DPRINTF("%s", firstTarget); + PTX_PARSE_DPRINTF("%s", firstTarget); cuobjdumpInst *instEntry = new cuobjdumpInst(); instEntry->setBase(".target"); g_headerList->add(instEntry); @@ -279,7 +278,7 @@ void target_header(char* firstTarget) void target_header2(char* firstTarget, char* secondTarget) { - DPRINTF("%s, %s", firstTarget, secondTarget); + PTX_PARSE_DPRINTF("%s, %s", firstTarget, secondTarget); cuobjdumpInst *instEntry = new cuobjdumpInst(); instEntry->setBase(".target"); g_headerList->add(instEntry); @@ -291,7 +290,7 @@ void target_header2(char* firstTarget, char* secondTarget) void target_header3(char* firstTarget, char* secondTarget, char* thirdTarget) { - DPRINTF("%s, %s, %s", firstTarget, secondTarget, thirdTarget); + PTX_PARSE_DPRINTF("%s, %s, %s", firstTarget, secondTarget, thirdTarget); cuobjdumpInst *instEntry = new cuobjdumpInst(); instEntry->setBase(".target"); g_headerList->add(instEntry); @@ -305,20 +304,20 @@ void target_header3(char* firstTarget, char* secondTarget, char* thirdTarget) void start_function( int a ) { - DPRINTF(" "); + PTX_PARSE_DPRINTF(" "); inEntryDirective = true; } void* reset_symtab() { - DPRINTF(" "); + PTX_PARSE_DPRINTF(" "); inEntryDirective = false; return (void*) NULL; } void func_header(const char* headerBase) { - DPRINTF("%s", headerBase); + PTX_PARSE_DPRINTF("%s", headerBase); // If start of an entry if((strcmp(headerBase, ".entry")==0)||(strcmp(headerBase, ".func")==0)) { inEntryDirective = true; @@ -332,7 +331,7 @@ void func_header(const char* headerBase) void func_header_info(const char* headerInfo) { - DPRINTF("%s", headerInfo); + PTX_PARSE_DPRINTF("%s", headerInfo); //const char* compareString = g_headerList->getListEnd().getBase(); if(inEntryDirective && !inTexDirective) { @@ -360,7 +359,7 @@ void func_header_info(const char* headerInfo) void func_header_info_int(const char* s, int i) { - DPRINTF("%s %d", s, i); + PTX_PARSE_DPRINTF("%s %d", s, i); if(inEntryDirective && !inTexDirective) { g_headerList->getListEnd().addOperand(s); char *buff = (char*) malloc(30*sizeof(char)); diff --git a/src/Makefile b/src/Makefile index b20186c..cc31764 100644 --- a/src/Makefile +++ b/src/Makefile @@ -30,6 +30,7 @@ # GPGPU-Sim Makefile DEBUG?=0 +TRACE?=1 include ../version_detection.mk @@ -40,6 +41,10 @@ ifeq ($(GNUC_CPP0X), 1) CXXFLAGS += -std=c++0x endif +ifeq ($(TRACE),1) + CXXFLAGS += -DTRACING_ON=1 +endif + ifneq ($(DEBUG),1) OPTFLAGS += -O3 else diff --git a/src/cuda-sim/Makefile b/src/cuda-sim/Makefile index 3062d99..9e37fe7 100644 --- a/src/cuda-sim/Makefile +++ b/src/cuda-sim/Makefile @@ -30,6 +30,7 @@ default: libgpgpu_ptx_sim.a INTEL=0 DEBUG?=0 +TRACE?=0 CPP = g++ $(SNOW) CC = gcc $(SNOW) @@ -47,6 +48,10 @@ endif OPT += -I$(CUDA_INSTALL_PATH)/include OPT += -fPIC +ifeq ($(TRACE),1) + OPT += -DTRACING_ON=1 +endif + CXX_OPT = $(OPT) ifeq ($(INTEL),1) CXX_OPT += -std=c++0x diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index cf64e82..1dbff50 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -450,6 +450,22 @@ void ptx_print_insn( address_type pc, FILE *fp ) assert( finfo ); finfo->print_insn(pc,fp); } + +std::string ptx_get_insn_str( address_type pc ) +{ + std::map::iterator f = g_pc_to_finfo.find(pc); + if( f == g_pc_to_finfo.end() ) { + #define STR_SIZE 255 + char buff[STR_SIZE]; + buff[STR_SIZE - 1] = '\0'; + snprintf(buff, STR_SIZE,"", pc ); + return std::string(buff); + } + function_info *finfo = f->second; + assert( finfo ); + return finfo->get_insn_str(pc); +} + void ptx_instruction::set_fp_or_int_archop(){ op2=UN_OP; if((m_opcode == MEMBAR_OP)||(m_opcode == SSY_OP )||(m_opcode == BRA_OP) || (m_opcode == BAR_OP) || (m_opcode == RET_OP) || (m_opcode == RETP_OP) || (m_opcode == NOP_OP) || (m_opcode == EXIT_OP) || (m_opcode == CALLP_OP) || (m_opcode == CALL_OP)){ diff --git a/src/cuda-sim/cuda-sim.h b/src/cuda-sim/cuda-sim.h index bcc36d1..261d458 100644 --- a/src/cuda-sim/cuda-sim.h +++ b/src/cuda-sim/cuda-sim.h @@ -75,6 +75,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, const warp_inst_t *ptx_fetch_inst( address_type pc ); const struct gpgpu_ptx_sim_kernel_info* ptx_sim_kernel_info(const class function_info *kernel); void ptx_print_insn( address_type pc, FILE *fp ); +std::string ptx_get_insn_str( address_type pc ); void set_param_gpgpu_num_shaders(int num_shaders); diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index 29f6ff4..0dffe70 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -35,9 +35,12 @@ #include #include #include +#include "assert.h" #include "cuda-sim.h" +#define STR_SIZE 1024 + unsigned symbol::sm_next_uid = 1; unsigned symbol::get_uid() @@ -1188,14 +1191,26 @@ void ptx_instruction::print_insn() const void ptx_instruction::print_insn( FILE *fp ) const { - char buf[1024], *p; - snprintf(buf,1024,"%s", m_source.c_str()); - p = strtok(buf,";"); - if( !is_label() ) - fprintf(fp," PC=0x%03x ", m_PC ); - else - fprintf(fp," " ); - fprintf(fp,"(%s:%u) %s", m_source_file.c_str(), m_source_line, p ); + fprintf( fp, to_string().c_str() ); +} + +std::string ptx_instruction::to_string() const +{ + std::string result( m_source ); + unsigned semi_c_pos = result.find(";"); + assert( semi_c_pos != std::string::npos ); + if( !is_label() ) { + char buf[ STR_SIZE ]; + buf[ STR_SIZE - 1 ] = '\0'; + snprintf( buf, STR_SIZE, " PC=0x%03x ", m_PC ); + result += std::string( buf ); + } else + result += std::string(" "); + char buf[STR_SIZE]; + buf[STR_SIZE - 1] = '\0'; + snprintf( buf, STR_SIZE, + "(%s:%d) %s", m_source_file.c_str(), m_source_line, m_source.c_str() + semi_c_pos ); + return result; } unsigned function_info::sm_next_uid = 1; @@ -1240,6 +1255,26 @@ unsigned function_info::print_insn( unsigned pc, FILE * fp ) const return inst_size; } +std::string function_info::get_insn_str( unsigned pc ) const +{ + unsigned index = pc - m_start_PC; + if ( index >= m_instr_mem_size ) { + char buff[STR_SIZE]; + buff[STR_SIZE-1] = '\0'; + snprintf(buff, STR_SIZE, "", m_start_PC + m_instr_mem_size - 1 ); + return std::string(buff); + } else { + if ( m_instr_mem[index] != NULL ) { + return m_instr_mem[index]->to_string(); + } else { + char buff[STR_SIZE]; + buff[STR_SIZE-1] = '\0'; + snprintf(buff, STR_SIZE, "", pc ); + return std::string(buff); + } + } +} + void gpgpu_ptx_assemble( std::string kname, void *kinfo ) { function_info *func_info = (function_info *)kinfo; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 547372d..9a24e47 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -786,6 +786,7 @@ public: void print_insn() const; virtual void print_insn( FILE *fp ) const; + std::string to_string() const; unsigned inst_size() const { return m_inst_size; } unsigned uid() const { return m_uid;} int get_opcode() const { return m_opcode;} @@ -1052,6 +1053,7 @@ public: return m_name; } unsigned print_insn( unsigned pc, FILE * fp ) const; + std::string get_insn_str( unsigned pc ) const; void add_inst( const std::list &instructions ) { m_instructions = instructions; diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index d33007b..a02832d 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -74,7 +74,7 @@ std::list g_operands; std::list g_options; std::list g_scalar_type; -#define DPRINTF(...) \ +#define PTX_PARSE_DPRINTF(...) \ if( g_debug_ir_generation ) { \ printf(" %s:%u => ",g_filename,ptx_lineno); \ printf(" (%s:%u) ", __FILE__, __LINE__); \ @@ -126,7 +126,7 @@ symbol_table *init_parser( const char *ptx_filename ) void init_directive_state() { - DPRINTF("init_directive_state"); + PTX_PARSE_DPRINTF("init_directive_state"); g_space_spec=undefined_space; g_ptr_spec=undefined_space; g_scalar_type_spec=-1; @@ -141,7 +141,7 @@ void init_directive_state() void init_instruction_state() { - DPRINTF("init_instruction_state"); + PTX_PARSE_DPRINTF("init_instruction_state"); g_pred = NULL; g_neg_pred = 0; g_pred_mod = -1; @@ -156,7 +156,7 @@ static int g_entry_point; void start_function( int entry_point ) { - DPRINTF("start_function"); + PTX_PARSE_DPRINTF("start_function"); init_directive_state(); init_instruction_state(); g_entry_point = entry_point; @@ -170,7 +170,7 @@ int g_add_identifier_cached__array_ident; void add_function_name( const char *name ) { - DPRINTF("add_function_name %s %s", name, ((g_entry_point==1)?"(entrypoint)":((g_entry_point==2)?"(extern)":""))); + PTX_PARSE_DPRINTF("add_function_name %s %s", name, ((g_entry_point==1)?"(entrypoint)":((g_entry_point==2)?"(extern)":""))); bool prior_decl = g_global_symbol_table->add_function_decl( name, g_entry_point, &g_func_info, &g_current_symbol_table ); if( g_add_identifier_cached__identifier ) { add_identifier( g_add_identifier_cached__identifier, @@ -189,7 +189,7 @@ void add_function_name( const char *name ) void add_directive() { - DPRINTF("add_directive"); + PTX_PARSE_DPRINTF("add_directive"); init_directive_state(); } @@ -197,7 +197,7 @@ void add_directive() void end_function() { - DPRINTF("end_function"); + PTX_PARSE_DPRINTF("end_function"); init_directive_state(); init_instruction_state(); @@ -207,7 +207,7 @@ void end_function() gpgpu_ptx_assemble( g_func_info->get_name(), g_func_info ); g_current_symbol_table = g_global_symbol_table; - DPRINTF("function %s, PC = %d\n", g_func_info->get_name().c_str(), g_func_info->get_start_PC()); + PTX_PARSE_DPRINTF("function %s, PC = %d\n", g_func_info->get_name().c_str(), g_func_info->get_start_PC()); } #define parse_error(msg, ...) parse_error_impl(__FILE__,__LINE__, msg, ##__VA_ARGS__) @@ -265,7 +265,7 @@ const ptx_instruction *ptx_instruction_lookup( const char *filename, unsigned li void add_instruction() { - DPRINTF("add_instruction: %s", ((g_opcode>0)?g_opcode_string[g_opcode]:"