]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
If we are doing cache simulation, refuse to start at all if the minimum
authorJulian Seward <jseward@acm.org>
Sun, 3 Jun 2012 23:10:55 +0000 (23:10 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 3 Jun 2012 23:10:55 +0000 (23:10 +0000)
cache line size is smaller than the maximum guest register size.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12606

callgrind/global.h
callgrind/main.c
callgrind/sim.c

index 63f6e106c7f57ca7f87174cbdaa79f970de4c40f..b10165d9264b30f9d78d34284960ffaf1351181e 100644 (file)
@@ -827,6 +827,8 @@ extern EventMapping* CLG_(dumpmap);
 /* Function active counter array, indexed by function number */
 extern UInt* CLG_(fn_active_array);
 extern Bool CLG_(instrument_state);
+ /* min of L1 and LL cache line sizes */
+extern Int CLG_(min_line_size);
 
 extern call_stack CLG_(current_call_stack);
 extern fn_stack   CLG_(current_fn_stack);
index 62ca8c904fc4bf8585fb3db6cdbf37f66ef8f636..66af64b7e02444317b77bb817dc05e3fbd6ebf2f 100644 (file)
@@ -52,6 +52,10 @@ Bool CLG_(instrument_state) = True; /* Instrumentation on ? */
 /* thread and signal handler specific */
 exec_state CLG_(current_state);
 
+/* min of L1 and LL cache line sizes.  This only gets set to a
+   non-zero value if we are doing cache simulation. */
+Int CLG_(min_line_size) = 0;
+
 
 /*------------------------------------------------------------*/
 /*--- Statistics                                           ---*/
@@ -613,8 +617,9 @@ void addEvent_Dr ( ClgState* clgs, InstrInfo* inode, Int datasize, IRAtom* ea )
 {
    Event* evt;
    tl_assert(isIRAtom(ea));
-   tl_assert(datasize >= 1 && datasize <= MIN_LINE_SIZE);
+   tl_assert(datasize >= 1);
    if (!CLG_(clo).simulate_cache) return;
+   tl_assert(datasize <= CLG_(min_line_size));
 
    if (clgs->events_used == N_EVENTS)
       flushEvents(clgs);
@@ -634,8 +639,9 @@ void addEvent_Dw ( ClgState* clgs, InstrInfo* inode, Int datasize, IRAtom* ea )
    Event* lastEvt;
    Event* evt;
    tl_assert(isIRAtom(ea));
-   tl_assert(datasize >= 1 && datasize <= MIN_LINE_SIZE);
+   tl_assert(datasize >= 1);
    if (!CLG_(clo).simulate_cache) return;
+   tl_assert(datasize <= CLG_(min_line_size));
 
    /* Is it possible to merge this write with the preceding read? */
    lastEvt = &clgs->events[clgs->events_used-1];
@@ -1027,8 +1033,8 @@ IRSB* CLG_(instrument)( VgCallbackClosure* closure,
               // instructions will be done inaccurately, but they're
               // very rare and this avoids errors from hitting more
               // than two cache lines in the simulation.
-              if (dataSize > MIN_LINE_SIZE)
-                 dataSize = MIN_LINE_SIZE;
+              if (CLG_(clo).simulate_cache && dataSize > CLG_(min_line_size))
+                 dataSize = CLG_(min_line_size);
               if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify)
                  addEvent_Dr( &clgs, curr_inode, dataSize, d->mAddr );
               if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify)
index c1deff72e8bb8e712fe95a5cd2ee40357e545e70..8703c60c814a3192968481eb18e3dff289546e86 100644 (file)
@@ -1307,6 +1307,28 @@ static void cachesim_post_clo_init(void)
   D1.name = "D1";
   LL.name = "LL";
 
+  // min_line_size is used to make sure that we never feed
+  // accesses to the simulator straddling more than two
+  // cache lines at any cache level
+  CLG_(min_line_size) = (I1c.line_size < D1c.line_size)
+                           ? I1c.line_size : D1c.line_size;
+  CLG_(min_line_size) = (LLc.line_size < CLG_(min_line_size))
+                           ? LLc.line_size : CLG_(min_line_size);
+
+  Int largest_load_or_store_size
+     = VG_(machine_get_size_of_largest_guest_register)();
+  if (CLG_(min_line_size) < largest_load_or_store_size) {
+     /* We can't continue, because the cache simulation might
+        straddle more than 2 lines, and it will assert.  So let's
+        just stop before we start. */
+     VG_(umsg)("Callgrind: cannot continue: the minimum line size (%d)\n",
+               (Int)CLG_(min_line_size));
+     VG_(umsg)("  must be equal to or larger than the maximum register size (%d)\n",
+               largest_load_or_store_size );
+     VG_(umsg)("  but it is not.  Exiting now.\n");
+     VG_(exit)(1);
+  }
+
   cachesim_initcache(I1c, &I1);
   cachesim_initcache(D1c, &D1);
   cachesim_initcache(LLc, &LL);