Example #1
0
void
CallGraphPass::handleInstruction(llvm::CallSite cs, callgraphs::FunctionInfo *fun, llvm::Module &m){
  // Check whether the instruction is actually a call
  if (!cs.getInstruction()) {
    return;
  }

  // Check whether the called function is directly invoked
  auto called = dyn_cast<Function>(cs.getCalledValue()->stripPointerCasts());
  if (!called) {
    for(auto &f : m){
      if(f.hasAddressTaken()){
        
        bool match = true;
        std::vector< Type* > argslist;
        for (Use &U : cs.getInstruction()->operands()) {
          Value *v = U.get();
          argslist.push_back( v->getType() ); 
        }
        
        llvm::Function::ArgumentListType &alt = f.getArgumentList();
        int j = 0;
        for( auto &a : alt){
          if( a.getType() != argslist[j++]){
            match = false;
         }
        }
        
        if( argslist.size() > (j+1) && !f.isVarArg() ){
          match = false;
        }
        
        if(match){
          DILocation *Loc = cs.getInstruction()->getDebugLoc();
          callgraphs::CallInfo ci( &f, Loc->getLine() , Loc->getFilename(),
                                  funcs.find( fun->getFunction() )->second.callCount);
          funcs.find( &f )->second.weight++;
          funcs.find( fun->getFunction() )->second.directCalls.push_back( ci );
        }
        
        
      }
    }
    funcs.find( fun->getFunction() )->second.callCount++;
    return;
  }

  if(called->getName() == "llvm.dbg.declare")
    return;
    
  // Direct Calls heres
  DILocation *Loc = cs.getInstruction()->getDebugLoc();
  callgraphs::CallInfo ci(called, Loc->getLine() , Loc->getFilename(), 
    funcs.find( fun->getFunction() )->second.callCount  );
  funcs.find( called )->second.weight++;
  funcs.find( fun->getFunction() )->second.directCalls.push_back( ci );
  funcs.find( fun->getFunction() )->second.callCount++;
  
}
Example #2
0
bool DSCallGraph::hasPointers(llvm::CallSite& CS) {
  if (CS.getCalledFunction())
    return hasPointers(CS.getCalledFunction());

  const llvm::Value* Callee = CS.getCalledValue();
  const llvm::Type* T = Callee->getType();
  if (const llvm::PointerType* PT = llvm::dyn_cast<llvm::PointerType>(T))
    T = PT->getElementType();
  return _hasPointers(llvm::cast<llvm::FunctionType>(T));
}
Example #3
0
llvm::InlineCost ExtremeInliner::getInlineCost(llvm::CallSite callSite)
{
    llvm::Function *caller = callSite.getCaller();

    if (caller != m_function) {
        return llvm::InlineCost::getNever();
    }

    const llvm::Type *type = callSite.getType();
    if (!m_inlineVoids && (type->isVoidTy() || type->isFloatTy() || type->isDoubleTy() || llvm::isa<llvm::PointerType>(type))) {
        return llvm::InlineCost::getNever();
    }

    return llvm::InlineCost::getAlways();
}
Example #4
0
//
// Method: insert()
//
// Description:
//  Insert a new entry into the call graph.  This entry says that the specified
//  call site calls the specified function.
//
// Inputs:
//  CS - The call site which calls the specified function.
//  F  - The function which is called.  This is permitted to be NULL.  It is
//       possible to have call sites that don't have any targets, and sometimes
//       users just want to ensure that a call site has an entry within the
//       call graph.
//
void
DSCallGraph::insert(llvm::CallSite CS, const llvm::Function* F) {
  //
  // Find the function to which the call site belongs.
  //
  const llvm::Function * Parent = CS.getInstruction()->getParent()->getParent();

  //
  // Determine the SCC leaders for both the calling function and the called
  // function.  If they don't belong to an SCC, add them as leaders.
  //
  SCCs.insert (Parent);
  SCCs.insert (F);
  const llvm::Function * ParentLeader = SCCs.getLeaderValue (Parent);
  const llvm::Function * FLeader      = SCCs.getLeaderValue (F);

  //
  // Create an empty set for the callee; hence, all called functions get to be
  // in the call graph also.  This simplifies SCC formation.
  //
  SimpleCallees[ParentLeader];
  if (F) {
    ActualCallees[CS].insert(FLeader);
    SimpleCallees[ParentLeader].insert(FLeader);
  }
}
Example #5
0
/*!
 * Add indirect def an memory object in the function
 */
bool MRGenerator::addModSideEffectOfCallSite(llvm::CallSite cs, const NodeBS& mods) {
    if(!mods.empty()) {
        NodeBS modset = mods;
        modset &= getCallSitePts(cs);
        getGlobalsAndHeapFromPts(modset,mods);
        addModSideEffectOfFunction(cs.getCaller(),modset);
        return csToModsMap[cs] |= modset;
    }
    return false;
}
Example #6
0
/*!
 * Add indirect uses an memory object in the function
 */
bool MRGenerator::addRefSideEffectOfCallSite(llvm::CallSite cs, const NodeBS& refs) {
    if(!refs.empty()) {
        NodeBS refset = refs;
        refset &= getCallSitePts(cs);
        getGlobalsAndHeapFromPts(refset,refs);
        addRefSideEffectOfFunction(cs.getCaller(),refset);
        return csToRefsMap[cs] |= refset;
    }
    return false;
}
Example #7
0
void DSCallGraph::addFullFunctionSet(llvm::CallSite CS,
                    svset<const llvm::Function*> &Set) const {
  DSCallGraph::callee_iterator csi = callee_begin(CS),
                               cse = callee_end(CS);
  while(csi != cse) {
    const Function *F = *csi;
    Set.insert(scc_begin(F), scc_end(F));
    ++csi;
  }
  const Function *F1 = CS.getInstruction()->getParent()->getParent();
  F1 = sccLeader(&*F1);
  Set.insert(scc_begin(F1), scc_end(F1));
}