liberty/lib/SLAMP/SLAMP.cpp
/// Pass in the loop and instrument invocation/iteration/exit hooks
Pass in the loop and instrument invocation/iteration/exit hooks
Pass in the loop and instrument invocation / iteration / exit hooks
void SLAMP::instrumentLoopStartStop(Module &m, Loop *loop) {
  BasicBlock *header = loop->getHeader();
  BasicBlock *latch = loop->getLoopLatch();
  assert(loop->getNumBackEdges() == 1 &&
         "Should be only 1 back edge, loop-simplify?");
  assert(latch && "Loop latch needs to exist, loop-simplify?");
  auto *f_loop_invoke = cast<Function>(
      m.getOrInsertFunction("SLAMP_loop_invocation", Void).getCallee());
  auto *f_loop_iter = cast<Function>(
      m.getOrInsertFunction("SLAMP_loop_iteration", Void).getCallee());
  auto *f_loop_exit = cast<Function>(
      m.getOrInsertFunction("SLAMP_loop_exit", Void).getCallee());
  PHINode *funcphi = PHINode::Create(f_loop_invoke->getType(), 2, "funcphi");
  InstInsertPt pt;
  if (isa<LandingPadInst>(header->getFirstNonPHI()))
    pt = InstInsertPt::After(header->getFirstNonPHI());
  else
    pt = InstInsertPt::Before(header->getFirstNonPHI());
  pt << funcphi;
  for (auto pred : predecessors(header)) {
    if (pred == latch)
      funcphi->addIncoming(f_loop_iter, pred);
    else
      funcphi->addIncoming(f_loop_invoke, pred);
  }
  CallInst::Create(funcphi, "", header->getFirstNonPHI());
  SmallVector<BasicBlock *, 8> exits;
  loop->getExitBlocks(exits);
  set<BasicBlock *> s;
  for (unsigned i = 0; i < exits.size(); i++) {
    if (s.count(exits[i]))
      continue;
    CallInst *ci = CallInst::Create(f_loop_exit, "");
    InstInsertPt pt2;
    if (isa<LandingPadInst>(exits[i]->getFirstNonPHI()))
      pt2 = InstInsertPt::After(exits[i]->getFirstNonPHI());
    else
      pt2 = InstInsertPt::Before(exits[i]->getFirstNonPHI());
    pt2 << ci;
    s.insert(exits[i]);
  }
}
void SLAMP :: instrumentLoopStartStop ( Module & m , Loop * loop ) { BasicBlock * header = loop -> getHeader ( ) ; BasicBlock * latch = loop -> getLoopLatch ( ) ; assert ( loop -> getNumBackEdges ( ) == 1 && " " ) ; assert ( latch && " " ) ; auto * f_loop_invoke = cast < Function > ( m . getOrInsertFunction ( " " , Void ) . getCallee ( ) ) ; auto * f_loop_iter = cast < Function > ( m . getOrInsertFunction ( " " , Void ) . getCallee ( ) ) ; auto * f_loop_exit = cast < Function > ( m . getOrInsertFunction ( " " , Void ) . getCallee ( ) ) ; PHINode * funcphi = PHINode :: Create ( f_loop_invoke -> getType ( ) , 2 , " " ) ; InstInsertPt pt ; if ( isa < LandingPadInst > ( header -> getFirstNonPHI ( ) ) ) pt = InstInsertPt :: After ( header -> getFirstNonPHI ( ) ) ; else pt = InstInsertPt :: Before ( header -> getFirstNonPHI ( ) ) ; pt << funcphi ; for ( auto pred : predecessors ( header ) ) { if ( pred == latch ) funcphi -> addIncoming ( f_loop_iter , pred ) ; else funcphi -> addIncoming ( f_loop_invoke , pred ) ; } CallInst :: Create ( funcphi , " " , header -> getFirstNonPHI ( ) ) ; SmallVector < BasicBlock * , 8 > exits ; loop -> getExitBlocks ( exits ) ; set < BasicBlock * > s ; for ( unsigned i = 0 ; i < exits . size ( ) ; i ++ ) { if ( s . count ( exits [ i ] ) ) continue ; CallInst * ci = CallInst :: Create ( f_loop_exit , " " ) ; InstInsertPt pt2 ; if ( isa < LandingPadInst > ( exits [ i ] -> getFirstNonPHI ( ) ) ) pt2 = InstInsertPt :: After ( exits [ i ] -> getFirstNonPHI ( ) ) ; else pt2 = InstInsertPt :: Before ( exits [ i ] -> getFirstNonPHI ( ) ) ; pt2 << ci ; s . insert ( exits [ i ] ) ; } }
Pass in the loop and instrument invocation/iteration/exit hooks
Pass in the loop and instrument invocation / iteration / exit hooks
// TODO: check setjmp/longjmp // check if loop-simplify pass executed // add instrumentation on loop header: // if new invocation, call SLAMP_loop_invocation, else, call // SLAMP_loop_iteration // choose which function to execute (iter or invoke) // Add `SLAMP_loop_exit` to all loop exits // one instrumentation per block