OpenCores
URL https://opencores.org/ocsvn/or2k/or2k/trunk

Subversion Repositories or2k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 21 to Rev 22
    Reverse comparison

Rev 21 → Rev 22

/or2k/trunk/analysis-bin/insnanalysis/insnanalysis.h
1,11 → 1,16
/*
Header for instruction analysis program.
 
Define instruction sets here
Have appropriate defines/typedefs for desired instruction set.
 
Todo: #ifdefs for other instruction sets
 
*/
 
// Settings for or1k 32-bit instruction analysis
 
 
// OpenRISC 1000 32-bit compiler output analysis settings:
 
#include "stdint.h"
#include "or1k-32-insn.h"
 
/or2k/trunk/analysis-bin/insnanalysis/or1k-32-insn.c
13,14 → 13,21
#include "assert.h"
#include "or1k-32-insn.h"
 
// These should also be in insnanalysis.h insnanalysis.h
// Define the appropriate instruction type, and instruction_properties type
// These should also be defined in insnanalysis.h
typedef uint32_t instruction;
typedef struct or1k_32_instruction_properties instruction_properties ;
 
#include "insn-lists.h"
 
// Enable debug printf'ing straight to stdout -- will be a LOT of output
#define DEBUG_PRINT 0
 
// Choose the output format, uncomment only one
//#define DISPLAY_STRING
#define DISPLAY_CSV
 
 
// Variable to keep track of unique instructions we have
int num_setup_insns;
int num_seen_insns;
31,6 → 38,11
// analysis.
int or1k_32_recent_insns[OR1K_MAX_GROUPINGS_ANALYSIS];
 
// Function to take the raw binary instruction, and configure the insn_props
// struct with the appropriate settings for that instruction (string, attributes
// etc.)
// TODO: vector instructions aren't picked up - but compiler never generates
// them, so not a big issue.
int or1k_32_analyse_insn(uint32_t insn,
struct or1k_32_instruction_properties * insn_props)
{
989,7 → 1001,9
}
 
 
 
