CCTLib
Calling-context and data-object attribution library for Intel Pin
deadspy_tp_simple.c
Go to the documentation of this file.
1 // True-positive victim: two consecutive writes to the same memory location
2 // with NO intervening read. Every second write is a dead write.
3 //
4 // Anti-optimization measures:
5 // - `volatile` to prevent the compiler from collapsing the two stores
6 // - `-O0` in the test build
7 // - external function calls between phases so the compiler can't reorder
8 //
9 // The program deliberately does WORK_COUNT iterations of a paired
10 // write-write so a machine-tested threshold can catch regressions.
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 
15 #define WORK_COUNT 10000
16 
17 static volatile uint64_t sink;
18 
19 // Force a store the compiler can't elide.
20 __attribute__((noinline)) void store8(volatile uint64_t* p, uint64_t v) {
21  *p = v;
22 }
23 
24 int main(int argc, char** argv) {
25  (void)argc; (void)argv;
26  uint64_t buf[WORK_COUNT];
27  // Prime buf to non-zero so the FIRST write of each pair definitely
28  // overwrites a previously-written cell (making it dead once the
29  // SECOND write happens).
30  for (int i = 0; i < WORK_COUNT; ++i) buf[i] = 0xAAULL;
31 
32  for (int i = 0; i < WORK_COUNT; ++i) {
33  store8(&buf[i], 1); // dead: overwritten below with no read between
34  store8(&buf[i], 2); // this is the survivor
35  }
36 
37  // Publish a checksum so DCE doesn't kill the loop.
38  uint64_t s = 0;
39  for (int i = 0; i < WORK_COUNT; ++i) s += buf[i];
40  sink = s;
41  return 0;
42 }
#define WORK_COUNT
int main(int argc, char **argv)
__attribute__((noinline))
static volatile uint64_t sink
static uint64_t buf[ITERS]