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 18 to Rev 19
    Reverse comparison

Rev 18 → Rev 19

/or2k/trunk/analysis-bin/insnanalysis/insn-lists.c
21,6 → 21,12
or1k_32_insn_lists_add(insn, insn_props);
}
 
void insn_lists_group_add(int n,
instruction_properties *insn_props)
{
or1k_32_ntuple_add(n, insn_props);
}
 
void insn_lists_free(void)
{
or1k_32_insn_lists_free();
/or2k/trunk/analysis-bin/insnanalysis/or1k-32-insn.c
19,6 → 19,16
#include "insn-lists.h"
 
 
// Variable to keep track of unique instructions we have
int num_setup_insns;
int num_seen_insns;
 
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
 
// Keep enough instructions required to do the maximum n-tuple set
// analysis.
int or1k_32_recent_insns[OR1K_MAX_GROUPINGS_ANALYSIS];
 
int or1k_32_analyse_insn(uint32_t insn,
struct or1k_32_instruction_properties * insn_props)
{
980,21 → 990,20
// Add this instruction's occurance to our data
insn_lists_add(insn, insn_props);
 
}
// n-tuple groupings stats recording here!
// only if we've seen enough to do all the sequence analysis
if (num_seen_insns > OR1K_MAX_GROUPINGS_ANALYSIS+1)
{
int n;
for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
insn_lists_group_add(n, insn_props);
}
// Finished adding to stats for this instruction
 
 
}
 
struct or1k_value_list
{
 
#define OR1K_VALUE_MAX_ENTRIES 64
int count;
// [value][occurances_of_value]
int32_t values[OR1K_VALUE_MAX_ENTRIES][2];
};
 
 
// Function to add entry to, or increment incidences of, value in the value list
void or1k_add_in_list(struct or1k_value_list * list, int32_t value)
{
1018,74 → 1027,12
list->values[(list->count)][0] = value;
list->values[(list->count)][1] = 1;
list->count++;
}
}
}
 
struct or1k_insn_info
{
char* insn_string;
 
int count;
int has_branchtarg;
struct or1k_value_list branch_info;
 
int has_imm;
struct or1k_value_list imm_info;
 
int has_rD;
int rD_use_freq[32];
int has_rA;
int rA_use_freq[32];
int has_rB;
int rB_use_freq[32];
 
// 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 1000
// Format of grouping data:
//
// 1st dimension: A list for each n-tuple group we're keeping track of
// (starting at pairs of instructions)
//
// 2nd dimension: Stores the list entries for the 1st dimension-tuple
// grouping. The number in [x][0][0] is the number of entries in the list so
// far, beginning at 0. The actual entries with data for grouping x start at
// [x][1][], where that entry holds the 1st x+2-tuple grouping information
// (eg. at x=0, [0][1][] is the first entry for/ pair instruction
// information, x=1, is for triples, x=2 quadruples, etc)
//
// 3rd dimension: Store up to x+2 instruction indexes (where x is the first
// dimension index, meaning this particular data is for a (x+2)-tuple set)
// and then a frequency count for this set (in index (x+2) of the third
// dimension array). Note we will have the index for the instruction this
// struct corresponds to in [x][n][(x+2)-1], which seems redundant, but can
// help processing later on.
//
// Note that we will have empty entries in the third dimension arrays for all
// but the last in the list of n-tuples. This is to save doing tricky naming
// defines and, in the future, if we would like to analyse sets that are
// bigger or smaller, hopefully all we need to do is change a single define.
//
int groupings[OR1K_MAX_GROUPINGS_ANALYSIS][OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1];
 
};
 
// This number should correspond to the maximum insn_index we assign in the
// analyse function
#define OR1K_32_MAX_INSNS 117
struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
 
 
// List management/analysis functions - accessed through insn_lists() set of
// functions
 