// Entry point for statistics collection.
// Passed binary copy of instruction, and pointer to properties struct
// Each function that can collect staistics is called.
void or1k_32_collect_stats(uint32_t insn,
struct or1k_32_instruction_properties * insn_props)
{
1039,6 → 1053,7
// List management/analysis functions - accessed through insn_lists() set of
// functions
 
// Clear the list structs
void or1k_32_insn_lists_init(void)
{
num_setup_insns = 0;
1154,7 → 1169,7
 
 
 
// Do the n-tuple set analysis for the most recently added instruction
// Do the n-tuple set checking for the current instruction
void or1k_32_ntuple_add(int n,
struct or1k_32_instruction_properties *insn_props)
{
1170,7 → 1185,8
// Get the number of sets for these n-tuple groups we've seen so far.
int sets_for_ntuple = insn_info->groupings[n-1][0][0];
#if DEBUG_PRINT
printf("%s\t:\t%d-tuple add - sets so far : %d\n",insn_info->insn_string, n, sets_for_ntuple);
printf("%s\t:\t%d-tuple add - sets so far : %d\n",
insn_info->insn_string, n, sets_for_ntuple);
#endif
 
int set_match_index;
1181,7 → 1197,8
// now find if the current n instructions in or1k_32_recent_insns[] matches
// any set of n instructions we're keeping track of in groupings[][][].
#if DEBUG_PRINT
printf("%s\tChecking\t%d\tsets for ntuple:\t",insn_info->insn_string,sets_for_ntuple);
printf("%s\tChecking\t%d\tsets for ntuple:\t",
insn_info->insn_string,sets_for_ntuple);
for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
printf("%s ",
or1k_32_insns[(or1k_32_recent_insns[n - 1 - tuple_set_itr])]->insn_string);
1256,8 → 1273,8
}
}
// Debugging :
#if DEBUG_PRINT
// Verbose announcement of found instruction
if (tuple_set_match)
{
printf("%s\t:\tMatch for %d-tuple - set %d - cnt: %d - ",
1282,15 → 1299,18
 
}
 
 
#define DISPLAY_STRING
//#define DISPLAY_CSV
 
// Generate a list for the most-frequently seen instructions
void or1k_32_most_freq_insn(FILE * stream)
{
// Print out most frequent instruction
int i, largest, largest_index;
int instructions_to_print = num_setup_insns;
 
#ifdef DISPLAY_CSV
fprintf(stream,"\"Most frequent instructions, descending\",\n");
fprintf(stream,"\"Instruction\",\"Occurances\",\"Frequency\",\n");
#endif
 
while (instructions_to_print)
{
--instructions_to_print;
1324,14 → 1344,128
}
 
 
// Print out top x of each kept statistic for the requested instruction
void or1k_32_insn_top_x(struct or1k_insn_info *insn_info, FILE * stream,
// Generate a list for the most-frequently seen n-tuple set
void or1k_32_most_freq_ntuple(int n, FILE * stream, int max_stats)
{
 
fprintf(stream,
#ifdef DISPLAY_STRING
"Top %d %d-tuple groupings of instructions\n",
#endif
#ifdef DISPLAY_CSV
"\"Top %d %d-tuple groupings of instructions\",\n",
#endif
max_stats, n);
 
// First get a copy of all the n-tuple values for each applicable
// instruction.
int set_counts[OR1K_32_MAX_INSNS][OR1K_MAX_ENTRIES_PER_GROUP];
int insn_index;
int set_index;
int num_sets;
struct or1k_insn_info *insn_info;
 
// Copy each instruction's set totals into our local array
for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
{
if (or1k_32_insns[insn_index] != NULL)
{
insn_info = or1k_32_insns[insn_index];
num_sets = insn_info->groupings[n-1][0][0];
for(set_index=0;set_index<num_sets;set_index++)
set_counts[insn_index][set_index] =
insn_info->groupings[n-1][set_index+1][n];
}
}
// Go through the set numbers, look at the most frequent one, print it out
// clear its count and continue
 
int largest_insn_index, largest_set_index, largest_count;
int tuple_set_itr;
 
 
#ifdef DISPLAY_CSV
for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
fprintf(stream, "\"insn%d\",",n-1-tuple_set_itr);
fprintf(stream, "\"count\",\n");
#endif
 
while(max_stats--)
{
largest_count = 0;
// Go through each instruction we have
for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
{
if (or1k_32_insns[insn_index] != NULL)
{
insn_info = or1k_32_insns[insn_index];
// Get the total number of sets for the n-tup. of this instruction
num_sets = insn_info->groupings[n-1][0][0];
for(set_index=0;set_index<num_sets;set_index++)
{
// Go through each set, check if it's largest
if (set_counts[insn_index][set_index] >
largest_count)
{
largest_insn_index = insn_index;
largest_set_index = set_index;
largest_count = set_counts[insn_index][set_index];
}
}
}
}
// Have indexes of the next largest n-tuple, print it out.
insn_info = or1k_32_insns[largest_insn_index];
#ifdef DISPLAY_STRING
fprintf(stream,"set :");
#endif
 
// insn_info->insn_string, n, set_match_index,
// insn_info->groupings[n-1][set_match_index+1][n]);
for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
fprintf(stream,
#ifdef DISPLAY_STRING
" %s",
#endif
#ifdef DISPLAY_CSV
"\"%s\",",
#endif
or1k_32_insns[(insn_info->groupings[n-1][largest_set_index][tuple_set_itr])]->insn_string);
fprintf(stream,
#ifdef DISPLAY_STRING
"\tcount: %d\n",
#endif
#ifdef DISPLAY_CSV
"%d,\n",
#endif
set_counts[largest_insn_index][largest_set_index]);
// Remove this value from getting selected from largest again
set_counts[largest_insn_index][largest_set_index] = -1;
}
 
}
 
 
 
 
// Print out top n of each kept statistic for the requested instruction
void or1k_32_insn_top_n(struct or1k_insn_info *insn_info, FILE * stream,
int max_stats)
{
int i, j, largest_i;
fprintf(stream,
"Insn: \"%s\" statistics (%d times (%f%%)):\n",
#ifdef DISPLAY_STRING
"Insn: \"%s\" statistics (%d times (%f%%))\n",
#endif
#ifdef DISPLAY_CSV
"\"Insn:\",\"%s\",\"occurances:\",%d,%f\n",
#endif
insn_info->insn_string,
insn_info->count,
(float)(((float)((insn_info)->count))/
1345,7 → 1479,14
// Print out top max_stats branch targets
if (insn_info->has_branchtarg)
{
fprintf(stream,"Branch values:\n");
fprintf(stream,
#ifdef DISPLAY_STRING
"Branch values:\n"
#endif
#ifdef DISPLAY_CSV
"\"branch distance\",\"occurances\"\n"
#endif
);
i = 0;
while(i<insn_info->branch_info.count && i < max_stats)
{
1357,7 → 1498,12
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"value:\t0x%x\tcount:\t%d\n",
#endif
#ifdef DISPLAY_CSV
"0x%x,%d\n",
#endif
insn_info->branch_info.values[largest_i][0],
insn_info->branch_info.values[largest_i][1]);
insn_info->branch_info.values[largest_i][1] = -1; // clear this one
1366,7 → 1512,14
}
if (insn_info->has_imm)
{
fprintf(stream,"Immediate values:\n");
fprintf(stream,
#ifdef DISPLAY_STRING
"Immediate values:\n"
#endif
#ifdef DISPLAY_CSV
"\"immediate value\",\"count\"\n"
#endif
);
i = 0;
while(i<insn_info->imm_info.count && i < max_stats)
{
1378,7 → 1531,12
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"value:\t0x%x\tcount:\t%d\n",
#endif
#ifdef DISPLAY_CSV
"0x%x,%d\n",
#endif
insn_info->imm_info.values[largest_i][0],
insn_info->imm_info.values[largest_i][1]);
insn_info->imm_info.values[largest_i][1] = -1; // clear this one
1385,9 → 1543,17
i++;
}
}
 
if (insn_info->has_rD)
{
fprintf(stream,"rD usage:\n");
fprintf(stream,
#ifdef DISPLAY_STRING
"rD usage:\n"
#endif
#ifdef DISPLAY_CSV
"\"rD\",\"count\"\n"
#endif
);
i = 0;
while(i<32 && i < max_stats)
{
1403,7 → 1569,12
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"r%d\tcount:\t%d\n",
#endif
#ifdef DISPLAY_CSV
"\"r%d\",%d\n",
#endif
largest_i,
insn_info->rD_use_freq[largest_i]);
insn_info->rD_use_freq[largest_i] = -1; // clear this one
1413,7 → 1584,14
 
if (insn_info->has_rA)
{
fprintf(stream,"rA usage:\n");
fprintf(stream,
#ifdef DISPLAY_STRING
"rA usage:\n"
#endif
#ifdef DISPLAY_CSV
"\"rA\",\"count\"\n"
#endif
);
i = 0;
while(i<32 && i < max_stats)
{
1430,7 → 1608,12
 
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"r%d\tcount:\t%d\n",
#endif
#ifdef DISPLAY_CSV
"\"r%d\",%d\n",
#endif
largest_i,
insn_info->rA_use_freq[largest_i]);
insn_info->rA_use_freq[largest_i] = -1; // clear this one
1440,7 → 1623,14
if (insn_info->has_rB)
{
fprintf(stream,"rB usage:\n");
fprintf(stream,
#ifdef DISPLAY_STRING
"rB usage:\n"
#endif
#ifdef DISPLAY_CSV
"\"rB\",\"count\"\n"
#endif
);
i = 0;
while(i<32 && i < max_stats)
{
1457,7 → 1647,12
// largest_i has index of most frequent value
fprintf(stream,
#ifdef DISPLAY_STRING
"r%d\tcount:\t%d\n",
#endif
#ifdef DISPLAY_CSV
"\"r%d\",%d\n",
#endif
largest_i,
insn_info->rB_use_freq[largest_i]);
insn_info->rB_use_freq[largest_i] = -1; // clear this one
1475,28 → 1670,35
// Maximum number we'll print out
#define MAX_NTUPLE_LISTING 5
 
 
int (*ntuplelist)[OR1K_MAX_GROUPINGS_ANALYSIS+1];
int *set;
int set_count, set_count2;
 
// Get total number of sets for this n-tuple, eg:
// if n=2 (pairs) then groupings[1] is where our list is, and we store the number
// of sets in [0][0] of that n-tuple data.
// if n=2 (pairs) then groupings[1] is where our list is, and we store the
// number of sets in [0][0] of that n-tuple data.
int total_sets_for_ntuple = insn_info->groupings[n-1][0][0];
 
if (total_sets_for_ntuple == 0)
return;
 
fprintf(stream, "%d-tuple groupings finishing with %s (%d)\n",n, insn_info->insn_string,
total_sets_for_ntuple);
fprintf(stream,
#ifdef DISPLAY_STRING
"%d-tuple groupings finishing with %s (%d)\n",
#endif
#ifdef DISPLAY_CSV
"\"%d-tuple groupings\",\n",
#endif
n, insn_info->insn_string, total_sets_for_ntuple);
 
 
// Debug - dump out all of the info for the sets
#if DEBUG_PRINT
for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
{
 
printf("set: %d - count %d - set: ", set_count, insn_info->groupings[n-1][set_count+1][n]);
printf("set: %d - count %d - set: ", set_count,
insn_info->groupings[n-1][set_count+1][n]);
for(set_count2=0;set_count2<n;set_count2++)
fprintf(stream, "%s\t",
1507,8 → 1709,8
 
// A pointer to the n-tuple sets
// This is actually a pointer to a 2-dimensional integer array, looking like:
// [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1], so in 2-dimensional
// array pointer fashion, we should provide the "column" sizing.
// [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1], so in
// 2-dimensional array pointer fashion, we should provide the "column" sizing.
ntuplelist = insn_info->groupings[n-1];
// Let's make a copy of the counts for each... so we don't trash them
1521,10 → 1723,9
{
// Pointer to a set's data
set = ntuplelist[set_count+1];
// Fish out the copy (0 to n-1 will be the instruction index, n will be the count)
// Fish out the copy (0 to n-1 will be the instruction index, n will be
// the count)
set_count_copy[set_count+1] = set[n];
//printf("Set %d, count %d (%d) (%d)\n", set_count+1, set_count_copy[set_count+1],
//set[n], insn_info->groupings[n-1][set_count+1][n] );
}
// Now go through, finding the most frequent n-tuple of instructions and
1543,14 → 1744,35
set = (int*)ntuplelist[largest_indx+1];
 
// Print out the sequence of prior isntructions
#ifdef DISPLAY_STRING
fprintf(stream,"Seq:\t");
#endif
#ifdef DISPLAY_CSV
for(set_count2=0;set_count2<n;set_count2++)
fprintf(stream, "\"insn%d\",",n-1-set_count2);
fprintf(stream, "\"count\",\n");
#endif
// Go through the indexes of the previous instructions, get their
// strings, and print them out
for(set_count2=0;set_count2<n;set_count2++)
fprintf(stream, "%s\t", or1k_32_insns[(set[set_count2])]->insn_string);
fprintf(stream,
#ifdef DISPLAY_STRING
"%s\t",
#endif
#ifdef DISPLAY_CSV
"\"%s\",",
#endif
or1k_32_insns[(set[set_count2])]->insn_string);
// now print out the occurances
fprintf(stream, "\t%d\ttimes (%f%%)\n", set[n],
fprintf(stream,
#ifdef DISPLAY_STRING
"\t%d\ttimes (%f%%)\n",
#endif
#ifdef DISPLAY_CSV
"%d,\n",
#endif
set[n],
(float)((float)set[n]/(float)insn_info->count)*100.0f);
// done printing this one out.. let's clear its count
1574,12 → 1796,14
or1k_32_generate_ntuple_stats(n, insn_info, stream);
 
}
 
// Entry point for statistics generation.
void or1k_32_generate_stats(FILE * stream)
{
#ifdef DISPLAY_STRING
// Generate some useful things
fprintf(stream, "Analysis output:\n");
#endif
//
 
// Print out all stats for every instruction we saw!
1588,15 → 1812,24
{
if (or1k_32_insns[insn_index] != NULL)
{
or1k_32_insn_top_x(or1k_32_insns[insn_index],stream,10);
or1k_32_insn_top_n(or1k_32_insns[insn_index],stream,10);
or1k_32_generate_groupings_stats(or1k_32_insns[insn_index],stream);
#ifdef DISPLAY_STRING
fprintf(stream, "\t---\t---\t---\t---\n");
#endif
}
}
 
// print out most frequent n-tuple
int ntuple;
for(ntuple=2;ntuple<5;ntuple++)
or1k_32_most_freq_ntuple(ntuple, stream, 10);
// Do most frequent instruction analysis -- note this trashes instruction
// frequency count - should be fixed
#ifdef DISPLAY_STRING
fprintf(stream, "Individual instruction frequency:\n");
#endif
or1k_32_most_freq_insn(stream);
}
/or2k/trunk/analysis-bin/insnanalysis/or1k-32-insn.h
60,7 → 60,7
 
// Set maximum instructions in a row we'll keep track of, starting at pairs
#define OR1K_MAX_GROUPINGS_ANALYSIS 4
#define OR1K_MAX_ENTRIES_PER_GROUP 300
#define OR1K_MAX_ENTRIES_PER_GROUP 500
// Format of grouping data:
//
// 1st dimension: A list for each n-tuple group we're keeping track of
/or2k/trunk/analysis-bin/insnanalysis/insnanalysis.c
67,12 → 67,15
filesize_bytes = ftell(fp);
filesize_insns = filesize_bytes / INSN_SIZE_BYTES;
 
#ifdef DISPLAY_STRING
printf("\nAnalysing file:\t%s\tSize: %d MB\n",
argv[1],((filesize_bytes/1024)/1024));
#endif
 
// Reset pointer
rewind(fp);
 
 
instruction * insn = (instruction *)insn_buff;
 
instruction_properties insn_props;
81,7 → 84,7
// What is one-percent of instructions
float file_one_percent = ((float)filesize_insns / 100.0f );
float percent_of_percent=0; int percent;
float percent_of_percent=0; int percent=0;
 
insn_lists_init();
 
129,8 → 132,10
 
fclose(fp);
fprintf(stderr, "\rDone\n", percent);
#ifdef DISPLAY_STRING
printf("\rSaw %d instructions\n", insns_seen_total);
 
#endif
generate_stats(stdout);
insn_lists_free();

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.