Add simple function-tracing support. Prints a message
authorSteve Reinhardt <stever@eecs.umich.edu>
Tue, 16 Nov 2004 22:20:38 +0000 (17:20 -0500)
committerSteve Reinhardt <stever@eecs.umich.edu>
Tue, 16 Nov 2004 22:20:38 +0000 (17:20 -0500)
every time the committed PC changes from one symbol scope
to another.
Set function_trace=y on target CPU to enable.
To defer start, use function_trace_start=<tick>
(in addition to setting function_trace=y).

cpu/base_cpu.cc:
cpu/base_cpu.hh:
    Add simple function-tracing support.
cpu/simple_cpu/simple_cpu.cc:
    Add function_trace, function_trace_start params
    Call traceFunctions() on instruction completion
cpu/simple_cpu/simple_cpu.hh:
    Add function_trace, function_trace_start params

--HG--
extra : convert_revision : 8a7f84028ccbaee585253629007f32fc8eae35e1

cpu/base_cpu.cc
cpu/base_cpu.hh
cpu/simple_cpu/simple_cpu.cc
cpu/simple_cpu/simple_cpu.hh

index e4dd744a6d9ac711b55c5585988895bc43fa0947..7605ff3c3fd05b26b025b02563609ab58ffe1b7f 100644 (file)
 #include <sstream>
 #include <iostream>
 
-#include "cpu/base_cpu.hh"
 #include "base/cprintf.hh"
-#include "cpu/exec_context.hh"
+#include "base/loader/symtab.hh"
 #include "base/misc.hh"
+#include "cpu/base_cpu.hh"
+#include "cpu/exec_context.hh"
 #include "sim/param.hh"
 #include "sim/sim_events.hh"
 
@@ -52,7 +53,8 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
                  Counter max_insts_all_threads,
                  Counter max_loads_any_thread,
                  Counter max_loads_all_threads,
-                 System *_system, Tick freq)
+                 System *_system, Tick freq,
+                 bool _function_trace, Tick _function_trace_start)
     : SimObject(_name), frequency(freq), checkInterrupts(true),
       deferRegistration(_def_reg), number_of_threads(_number_of_threads),
       system(_system)
@@ -61,7 +63,8 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
                  Counter max_insts_any_thread,
                  Counter max_insts_all_threads,
                  Counter max_loads_any_thread,
-                 Counter max_loads_all_threads)
+                 Counter max_loads_all_threads,
+                 bool _function_trace, Tick _function_trace_start)
     : SimObject(_name), deferRegistration(_def_reg),
       number_of_threads(_number_of_threads)
 #endif
@@ -126,8 +129,39 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
     memset(interrupts, 0, sizeof(interrupts));
     intstatus = 0;
 #endif
+
+    functionTracingEnabled = false;
+    if (_function_trace) {
+        std::string filename = csprintf("ftrace.%s", name());
+        functionTraceStream = makeOutputStream(filename);
+        currentFunctionStart = currentFunctionEnd = 0;
+        functionEntryTick = _function_trace_start;
+
+        if (_function_trace_start == 0) {
+            functionTracingEnabled = true;
+        } else {
+            Event *e =
+                new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
+                                                                         true);
+            e->schedule(_function_trace_start);
+        }
+    }
 }
 
+
+void
+BaseCPU::enableFunctionTrace()
+{
+    functionTracingEnabled = true;
+}
+
+BaseCPU::~BaseCPU()
+{
+    if (functionTracingEnabled)
+        closeOutputStream(functionTraceStream);
+}
+
+
 void
 BaseCPU::init()
 {
@@ -267,4 +301,32 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
 
 #endif // FULL_SYSTEM
 
+void
+BaseCPU::traceFunctionsInternal(Addr pc)
+{
+    if (!debugSymbolTable)
+        return;
+
+    // if pc enters different function, print new function symbol and
+    // update saved range.  Otherwise do nothing.
+    if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
+        string sym_str;
+        bool found = debugSymbolTable->findNearestSymbol(pc, sym_str,
+                                                         currentFunctionStart,
+                                                         currentFunctionEnd);
+
+        if (!found) {
+            // no symbol found: use addr as label
+            sym_str = csprintf("0x%x", pc);
+            currentFunctionStart = pc;
+            currentFunctionEnd = pc + 1;
+        }
+
+        ccprintf(*functionTraceStream, " (%d)\n%d: %s",
+                 curTick - functionEntryTick, curTick, sym_str);
+        functionEntryTick = curTick;
+    }
+}
+
+
 DEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
index 8668c3216ac5de0eed7a74140ebeea070c21db43..baa956aa8abf06de81b462b1c9e06cc6fae915bb 100644 (file)
@@ -95,16 +95,18 @@ class BaseCPU : public SimObject
     BaseCPU(const std::string &_name, int _number_of_threads, bool _def_reg,
             Counter max_insts_any_thread, Counter max_insts_all_threads,
             Counter max_loads_any_thread, Counter max_loads_all_threads,
-            System *_system, Tick freq);
+            System *_system, Tick freq,
+            bool _function_trace = false, Tick _function_trace_start = 0);
 #else
     BaseCPU(const std::string &_name, int _number_of_threads, bool _def_reg,
             Counter max_insts_any_thread = 0,
             Counter max_insts_all_threads = 0,
             Counter max_loads_any_thread = 0,
-            Counter max_loads_all_threads = 0);
+            Counter max_loads_all_threads = 0,
+            bool _function_trace = false, Tick _function_trace_start = 0);
 #endif
 