// Variable to keep track of unique instructions we have
int num_setup_insns;
int num_seen_insns;
 
 
void or1k_32_insn_lists_init(void)
{
num_setup_insns = 0;
1111,6 → 1058,11
// index, as set when we decode the instruction
or1k_32_insns[insn_props->insn_index] = new_insn;
 
// Clear the set statistics counters
int set_itr;
for(set_itr=0;set_itr<OR1K_MAX_GROUPINGS_ANALYSIS;set_itr++)
or1k_32_insns[insn_props->insn_index]->groupings[set_itr][0][0] = 0;
 
// Increment number of instructions we have set up
num_setup_insns++;
1181,28 → 1133,90
(or1k_32_insns[insn_props->insn_index])->has_rB = 1;
((or1k_32_insns[insn_props->insn_index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
}
 
 
// TODO: n-tuple groupings stats recording here!
 
// Finished adding to stats for this instruction
// Increment overall instructions "seen" counter
num_seen_insns++;
 
// Shift along the recently seen instructions
int i;
for(i=OR1K_MAX_GROUPINGS_ANALYSIS-1;i>0;i--)
or1k_32_recent_insns[i] = or1k_32_recent_insns[i-1];
or1k_32_recent_insns[0] = insn_props->insn_index;
 
}
 
 
// Free up all added instruction statistic tracking structs
void or1k_32_insn_lists_free(void)
 
 
// Do the n-tuple set analysis for the most recently added instruction
void or1k_32_ntuple_add(int n,
struct or1k_32_instruction_properties *insn_props)
{
// Free all entries we m/calloc()'d
int insn_index;
for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
 
if (n<2)
{
if (or1k_32_insns[insn_index] != NULL)
free(or1k_32_insns[insn_index]);
fprintf(stderr,"or1k_32_ntuple_add: tuple number < 2 (%d)",n);
return;
}
 
struct or1k_insn_info * insn_info = or1k_32_insns[insn_props->insn_index];
 
// 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];
 
int set_match_index; int tuple_set_itr, tuple_set_match;
// 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[][][].
for (set_match_index=0; set_match_index<sets_for_ntuple; set_match_index++)
{
// Check this set for a match with our existing trace
// Example:
// In case of a triple (n=3), 1st set, [3][1][0] corresponds to the third
// instruction in the trace (or1k_32_recent_insns[2]), [3][1][1] should
// be the second in the trace, and [3][1][2] should be the first in the
// trace (same index as insn_props->insn_index)
// Presuppose a match, de-assert and break out of the loop as soon as we
// detect a mismatch.
tuple_set_match = 1;
for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
{
if (insn_info->groupings[n-1][set_match_index+1][tuple_set_itr]
!= or1k_32_recent_insns[n-1 - tuple_set_itr])
{
tuple_set_match = 0;
break; // No match, so break out of this for() loop
}
}
if (!tuple_set_match)
continue; // go again...
}
 
if (tuple_set_match)
// Found a match - just increment the counter (set_match_index should
// be pointing at the right set)
(insn_info->groupings[n-1][set_match_index+1][n])++;
else
{
// If we can record a new set
if (sets_for_ntuple < OR1K_MAX_ENTRIES_PER_GROUP)
{
// Increment the number of sets we have for this n-tuple starting
// on the current instruction
sets_for_ntuple++;
// Add new set to the end (all n instructions, copy in)
for(tuple_set_itr=0;tuple_set_itr<n;tuple_set_itr++)
insn_info->groupings[n-1][sets_for_ntuple][tuple_set_itr]
= or1k_32_recent_insns[n-1 - tuple_set_itr];
// Set the count for this set to 1
insn_info->groupings[n-1][sets_for_ntuple][n] = 1;
// Increment the counter of these n-tuple sets
(insn_info->groupings[n-1][0][0])++;
}
}
}
 
 
1388,6 → 1402,83
}
}
}
 
#define MAX_NTUPLE_LISTING 5
// Print out the most common n-tuple groupings for an instruction
void or1k_32_generate_ntuple_stats(int n, struct or1k_insn_info *insn_info,
FILE * stream)
{
// If n=2 (pairs) then groupings[1] is where our list is
int total_sets_for_ntuple = insn_info->groupings[n-1][0][0];
 
if (total_sets_for_ntuple == 0)
return;
 
fprintf(stream, "%d-tuple groupings ending with this instruction\n",n);
 
// This is actually a pointer to a 2-dimensional integer array, looking like:
// [OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1;]
int *ntuplelist = (int*)&(insn_info->groupings[n-1]);
int *set;
int set_count, set_count2;
// Let's make a copy of the counts for each... so we don't trash them
int set_count_copy[OR1K_MAX_ENTRIES_PER_GROUP+1];
// Go through the list, copy the counts for each
for (set_count = 0;set_count <total_sets_for_ntuple;set_count++)
{
set = (int*)ntuplelist[set_count+1];
set_count_copy[set_count+1]=set[n];
}
// Now go through, finding the most frequent n-tuple of instructions and
// print it out
int largest_indx = 0;
set_count=0;
while(set_count < total_sets_for_ntuple && set_count < MAX_NTUPLE_LISTING)
{
largest_indx = 0;
for(set_count2=0;set_count2<total_sets_for_ntuple;set_count2++)
largest_indx = (set_count_copy[set_count2 + 1] >
set_count_copy[largest_indx + 1]) ?
set_count2 : largest_indx;
// largest_indx is the index of the set with the highest occurance, so
// let's print it out, but first get a pointer to the set's data
set = (int*)ntuplelist[largest_indx+1];
// Print out the sequence of prior isntructions
fprintf(stream,"Seq:\t");
// 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);
// now print out the occurances
fprintf(stream, "%d\ttimes\n", set_count_copy[largest_indx + 1]);
 
// done printing this one out.. let's clear its count
set_count_copy[largest_indx + 1] = -1;
set_count++;
}
return;
 
}
 
 
// Print out the stats relating to the sequences of instructions most
// common before seeing this instruction
void or1k_32_generate_groupings_stats(struct or1k_insn_info *insn_info,
FILE * stream)
{
int n;
for(n=2;n<OR1K_MAX_GROUPINGS_ANALYSIS+1;n++)
or1k_32_generate_ntuple_stats(n, insn_info, stream);
 
}
void or1k_32_generate_stats(FILE * stream)
{
1401,9 → 1492,13
for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
{
if (or1k_32_insns[insn_index] != NULL)
or1k_32_insn_top_x(or1k_32_insns[insn_index],stream,10);
{
or1k_32_insn_top_x(or1k_32_insns[insn_index],stream,10);
or1k_32_generate_groupings_stats(or1k_32_insns[insn_index],stream);
}
}
 
 
// Do most frequent instruction analysis -- note this trashes instruction
// frequency count - should be fixed
1410,3 → 1505,18
or1k_32_most_freq_insn(stream);
}
 
 
 
 
// Free up all added instruction statistic tracking structs
void or1k_32_insn_lists_free(void)
{
// Free all entries we m/calloc()'d
int insn_index;
for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
{
if (or1k_32_insns[insn_index] != NULL)
free(or1k_32_insns[insn_index]);
}
}
/or2k/trunk/analysis-bin/insnanalysis/insn-lists.h
17,5 → 17,9
void insn_lists_add(instruction insn,
instruction_properties *insn_props);
 
