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++; }
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)); }
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(); }
// // 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); } }
/*! * 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; }
/*! * 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; }
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)); }