-    virtual ~BaseCPU() {}
+    virtual ~BaseCPU();
 
     virtual void init();
     virtual void regStats();
@@ -166,6 +168,23 @@ class BaseCPU : public SimObject
 
     virtual Counter totalInstructions() const { return 0; }
 
+    // Function tracing
+  private:
+    bool functionTracingEnabled;
+    std::ostream *functionTraceStream;
+    Addr currentFunctionStart;
+    Addr currentFunctionEnd;
+    Tick functionEntryTick;
+    void enableFunctionTrace();
+    void traceFunctionsInternal(Addr pc);
+
+  protected:
+    void traceFunctions(Addr pc)
+    {
+        if (functionTracingEnabled)
+            traceFunctionsInternal(pc);
+    }
+
   private:
     static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
 
index 04783574f7ec1bebbcf910e73ef3185d3cd40e59..d48f936638eb3bc86972c8f36aab579816b7aedf 100644 (file)
@@ -123,11 +123,12 @@ SimpleCPU::SimpleCPU(const string &_name,
                      FunctionalMemory *mem,
                      MemInterface *icache_interface,
                      MemInterface *dcache_interface,
-                     bool _def_reg, Tick freq)
+                     bool _def_reg, Tick freq,
+                     bool _function_trace, Tick _function_trace_start)
     : BaseCPU(_name, /* number_of_threads */ 1, _def_reg,
               max_insts_any_thread, max_insts_all_threads,
               max_loads_any_thread, max_loads_all_threads,
-              _system, freq),
+              _system, freq, _function_trace, _function_trace_start),
 #else
 SimpleCPU::SimpleCPU(const string &_name, Process *_process,
                      Counter max_insts_any_thread,
@@ -136,10 +137,12 @@ SimpleCPU::SimpleCPU(const string &_name, Process *_process,
                      Counter max_loads_all_threads,
                      MemInterface *icache_interface,
                      MemInterface *dcache_interface,
-                     bool _def_reg)
+                     bool _def_reg,
+                     bool _function_trace, Tick _function_trace_start)
     : BaseCPU(_name, /* number_of_threads */ 1, _def_reg,
               max_insts_any_thread, max_insts_all_threads,
-              max_loads_any_thread, max_loads_all_threads),
+              max_loads_any_thread, max_loads_all_threads,
+              _function_trace, _function_trace_start),
 #endif
       tickEvent(this), xc(NULL), cacheCompletionEvent(this)
 {
@@ -778,6 +781,8 @@ SimpleCPU::tick()
         if (traceData)
             traceData->finalize();
 
+        traceFunctions(xc->regs.pc);
+
     }  // if (fault == No_Fault)
 
     if (fault != No_Fault) {
@@ -836,6 +841,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
 
     Param<bool> defer_registration;
     Param<int> multiplier;
+    Param<bool> function_trace;
+    Param<Tick> function_trace_start;
 
 END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
 
@@ -869,7 +876,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
     INIT_PARAM_DFLT(defer_registration, "defer registration with system "
                     "(for sampling)", false),
 
-    INIT_PARAM_DFLT(multiplier, "clock multiplier", 1)
+    INIT_PARAM_DFLT(multiplier, "clock multiplier", 1),
+    INIT_PARAM_DFLT(function_trace, "Enable function trace", false),
+    INIT_PARAM_DFLT(function_trace_start, "Cycle to start function trace", 0)
 
 END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
 
@@ -888,7 +897,8 @@ CREATE_SIM_OBJECT(SimpleCPU)
                         (icache) ? icache->getInterface() : NULL,
                         (dcache) ? dcache->getInterface() : NULL,
                         defer_registration,
-                        ticksPerSecond * mult);
+                        ticksPerSecond * mult,
+                        function_trace, function_trace_start);
 #else
 
     cpu = new SimpleCPU(getInstanceName(), workload,
@@ -896,7 +906,8 @@ CREATE_SIM_OBJECT(SimpleCPU)
                         max_loads_any_thread, max_loads_all_threads,
                         (icache) ? icache->getInterface() : NULL,
                         (dcache) ? dcache->getInterface() : NULL,
-                        defer_registration);
+                        defer_registration,
+                        function_trace, function_trace_start);
 
 #endif // FULL_SYSTEM
 
index 8ea100b223e1d0310d496872e3f796c68d1381ed..341a0da2369c5c9a461e2290dd9e87ee1b81a3e0 100644 (file)
@@ -142,7 +142,8 @@ class SimpleCPU : public BaseCPU
               Counter max_loads_any_thread, Counter max_loads_all_threads,
               AlphaITB *itb, AlphaDTB *dtb, FunctionalMemory *mem,
               MemInterface *icache_interface, MemInterface *dcache_interface,
-              bool _def_reg, Tick freq);
+              bool _def_reg, Tick freq,
+              bool _function_trace, Tick _function_trace_start);
 
 #else
 
@@ -152,7 +153,8 @@ class SimpleCPU : public BaseCPU
               Counter max_loads_any_thread,
               Counter max_loads_all_threads,
               MemInterface *icache_interface, MemInterface *dcache_interface,
-              bool _def_reg);
+              bool _def_reg,
+              bool _function_trace, Tick _function_trace_start);
 
 #endif