static void addEvent_Dw ( CgState* cgs, InstrInfo* inode, Int datasize, IRAtom* ea ) { Event* lastEvt; Event* evt; tl_assert(isIRAtom(ea)); tl_assert(datasize >= 1 && datasize <= MIN_LINE_SIZE); /* Is it possible to merge this write with the preceding read? */ lastEvt = &cgs->events[cgs->events_used-1]; if (cgs->events_used > 0 && lastEvt->ekind == Event_Dr && lastEvt->datasize == datasize && lastEvt->inode == inode && eqIRAtom(lastEvt->dataEA, ea)) { lastEvt->ekind = Event_Dm; return; } /* No. Add as normal. */ if (cgs->events_used == N_EVENTS) flushEvents(cgs); tl_assert(cgs->events_used >= 0 && cgs->events_used < N_EVENTS); evt = &cgs->events[cgs->events_used]; evt->ekind = Event_Dw; evt->inode = inode; evt->datasize = datasize; evt->dataEA = ea; cgs->events_used++; }
/* Add an ordinary write event. Try to merge it with an immediately preceding ordinary read event of the same size to the same address. */ static void addEvent_Dw ( IRSB* sb, IRAtom* daddr, Int dsize ) { Event* lastEvt; Event* evt; tl_assert(clo_trace_mem); tl_assert(isIRAtom(daddr)); tl_assert(dsize >= 1 && dsize <= MAX_DSIZE); // Is it possible to merge this write with the preceding read? lastEvt = &events[events_used-1]; if (events_used > 0 && lastEvt->ekind == Event_Dr && lastEvt->size == dsize && lastEvt->guard == NULL && eqIRAtom(lastEvt->addr, daddr)) { lastEvt->ekind = Event_Dm; return; } // No. Add as normal. if (events_used == N_EVENTS) flushEvents(sb); tl_assert(events_used >= 0 && events_used < N_EVENTS); evt = &events[events_used]; evt->ekind = Event_Dw; evt->size = dsize; evt->addr = daddr; evt->guard = NULL; events_used++; }
static Bool loadStoreAddrsMatch(IRExpr* loadAddrExpr, IRExpr* storeAddrExpr) { // I'm assuming that for 'modify' instructions, that Vex always makes // the loadAddrExpr and storeAddrExpr be of the same type, ie. both Tmp // expressions, or both Const expressions. CLG_ASSERT(isIRAtom(loadAddrExpr)); CLG_ASSERT(isIRAtom(storeAddrExpr)); return eqIRAtom(loadAddrExpr, storeAddrExpr); }