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

Subversion Repositories or2k

[/] [or2k/] [trunk/] [analysis-bin/] [insnanalysis/] [or1k-32-insn.c] - Diff between revs 18 and 19

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 18 Rev 19
Line 17... Line 17...
typedef struct or1k_32_instruction_properties instruction_properties ;
typedef struct or1k_32_instruction_properties instruction_properties ;
 
 
#include "insn-lists.h"
#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,
int or1k_32_analyse_insn(uint32_t insn,
                         struct or1k_32_instruction_properties  * insn_props)
                         struct or1k_32_instruction_properties  * insn_props)
{
{
 
 
  switch(insn_or1k_opcode(insn))
  switch(insn_or1k_opcode(insn))
Line 978... Line 988...
                         struct or1k_32_instruction_properties  * insn_props)
                         struct or1k_32_instruction_properties  * insn_props)
{
{
  // Add this instruction's occurance to our data
  // Add this instruction's occurance to our data
  insn_lists_add(insn, insn_props);
  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
// 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)
void or1k_add_in_list(struct or1k_value_list * list, int32_t value)
{
{
  int i;
  int i;
Line 1017... Line 1026...
      // Not found, add it to the list
      // Not found, add it to the list
      list->values[(list->count)][0] = value;
      list->values[(list->count)][0] = value;
      list->values[(list->count)][1] = 1;
      list->values[(list->count)][1] = 1;
      list->count++;
      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
// List management/analysis functions - accessed through insn_lists() set of
// functions
// 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)
void or1k_32_insn_lists_init(void)
{
{
  num_setup_insns = 0;
  num_setup_insns = 0;
  num_seen_insns = 0;
  num_seen_insns = 0;
  // Clear the pointer array so we can tell if things are used or not
  // Clear the pointer array so we can tell if things are used or not
Line 1109... Line 1056...
 
 
  // Install the pointer for this newly allocated struct in its corresponding
  // Install the pointer for this newly allocated struct in its corresponding
  // index, as set when we decode the instruction
  // index, as set when we decode the instruction
  or1k_32_insns[insn_props->insn_index] = new_insn;
  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
  // Increment number of instructions we have set up
  num_setup_insns++;
  num_setup_insns++;
 
 
  // Debugging:
  // Debugging:
  //printf("Adding %dth instruction - %s\n",
  //printf("Adding %dth instruction - %s\n",
Line 1180... Line 1132...
    {
    {
      (or1k_32_insns[insn_props->insn_index])->has_rB = 1;
      (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)])++;
      ((or1k_32_insns[insn_props->insn_index])->rB_use_freq[insn_or1k_32_rB(insn)])++;
    }
    }
 
 
 
  // Increment overall instructions "seen" counter
 
  num_seen_insns++;
 
 
  // TODO: n-tuple groupings stats recording here!
  // 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;
 
 
  // Finished adding to stats for this instruction
}
 
 
  // Increment overall instructions "seen" counter
 
  num_seen_insns++;
 
 
 
 
 
 
 
 
// 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)
 
{
 
 
 
  if (n<2)
 
    {
 
      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];
 
 
// Free up all added instruction statistic tracking structs
  // Get the number of sets for these n-tuple groups we've seen so far.
void or1k_32_insn_lists_free(void)
  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++)
{
{
  // Free all entries we m/calloc()'d
      // Check this set for a match with our existing trace
  int insn_index;
      // Example:
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
      // 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 (or1k_32_insns[insn_index] != NULL)
          if (insn_info->groupings[n-1][set_match_index+1][tuple_set_itr]
        free(or1k_32_insns[insn_index]);
              != 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])++;
 
        }
    }
    }
}
}
 
 
 
 
#define DISPLAY_STRING
#define DISPLAY_STRING
Line 1387... Line 1401...
          i++;
          i++;
        }
        }
    }
    }
}
}
 
 
 
#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)
void or1k_32_generate_stats(FILE * stream)
{
{
  // Generate some useful things
  // Generate some useful things
  fprintf(stream, "Analysis output:\n");
  fprintf(stream, "Analysis output:\n");
 
 
Line 1399... Line 1490...
  // Print out all stats for every instruction we saw!
  // Print out all stats for every instruction we saw!
  int insn_index;
  int insn_index;
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
  for(insn_index=0;insn_index<OR1K_32_MAX_INSNS;insn_index++)
    {
    {
      if (or1k_32_insns[insn_index] != NULL)
      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
  // Do most frequent instruction analysis -- note this trashes instruction
  // frequency count - should be fixed
  // frequency count - should be fixed
  or1k_32_most_freq_insn(stream);
  or1k_32_most_freq_insn(stream);
 
 
}
}
 
 
 No newline at end of file
 No newline at end of file
 
 
 
 
 
 
 
// 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]);
 
    }
 
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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