// Record occurance of last n instructions
void insn_lists_group_add(int n,
instruction_properties *insn_props);
 
// Free, clean up, anything we need to
void insn_lists_free(void);
/or2k/trunk/analysis-bin/insnanalysis/or1k-32-insn.h
26,6 → 26,76
 
};
 
 
// Structs for internal statistics keeping
 
struct or1k_value_list
{
 
#define OR1K_VALUE_MAX_ENTRIES 64
int count;
// [value][occurances_of_value]
int32_t values[OR1K_VALUE_MAX_ENTRIES][2];
};
 
struct or1k_insn_info
{
char* insn_string;
 
int count;
int has_branchtarg;
struct or1k_value_list branch_info;
 
int has_imm;
struct or1k_value_list imm_info;
 
int has_rD;
int rD_use_freq[32];
int has_rA;
int rA_use_freq[32];
int has_rB;
int rB_use_freq[32];
 
// 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 1000
// Format of grouping data:
//
// 1st dimension: A list for each n-tuple group we're keeping track of
// (starting at pairs of instructions)
//
// 2nd dimension: Stores the list entries for the 1st dimension-tuple
// grouping. The number in [x][0][0] is the number of entries in the list so
// far, beginning at 0. The actual entries with data for grouping x start at
// [x][1][], where that entry holds the 1st x+2-tuple grouping information
// (eg. at x=0, [0][1][] is the first entry for/ pair instruction
// information, x=1, is for triples, x=2 quadruples, etc)
//
// 3rd dimension: Store up to x+2 instruction indexes (where x is the first
// dimension index, meaning this particular data is for a (x+2)-tuple set)
// and then a frequency count for this set (in index (x+2) of the third
// dimension array). Note we will have the index for the instruction this
// struct corresponds to in [x][n][(x+2)-1], which seems redundant, but can
// help processing later on. The final entry after the instruction indexes
// is the occurance count for this particular set (at [x][n][x+2])
//
// Note that we will have empty entries in the third dimension arrays for all
// but the last in the list of n-tuples. This is to save doing tricky naming
// defines and, in the future, if we would like to analyse sets that are
// bigger or smaller, hopefully all we need to do is change a single define.
//
int groupings[OR1K_MAX_GROUPINGS_ANALYSIS][OR1K_MAX_ENTRIES_PER_GROUP+1][OR1K_MAX_GROUPINGS_ANALYSIS+1];
 
};
 
// This number should correspond to the maximum insn_index we assign in the
// analyse function
#define OR1K_32_MAX_INSNS 117
extern struct or1k_insn_info * or1k_32_insns[OR1K_32_MAX_INSNS];
 
 
// OpenRISC 1000 32-bit instruction defines, helping us
// extract fields of the instructions
 
47,6 → 117,10
void or1k_32_insn_lists_add(uint32_t insn,
struct or1k_32_instruction_properties *insn_props);
 
// Record the occurance of a group of instructions
void or1k_32_ntuple_add(int n,
struct or1k_32_instruction_properties *insn_props);
 
// Print out some useful information
void or1k_32_generate_stats(FILE * stream);
 
/or2k/trunk/analysis-bin/insnanalysis/insnanalysis.c
90,7 → 90,11
}
else
{
printf("\n");
// Non-zero return from analyse_insn(): problem analysing instruction.
 
// Is a NOP for now, but do something here if needed
 
do{ } while(0);
}
}
/or2k/trunk/analysis-bin/insnanalysis/Makefile
1,6 → 1,8
 
APP=insnanalysis
 
CFLAGS ?= -O2
 
all: $(APP)
 
SRC=insnanalysis.c or1k-32-insn.c insn-lists.c
8,7 → 10,7
 
 
insnanalysis: $(SRC) $(HDRS)
gcc -O2 $(SRC) -o $@
gcc $(CFLAGS) $(SRC) -o $@
 
 
test: test.bin $(APP)

powered by: WebSVN 2.1.0

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