本文整理汇总了C++中DSGraph::getScalarMap方法的典型用法代码示例。如果您正苦于以下问题:C++ DSGraph::getScalarMap方法的具体用法?C++ DSGraph::getScalarMap怎么用?C++ DSGraph::getScalarMap使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DSGraph
的用法示例。
在下文中一共展示了DSGraph::getScalarMap方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: OptimizeGlobals
/// OptimizeGlobals - This method uses information taken from DSA to optimize
/// global variables.
///
bool DSOpt::OptimizeGlobals(Module &M) {
DSGraph* GG = TD->getGlobalsGraph();
const DSGraph::ScalarMapTy &SM = GG->getScalarMap();
bool Changed = false;
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
if (!I->isDeclaration()) { // Loop over all of the non-external globals...
// Look up the node corresponding to this global, if it exists.
DSNode *GNode = 0;
DSGraph::ScalarMapTy::const_iterator SMI = SM.find(I);
if (SMI != SM.end()) GNode = SMI->second.getNode();
if (GNode == 0 && I->hasInternalLinkage()) {
// If there is no entry in the scalar map for this global, it was never
// referenced in the program. If it has internal linkage, that means we
// can delete it. We don't ACTUALLY want to delete the global, just
// remove anything that references the global: later passes will take
// care of nuking it.
if (!I->use_empty()) {
I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
++NumGlobalsIsolated;
}
} else if (GNode && GNode->NodeType.isCompleteNode()) {
// If the node has not been read or written, and it is not externally
// visible, kill any references to it so it can be DCE'd.
if (!GNode->NodeType.isModifiedNode() && !GNode->NodeType.isReadNode() &&I->hasInternalLinkage()){
if (!I->use_empty()) {
I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
++NumGlobalsIsolated;
}
}
// We expect that there will almost always be a node for this global.
// If there is, and the node doesn't have the M bit set, we can set the
// 'constant' bit on the global.
if (!GNode->NodeType.isModifiedNode() && !I->isConstant()) {
I->setConstant(true);
++NumGlobalsConstanted;
Changed = true;
}
}
}
return Changed;
}
示例2: castTo
//
// Method: TransformCollapsedAllocas()
//
// Description:
// Transform all stack allocated objects that are type-unknown
// (i.e., are completely folded) to heap allocations.
//
void
ConvertUnsafeAllocas::TransformCollapsedAllocas(Module &M) {
//
// Need to check if the following is incomplete because we are only looking
// at scalars.
//
// It may be complete because every instruction actually is a scalar in
// LLVM?!
for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
if (!MI->isDeclaration()) {
DSGraph *G = budsPass->getDSGraph(*MI);
DSGraph::ScalarMapTy &SM = G->getScalarMap();
for (DSGraph::ScalarMapTy::iterator SMI = SM.begin(), SME = SM.end();
SMI != SME; ) {
if (AllocaInst *AI = dyn_cast<AllocaInst>((Value *)(SMI->first))) {
if (SMI->second.getNode()->isNodeCompletelyFolded()) {
Value *AllocSize =
ConstantInt::get(Int32Type,
TD->getTypeAllocSize(AI->getAllocatedType()));
if (AI->isArrayAllocation())
AllocSize = BinaryOperator::Create(Instruction::Mul, AllocSize,
AI->getOperand(0), "sizetmp",
AI);
CallInst *CI = CallInst::Create (kmalloc, AllocSize, "", AI);
Value * MI = castTo (CI, AI->getType(), "", AI);
InsertFreesAtEnd(CI);
AI->replaceAllUsesWith(MI);
SMI->second.getNode()->setHeapMarker();
SM.erase(SMI++);
AI->getParent()->getInstList().erase(AI);
++ConvAllocas;
} else {
++SMI;
}
} else {
++SMI;
}
}
}
}
}
示例3:
//
// Method: getFunctionTargets()
//
// Description:
// This method finds all of the potential targets of the specified indirect
// function call.
//
void
CompleteChecks::getFunctionTargets (CallSite CS,
std::vector<const Function *> & Targets) {
EQTDDataStructures & dsaPass = getAnalysis<EQTDDataStructures>();
const DSCallGraph & callgraph = dsaPass.getCallGraph();
DSGraph* G = dsaPass.getGlobalsGraph();
DSGraph::ScalarMapTy& SM = G->getScalarMap();
DSCallGraph::callee_iterator csi = callgraph.callee_begin(CS);
DSCallGraph::callee_iterator cse = callgraph.callee_end(CS);
for (; csi != cse; ++csi) {
const Function *F = *csi;
DSCallGraph::scc_iterator sccii = callgraph.scc_begin(F),
sccee = callgraph.scc_end(F);
for (;sccii != sccee; ++sccii) {
DSGraph::ScalarMapTy::const_iterator I =
SM.find(SM.getLeaderForGlobal(*sccii));
if (I != SM.end() && !((*sccii)->isDeclaration())) {
Targets.push_back (*sccii);
}
}
}
const Function *F1 = CS.getInstruction()->getParent()->getParent();
F1 = callgraph.sccLeader(&*F1);
DSCallGraph::scc_iterator sccii = callgraph.scc_begin(F1),
sccee = callgraph.scc_end(F1);
for(;sccii != sccee; ++sccii) {
DSGraph::ScalarMapTy::const_iterator I =
SM.find(SM.getLeaderForGlobal(*sccii));
if (I != SM.end() && !((*sccii)->isDeclaration())) {
Targets.push_back (*sccii);
}
}
return;
}
示例4: visitCallSite
//.........这里部分代码省略.........
std::vector<const DSNode*> ArgNodes;
DSGraph *CalleeGraph; // The callee graph
// For indirect callees, find any callee since all DS graphs have been
// merged.
if (CF) { // Direct calls are nice and simple.
DEBUG(errs() << " Handling direct call: " << *TheCall << "\n");
//
// Do not try to add pool handles to the function if it:
// a) Already calls a cloned function; or
// b) Calls a function which was never cloned.
//
// For such a call, just replace any arguments that take original functions
// with their cloned function poiner values.
//
FuncInfo *CFI = PAInfo.getFuncInfo(*CF);
if (CFI == 0 || CFI->Clone == 0) { // Nothing to transform...
visitInstruction(*TheCall);
return;
}
//
// Oh, dear. We must add pool descriptors to this direct call.
//
NewCallee = CFI->Clone;
ArgNodes = CFI->ArgNodes;
assert ((Graphs.hasDSGraph (*CF)) && "Function has no ECGraph!\n");
CalleeGraph = Graphs.getDSGraph(*CF);
} else {
DEBUG(errs() << " Handling indirect call: " << *TheCall << "\n");
DSGraph *G = Graphs.getGlobalsGraph();
DSGraph::ScalarMapTy& SM = G->getScalarMap();
// Here we fill in CF with one of the possible called functions. Because we
// merged together all of the arguments to all of the functions in the
// equivalence set, it doesn't really matter which one we pick.
// (If the function was cloned, we have to map the cloned call instruction
// in CS back to the original call instruction.)
Instruction *OrigInst =
cast<Instruction>(getOldValueIfAvailable(CS.getInstruction()));
//
// Attempt to get one of the function targets of this indirect call site by
// looking at the call graph constructed by the points-to analysis. Be
// sure to use the original call site from the original function; the
// points-to analysis has no information on the clones we've created.
//
// Also, look for the target that has the greatest number of arguments that
// have associated DSNodes. This ensures that we pass the maximum number
// of pools possible and prevents us from eliding a pool because we're
// examining a target that doesn't need it.
//
const DSCallGraph & callGraph = Graphs.getCallGraph();
DSCallGraph::callee_iterator I = callGraph.callee_begin(OrigInst);
for (; I != callGraph.callee_end(OrigInst); ++I) {
for(DSCallGraph::scc_iterator sccii = callGraph.scc_begin(*I),
sccee = callGraph.scc_end(*I); sccii != sccee; ++sccii){
if(SM.find(SM.getLeaderForGlobal(*sccii)) == SM.end())
continue;
//
// Get the information for this function. Since this is coming from
// DSA, it should be an original function.
//
示例5: alias
AliasAnalysis::AliasResult DSAAA::alias(const AliasAnalysis::Location& l1, const AliasAnalysis::Location& l2)
{
DSAAA_TOTAL_ANSWER++;
if (l1.Size == 0 || l2.Size == 0)
return NoAlias;
/// ? Zhiyuan: weired, l1 & l2's locations are both instructions, in my opinion, they should be operands
const Value* v1 = (l1.Ptr)->stripPointerCasts();
const Value* v2 = (l2.Ptr)->stripPointerCasts();
if (!v1->getType()->isPointerTy() || !v2->getType()->isPointerTy())
return NoAlias;
if (v1 == v2) return MustAlias;
DSGraph *G1 = getGraphForValue(v1);
DSGraph *G2 = getGraphForValue(v2);
assert((!G1 || !G2 || G1 == G2) && "Alias query for 2 different functions?");
const Function *func = nullptr;
/// Zhiyuan: Debug
if (const Instruction *I = dyn_cast<Instruction>(v1)) {
func = I->getParent()->getParent();
} else if (const Argument *A = dyn_cast<Argument>(v1)) {
func = A->getParent();
} else if (const BasicBlock *BB = dyn_cast<BasicBlock>(v1)) {
func = BB->getParent();
}
if (func != nullptr) {
//errs() << "[DSAAA Debug] We are in function [" << func->getName() << "].\n";
DEBUG_QueryFunctionSet.insert(func->getName().str());
}
DSAAA_TOTAL_QUERY_FUNCTIONS = DEBUG_QueryFunctionSet.size();
// Get the graph to use...
DSGraph* G = G1 ? G1 : (G2 ? G2 : TD->getGlobalsGraph());
const DSGraph::ScalarMapTy &GSM = G->getScalarMap();
DSGraph::ScalarMapTy::const_iterator I = GSM.find((Value*)v1);
if (I == GSM.end()) return NoAlias;
DSGraph::ScalarMapTy::const_iterator J = GSM.find((Value*)v2);
if (J == GSM.end()) return NoAlias;
DSNode *N1 = I->second.getNode(), *N2 = J->second.getNode();
unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset();
if (N1 == nullptr || N2 == nullptr) {
// Can't tell whether anything aliases null.
errs() << "[DSAAA DEBUG] nullptr for this value. \n";
return AliasAnalysis::alias(l1, l2);
}
if (!N1->isCompleteNode() && !N2->isCompleteNode()) {
// if (llvm::DebugFlag) {
// errs() << "We calculate MayAlias here.\n";
// errs() << "v1 = " << *(l1.Ptr) << "; v2 = " << *(l2.Ptr) << "\n";
// errs() << "N1 = " << N1 << "; N2 = " << N2 << "\n";
// errs() << "N1 complete? " << N1->isCompleteNode() << "; N2 complete? " << N2->isCompleteNode() << "\n";
// }
if (N1 == N2) {
DSAAA_INCOMPLETE_SAME_NODE++;
}
DSAAA_INCOMPLETE_NODE++;
DEBUG_IncompleteNodeSet.insert(N1);
DSAAA_INCOMPLETE_NODE_COUNT = DEBUG_IncompleteNodeSet.size();
if ( llvm::DebugFlag && func != nullptr && func->getName().str() == "BZ2_decompress") {
errs() << "[DSAAA DEBUG] # of referrers: " << N1->getNumReferrers() << "\n";
// errs() << "[DSAAA DEBUG] # of links: " << N1->getLinkCount() << "\n";
N1->print(errs(), G);
const DSScalarMap &SM = G->getScalarMap();
int refCount = 1;
for (DSScalarMap::const_iterator i = SM.begin(); i != SM.end(); i++) {
if (i->second.getNode() == N1 && refCount < 240) {
errs() << refCount++ <<": " << *(i->first) << "\n";
}
}
//exit(0);
}
return AliasAnalysis::alias(l1, l2);
}
// We can only make a judgment if one of the nodes is complete.
if (N1->isCompleteNode() || N2->isCompleteNode()) {
if (N1 != N2) return NoAlias; // Completely different nodes.
// See if they point to different offsets... if so, we may be able to
// determine that they do not alias...
if (O1 != O2) {
uint64_t V1Size = l1.Size;
uint64_t V2Size = l2.Size;
if (O2 < O1) { // Ensure that O1 <= O2
std::swap(v1, v2);
std::swap(O1, O2);
std::swap(V1Size, V2Size);
}
if (O1+V1Size <= O2) return NoAlias;
}
}
/**
* Below added by Zhiyuan
//.........这里部分代码省略.........
示例6: cs
void CallTargetFinder<dsa>::findIndTargets(Module &M)
{
dsa* T = &getAnalysis<dsa>();
const DSCallGraph & callgraph = T->getCallGraph();
DSGraph* G = T->getGlobalsGraph();
DSGraph::ScalarMapTy& SM = G->getScalarMap();
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration())
for (Function::iterator F = I->begin(), FE = I->end(); F != FE; ++F)
for (BasicBlock::iterator B = F->begin(), BE = F->end(); B != BE; ++B)
if (isa<CallInst>(B) || isa<InvokeInst>(B)) {
CallSite cs(B);
AllSites.push_back(cs);
Function* CF = cs.getCalledFunction();
if (isa<UndefValue>(cs.getCalledValue())) continue;
if (isa<InlineAsm>(cs.getCalledValue())) continue;
//
// If the called function is casted from one function type to
// another, peer into the cast instruction and pull out the actual
// function being called.
//
if (!CF)
CF = dyn_cast<Function>(cs.getCalledValue()->stripPointerCasts());
if (!CF) {
Value * calledValue = cs.getCalledValue()->stripPointerCasts();
if (isa<ConstantPointerNull>(calledValue)) {
++DirCall;
CompleteSites.insert(cs);
} else {
IndCall++;
DSCallGraph::callee_iterator csi = callgraph.callee_begin(cs),
cse = callgraph.callee_end(cs);
while(csi != cse) {
const Function *F = *csi;
DSCallGraph::scc_iterator sccii = callgraph.scc_begin(F),
sccee = callgraph.scc_end(F);
for(;sccii != sccee; ++sccii) {
DSGraph::ScalarMapTy::const_iterator I = SM.find(SM.getLeaderForGlobal(*sccii));
if (I != SM.end()) {
IndMap[cs].push_back (*sccii);
}
}
++csi;
}
const Function *F1 = (cs).getInstruction()->getParent()->getParent();
F1 = callgraph.sccLeader(&*F1);
DSCallGraph::scc_iterator sccii = callgraph.scc_begin(F1),
sccee = callgraph.scc_end(F1);
for(;sccii != sccee; ++sccii) {
DSGraph::ScalarMapTy::const_iterator I = SM.find(SM.getLeaderForGlobal(*sccii));
if (I != SM.end()) {
IndMap[cs].push_back (*sccii);
}
}
DSNode* N = T->getDSGraph(*cs.getCaller())
->getNodeForValue(cs.getCalledValue()).getNode();
assert (N && "CallTarget: findIndTargets: No DSNode!");
if (!N->isIncompleteNode() && !N->isExternalNode() && IndMap[cs].size()) {
CompleteSites.insert(cs);
++CompleteInd;
}
if (!N->isIncompleteNode() && !N->isExternalNode() && !IndMap[cs].size()) {
++CompleteEmpty;
DEBUG(errs() << "Call site empty: '"
<< cs.getInstruction()->getName()
<< "' In '"
<< cs.getInstruction()->getParent()->getParent()->getName()
<< "'\n");
}
}
} else {
++DirCall;
IndMap[cs].push_back(CF);
CompleteSites.insert(cs);
}
}
//Print the indirect call Map:
for(std::map<CallSite, std::vector<const Function*> >::iterator indMapIt = IndMap.begin(); indMapIt != IndMap.end(); ++indMapIt )
{
CallSite CS = indMapIt->first;
Instruction* Inst = CS.getInstruction();
Inst->dump();
}
}
示例7: ComputeInverseGraphFrom
/// ProcessNodesReachableFromGlobals - If we inferred anything about nodes
/// reachable from globals, we have to make sure that we incorporate data for
/// all graphs that include those globals due to the nature of the globals
/// graph.
///
void StructureFieldVisitorBase::
ProcessNodesReachableFromGlobals(DSGraph &DSG,
std::multimap<DSNode*,LatticeValue*> &NodeLVs){
// Start by marking all nodes reachable from globals.
DSScalarMap &SM = DSG.getScalarMap();
if (SM.global_begin() == SM.global_end()) return;
hash_set<const DSNode*> Reachable;
for (DSScalarMap::global_iterator GI = SM.global_begin(),
E = SM.global_end(); GI != E; ++GI)
SM[*GI].getNode()->markReachableNodes(Reachable);
if (Reachable.empty()) return;
// If any of the nodes with dataflow facts are reachable from the globals
// graph, we have to do the GG processing step.
bool MustProcessThroughGlobalsGraph = false;
for (std::multimap<DSNode*, LatticeValue*>::iterator I = NodeLVs.begin(),
E = NodeLVs.end(); I != E; ++I)
if (Reachable.count(I->first)) {
MustProcessThroughGlobalsGraph = true;
break;
}
if (!MustProcessThroughGlobalsGraph) return;
Reachable.clear();
// Compute the mapping from DSG to the globals graph.
DSGraph::NodeMapTy DSGToGGMap;
DSG.computeGToGGMapping(DSGToGGMap);
// Most of the times when we find facts about things reachable from globals we
// we are in the main graph. This means that we have *all* of the globals
// graph in this DSG. To be efficient, we compute the minimum set of globals
// that can reach any of the NodeLVs facts.
//
// I'm not aware of any wonderful way of computing the set of globals that
// points to the set of nodes in NodeLVs that is not N^2 in either NodeLVs or
// the number of globals, except to compute the inverse of DSG. As such, we
// compute the inverse graph of DSG, which basically has the edges going from
// pointed to nodes to pointing nodes. Because we only care about one
// connectedness properties, we ignore field info. In addition, we only
// compute inverse of the portion of the graph reachable from the globals.
std::set<std::pair<DSNode*,DSNode*> > InverseGraph;
for (DSScalarMap::global_iterator GI = SM.global_begin(),
E = SM.global_end(); GI != E; ++GI)
ComputeInverseGraphFrom(SM[*GI].getNode(), InverseGraph);
// Okay, now that we have our bastardized inverse graph, compute the set of
// globals nodes reachable from our lattice nodes.
for (std::multimap<DSNode*, LatticeValue*>::iterator I = NodeLVs.begin(),
E = NodeLVs.end(); I != E; ++I)
ComputeNodesReachableFrom(I->first, InverseGraph, Reachable);
// Now that we know which nodes point to the data flow facts, figure out which
// globals point to the data flow facts.
std::set<GlobalValue*> Globals;
for (hash_set<const DSNode*>::iterator I = Reachable.begin(),
E = Reachable.end(); I != E; ++I)
Globals.insert((*I)->globals_begin(), (*I)->globals_end());
// Finally, loop over all of the DSGraphs for the program, computing
// information for the graph if not done already, mapping the result into our
// context.
for (hash_map<const Function*, DSGraph*>::iterator GI = ECG.DSInfo.begin(),
E = ECG.DSInfo.end(); GI != E; ++GI) {
DSGraph &FG = *GI->second;
// Graphs can contain multiple functions, only process the graph once.
if (GI->first != FG.retnodes_begin()->first ||
// Also, do not bother reprocessing DSG.
&FG == &DSG)
continue;
bool GraphUsesGlobal = false;
for (std::set<GlobalValue*>::iterator I = Globals.begin(),
E = Globals.end(); I != E; ++I)
if (FG.getScalarMap().count(*I)) {
GraphUsesGlobal = true;
break;
}
// If this graph does not contain the global at all, there is no reason to
// even think about it.
if (!GraphUsesGlobal) continue;
// Otherwise, compute the full set of dataflow effects of the function.
std::multimap<DSNode*, LatticeValue*> &FGF = getCalleeFacts(FG);
//std::cerr << "Computed: " << FG.getFunctionNames() << "\n";
#if 0
for (std::multimap<DSNode*, LatticeValue*>::iterator I = FGF.begin(),
E = FGF.end(); I != E; ++I)
I->second->dump();
#endif
// Compute the mapping of nodes in the globals graph to the function's
//.........这里部分代码省略.........
示例8: TransformAllocasToMallocs
// Precondition: Enforce that the alloca nodes haven't been already converted
void ConvertUnsafeAllocas::TransformAllocasToMallocs(std::list<DSNode *>
& unsafeAllocaNodes) {
std::list<DSNode *>::const_iterator iCurrent = unsafeAllocaNodes.begin(),
iEnd = unsafeAllocaNodes.end();
for (; iCurrent != iEnd; ++iCurrent) {
DSNode *DSN = *iCurrent;
// Now change the alloca instruction corresponding to the node
// to malloc
DSGraph *DSG = DSN->getParentGraph();
DSGraph::ScalarMapTy &SM = DSG->getScalarMap();
#ifndef LLVA_KERNEL
Instruction *MI = 0;
#else
Value *MI = 0;
#endif
for (DSGraph::ScalarMapTy::iterator SMI = SM.begin(), SME = SM.end();
SMI != SME; ) {
bool stackAllocate = true;
// If this is already a heap node, then you cannot allocate this on the
// stack
if (DSN->isHeapNode()) {
stackAllocate = false;
}
if (SMI->second.getNode() == DSN) {
if (AllocaInst *AI = dyn_cast<AllocaInst>((Value *)(SMI->first))) {
//
// Create a new heap allocation instruction.
//
if (AI->getParent() != 0) {
//
// Create an LLVM value representing the size of the allocation.
// If it's an array allocation, we'll need to insert a
// multiplication instruction to get the size times the number of
// elements.
//
unsigned long size = TD->getTypeAllocSize(AI->getAllocatedType());
Value *AllocSize = ConstantInt::get(Int32Type, size);
if (AI->isArrayAllocation())
AllocSize = BinaryOperator::Create(Instruction::Mul, AllocSize,
AI->getOperand(0), "sizetmp",
AI);
std::vector<Value *> args(1, AllocSize);
CallInst *CI = CallInst::Create (kmalloc, args.begin(), args.end(), "", AI);
MI = castTo (CI, AI->getType(), "", AI);
DSN->setHeapMarker();
AI->replaceAllUsesWith(MI);
SM.erase(SMI++);
AI->getParent()->getInstList().erase(AI);
++ConvAllocas;
InsertFreesAtEnd(MI);
#ifndef LLVA_KERNEL
if (stackAllocate) {
ArrayMallocs.insert(MI);
}
#endif
} else {
++SMI;
}
} else {
++SMI;
}
} else {
++SMI;
}
}
}
}