本文整理汇总了C++中DSGraph::getNodeForValue方法的典型用法代码示例。如果您正苦于以下问题:C++ DSGraph::getNodeForValue方法的具体用法?C++ DSGraph::getNodeForValue怎么用?C++ DSGraph::getNodeForValue使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DSGraph
的用法示例。
在下文中一共展示了DSGraph::getNodeForValue方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
//
// Method: getDSNodeHandle()
//
// Description:
// This method looks up the DSNodeHandle for a given LLVM value. The context
// of the value is the specified function, although if it is a global value,
// the DSNodeHandle may exist within the global DSGraph.
//
// Return value:
// A DSNodeHandle for the value is returned. This DSNodeHandle could either
// be in the function's DSGraph or from the GlobalsGraph. Note that the
// DSNodeHandle may represent a NULL DSNode.
//
DSNodeHandle
CompleteChecks::getDSNodeHandle (const Value * V, const Function * F) {
//
// Get access to the points-to results.
//
EQTDDataStructures & dsaPass = getAnalysis<EQTDDataStructures>();
//
// Ensure that the function has a DSGraph
//
assert (dsaPass.hasDSGraph(*F) && "No DSGraph for function!\n");
//
// Lookup the DSNode for the value in the function's DSGraph.
//
DSGraph * TDG = dsaPass.getDSGraph(*F);
DSNodeHandle DSH = TDG->getNodeForValue(V);
//
// If the value wasn't found in the function's DSGraph, then maybe we can
// find the value in the globals graph.
//
if ((DSH.isNull()) && (isa<GlobalValue>(V))) {
//
// Try looking up this DSNode value in the globals graph. Note that
// globals are put into equivalence classes; we may need to first find the
// equivalence class to which our global belongs, find the global that
// represents all globals in that equivalence class, and then look up the
// DSNode Handle for *that* global.
//
DSGraph * GlobalsGraph = TDG->getGlobalsGraph ();
DSH = GlobalsGraph->getNodeForValue(V);
if (DSH.isNull()) {
//
// DSA does not currently handle global aliases.
//
if (!isa<GlobalAlias>(V)) {
//
// We have to dig into the globalEC of the DSGraph to find the DSNode.
//
const GlobalValue * GV = dyn_cast<GlobalValue>(V);
const GlobalValue * Leader;
Leader = GlobalsGraph->getGlobalECs().getLeaderValue(GV);
DSH = GlobalsGraph->getNodeForValue(Leader);
}
}
}
return DSH;
}
示例2: Builder
//
// Method: getUnsafeAllocsFromABC()
//
// Description:
// Find all memory objects that are both allocated on the stack and are not
// proven to be indexed in a type-safe manner according to the static array
// bounds checking pass.
//
// Notes:
// This method saves its results be remembering the set of DSNodes which are
// both on the stack and potentially indexed in a type-unsafe manner.
//
// FIXME:
// This method only considers unsafe GEP instructions; it does not consider
// unsafe call instructions or other instructions deemed unsafe by the array
// bounds checking pass.
//
void
ConvertUnsafeAllocas::getUnsafeAllocsFromABC(Module & M) {
UnsafeAllocaNodeListBuilder Builder(budsPass, unsafeAllocaNodes);
Builder.visit(M);
#if 0
// Haohui: Disable it right now since nobody using the code
std::map<BasicBlock *,std::set<Instruction*>*> UnsafeGEPMap= abcPass->UnsafeGetElemPtrs;
std::map<BasicBlock *,std::set<Instruction*>*>::const_iterator bCurrent = UnsafeGEPMap.begin(), bEnd = UnsafeGEPMap.end();
for (; bCurrent != bEnd; ++bCurrent) {
std::set<Instruction *> * UnsafeGetElemPtrs = bCurrent->second;
std::set<Instruction *>::const_iterator iCurrent = UnsafeGetElemPtrs->begin(), iEnd = UnsafeGetElemPtrs->end();
for (; iCurrent != iEnd; ++iCurrent) {
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*iCurrent)) {
Value *pointerOperand = GEP->getPointerOperand();
DSGraph * TDG = budsPass->getDSGraph(*(GEP->getParent()->getParent()));
DSNode *DSN = TDG->getNodeForValue(pointerOperand).getNode();
//FIXME DO we really need this ? markReachableAllocas(DSN);
if (DSN && DSN->isAllocaNode() && !DSN->isNodeCompletelyFolded()) {
unsafeAllocaNodes.push_back(DSN);
}
} else {
//call instruction add the corresponding *iCurrent->dump();
//FIXME abort();
}
}
}
#endif
}
示例3: visitGetElementPtrInst
void visitGetElementPtrInst(GetElementPtrInst &GEP) {
Value *pointerOperand = GEP.getPointerOperand();
DSGraph * TDG = budsPass->getDSGraph(*(GEP.getParent()->getParent()));
DSNode *DSN = TDG->getNodeForValue(pointerOperand).getNode();
//FIXME DO we really need this ? markReachableAllocas(DSN);
if (DSN && DSN->isAllocaNode() && !DSN->isNodeCompletelyFolded()) {
unsafeAllocaNodes.push_back(DSN);
}
}
示例4: assert
void
PoolRegisterElimination::removeTypeSafeRegistrations (const char * name) {
//
// Scan through all uses of the registration function and see if it can be
// safely removed. If so, schedule it for removal.
//
std::vector<CallInst*> toBeRemoved;
Function * F = intrinsic->getIntrinsic(name).F;
//
// Look for and record all registrations that can be deleted.
//
for (Value::use_iterator UI=F->use_begin(), UE=F->use_end();
UI != UE;
++UI) {
//
// Get the pointer to the registered object.
//
CallInst * CI = cast<CallInst>(*UI);
Value * Ptr = intrinsic->getValuePointer(CI);
// Lookup the DSNode for the value in the function's DSGraph.
//
DSGraph * TDG = dsaPass->getDSGraph(*(CI->getParent()->getParent()));
DSNodeHandle DSH = TDG->getNodeForValue(Ptr);
assert ((!(DSH.isNull())) && "No DSNode for Value!\n");
//
// If the DSNode is type-safe and is never used as an array, then there
// will never be a need to look it up in a splay tree, so remove its
// registration.
//
DSNode * N = DSH.getNode();
if(!N->isArrayNode() &&
TS->isTypeSafe(Ptr, F)){
toBeRemoved.push_back(CI);
}
}
//
// Update the statistics.
//
if (toBeRemoved.size()) {
RemovedRegistration += toBeRemoved.size();
TypeSafeRegistrations += toBeRemoved.size();
}
//
// Remove the unnecesary registrations.
//
std::vector<CallInst*>::iterator it, end;
for (it = toBeRemoved.begin(), end = toBeRemoved.end(); it != end; ++it) {
(*it)->eraseFromParent();
}
}
示例5: printSourceInfo
//
// Method: insertHardDanglingPointers()
//
// Description:
// Insert dangling pointer dereferences into the code. This is done by
// finding instructions that store pointers to memory and free'ing those
// pointers before the store. Subsequent loads and uses of the pointer will
// cause a dangling pointer dereference.
//
// Return value:
// true - The module was modified.
// false - The module was left unmodified.
//
// Notes:
// This code utilizes DSA to ensure that the pointer can point to heap
// memory (although the pointer is allowed to alias global and stack memory).
//
bool
FaultInjector::insertHardDanglingPointers (Function & F) {
//
// Ensure that we can get analysis information for this function.
//
if (!(TDPass->hasDSGraph(F)))
return false;
//
// Scan through each instruction of the function looking for store
// instructions that store a pointer to memory. Free the pointer right
// before the store instruction.
//
DSGraph * DSG = TDPass->getDSGraph(F);
for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
BasicBlock & BB = *fI;
for (BasicBlock::iterator bI = BB.begin(), bE = BB.end(); bI != bE; ++bI) {
Instruction * I = bI;
//
// Look to see if there is an instruction that stores a pointer to
// memory. If so, then free the pointer before the store.
//
if (StoreInst * SI = dyn_cast<StoreInst>(I)) {
if (isa<PointerType>(SI->getOperand(0)->getType())) {
Value * Pointer = SI->getOperand(0);
//
// Check to ensure that the pointer aliases with the heap. If so, go
// ahead and add the free. Note that we may introduce an invalid
// free, but we're injecting errors, so I think that's okay.
//
DSNode * Node = DSG->getNodeForValue(Pointer).getNode();
if (Node && (Node->isHeapNode())) {
// Skip if we should not insert a fault.
if (!doFault()) continue;
//
// Print information about where the fault is being inserted.
//
printSourceInfo ("Hard dangling pointer", I);
CallInst::Create (Free, Pointer, "", I);
++DPFaults;
}
}
}
}
}
return (DPFaults > 0);
}
示例6: getDSGraph
//
// Function: processRuntimeCheck()
//
// Description:
// Modify a run-time check so that its return value has the same DSNode as the
// checked pointer.
//
// Inputs:
// M - The module in which calls to the function live.
// name - The name of the function for which direct calls should be processed.
// arg - The argument index that contains the pointer which the run-time
// check returns.
//
void
StdLibDataStructures::processRuntimeCheck (Module & M,
std::string name,
unsigned arg) {
//
// Get a pointer to the function.
//
Function* F = M.getFunction (name);
//
// If the function doesn't exist, then there is no work to do.
//
if (!F) return;
//
// Scan through all direct calls to the function (there should only be direct
// calls) and process each one.
//
for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
ii != ee; ++ii) {
if (CallInst* CI = dyn_cast<CallInst>(*ii)) {
if (CI->getCalledValue() == F) {
DSGraph* Graph = getDSGraph(*CI->getParent()->getParent());
DSNodeHandle & RetNode = Graph->getNodeForValue(CI);
DSNodeHandle & ArgNode = Graph->getNodeForValue(CI->getArgOperand(arg));
RetNode.mergeWith(ArgNode);
}
}
}
//
// Erase the DSCallSites for this function. This should prevent other DSA
// passes from making the DSNodes passed to/returned from the function
// from becoming Incomplete or External.
//
eraseCallsTo (F);
return;
}
示例7: initialize
void initialize(const Module *M, const DataStructures *DS) {
parseValue(M);
assert(V && "Failed to parse value?");
if (isa<GlobalValue>(V)) {
DSGraph *G = DS->getGlobalsGraph();
assert(G->hasNodeForValue(V) && "Node not in specified graph!");
NH = G->getNodeForValue(V);
} else {
assert(F && "No function?");
DSGraph *G = DS->getDSGraph(*F);
assert(G->hasNodeForValue(V) && "Node not in specified graph!");
NH = G->getNodeForValue(V);
}
// Handle offsets, if any
// For each offset in the offsets vector, follow the link at that offset
for (OffsetVectorTy::const_iterator I = offsets.begin(), E = offsets.end();
I != E; ++I ) {
assert(!NH.isNull() && "Null NodeHandle?");
assert(NH.hasLink(*I) && "Handle doesn't have link?");
// Follow the offset
NH = NH.getLink(*I);
}
}
示例8: runOnModule
bool CSDataRando::runOnModule(Module &M) {
DSA = &getAnalysis<BUMarkDoNotEncrypt>();
MaskTy = TypeBuilder<mask_t, false>::get(M.getContext());
FunctionWrappers &FW = getAnalysis<FunctionWrappers>();
{
// Gather statistics on the globals
DenseMap<const DSNode*, unsigned int> GlobalClassSizes;
DSGraph *GG = DSA->getGlobalsGraph();
for (GlobalVariable &GV : M.getGlobalList()) {
if (!(GV.isDeclaration() || PointerEquivalenceAnalysis::shouldIgnoreGlobal(GV))) {
GlobalClassSizes[GG->getNodeForValue(&GV).getNode()] += 1;
}
}
NumGlobalECs = GlobalClassSizes.size();
for (auto i : GlobalClassSizes) {
if (i.second > MaxSizeGlobalEC) {
MaxSizeGlobalEC = i.second;
}
}
}
findGlobalNodes(M);
findArgNodes(M);
// Find which functions may need cloning. If we have a DSGraph for the
// function, consider it a candidate for cloning.
std::vector<Function *> OriginalFunctions;
for (Function &F : M) {
if (!F.isDeclaration() && DSA->hasDSGraph(F)) {
OriginalFunctions.push_back(&F);
}
}
// Perform cloning of the original functions
Function *Main = M.getFunction("main");
for (Function *Original : OriginalFunctions) {
// Handle the main function
if (Main && Original == Main) {
// Never clone main
OldToNewFuncMap[Original] = nullptr;
// If main has no uses then we can encrypt the arguments to main. To allow
// the arg nodes to be encrypted we clear ArgNodes.
if (Original->uses().begin() == Original->uses().end()) {
FunctionInfo[Original].ArgNodes.clear();
}
continue;
}
// Maybe make a clone, if a clone was not made nullptr is returned.
OldToNewFuncMap[Original] = makeFunctionClone(Original);
}
// File to potentially print diagnostic information
std::unique_ptr<tool_output_file> Out(nullptr);
// If we will be printing diagnostic information, open the file
if (!PointerEquivalenceAnalysis::PrintEquivalenceClassesTo.empty()) {
std::error_code error;
Out.reset(new tool_output_file(PointerEquivalenceAnalysis::PrintEquivalenceClassesTo,
error,
sys::fs::F_None));
if (error) {
Out.release();
}
}
// Perform randomization
DataRandomizer DR(M);
RandomNumberGenerator *RNG = M.createRNG(this);
FuncInfo empty;
ContextSensitivePEA GGPEA(*RNG, M.getContext(), empty, *DSA->getGlobalsGraph());
DR.encryptGlobalVariables(M, GGPEA);
// All original functions with DSGraphs will be in OldToNewFuncMap. If a clone
// was not made, then the entry will map to nullptr.
for (auto i : OldToNewFuncMap) {
Function *Original = i.first;
Function *Clone = i.second;
FuncInfo &FI = FunctionInfo[Original];
DSGraph *Graph = DSA->getDSGraph(*Original);
if (Clone) {
// Perform randomization of the cloned function
CloneFunctionPEA CP(*RNG, M.getContext(), FI, *Graph, &GGPEA);
DR.instrumentMemoryOperations(*Clone, CP, NULL);
DR.wrapLibraryFunctions(*Clone, CP, FW);
replaceWithClones(Clone, FI, CP, Graph);
if (Out.get()) {
// Add all Instructions before dumping to make the dump more complete.
addAllInstructions(Clone, CP);
Out->os() << "*** Equivalence classes for: " << Clone->getName() << " ***\n";
CP.printEquivalenceClasses(Out->os());
Out->os() << "*** End of equivalence classes for: " << Clone->getName() << " ***\n";
}
}
// Perform randomization of the original function
//.........这里部分代码省略.........
示例9: InlineCallersIntoGraph
/// InlineCallersIntoGraph - Inline all of the callers of the specified DS graph
/// into it, then recompute completeness of nodes in the resultant graph.
void TDDataStructures::InlineCallersIntoGraph(DSGraph* DSG) {
// Inline caller graphs into this graph. First step, get the list of call
// sites that call into this graph.
std::vector<CallerCallEdge> EdgesFromCaller;
std::map<DSGraph*, std::vector<CallerCallEdge> >::iterator
CEI = CallerEdges.find(DSG);
if (CEI != CallerEdges.end()) {
std::swap(CEI->second, EdgesFromCaller);
CallerEdges.erase(CEI);
}
// Sort the caller sites to provide a by-caller-graph ordering.
std::sort(EdgesFromCaller.begin(), EdgesFromCaller.end());
// Merge information from the globals graph into this graph. FIXME: This is
// stupid. Instead of us cloning information from the GG into this graph,
// then having RemoveDeadNodes clone it back, we should do all of this as a
// post-pass over all of the graphs. We need to take cloning out of
// removeDeadNodes and gut removeDeadNodes at the same time first though. :(
{
DSGraph* GG = DSG->getGlobalsGraph();
ReachabilityCloner RC(DSG, GG,
DSGraph::DontCloneCallNodes |
DSGraph::DontCloneAuxCallNodes);
for (DSScalarMap::global_iterator
GI = DSG->getScalarMap().global_begin(),
E = DSG->getScalarMap().global_end(); GI != E; ++GI)
RC.getClonedNH(GG->getNodeForValue(*GI));
}
DEBUG(errs() << "[TD] Inlining callers into '"
<< DSG->getFunctionNames() << "'\n");
// Iteratively inline caller graphs into this graph.
while (!EdgesFromCaller.empty()) {
DSGraph* CallerGraph = EdgesFromCaller.back().CallerGraph;
// Iterate through all of the call sites of this graph, cloning and merging
// any nodes required by the call.
ReachabilityCloner RC(DSG, CallerGraph,
DSGraph::DontCloneCallNodes |
DSGraph::DontCloneAuxCallNodes);
// Inline all call sites from this caller graph.
do {
const DSCallSite &CS = *EdgesFromCaller.back().CS;
const Function &CF = *EdgesFromCaller.back().CalledFunction;
DEBUG(errs() << " [TD] Inlining graph into Fn '"
<< CF.getNameStr() << "' from ");
if (CallerGraph->getReturnNodes().empty()) {
DEBUG(errs() << "SYNTHESIZED INDIRECT GRAPH");
} else {
DEBUG(errs() << "Fn '" << CS.getCallSite().getInstruction()->
getParent()->getParent()->getNameStr() << "'");
}
DEBUG(errs() << ": " << CF.getFunctionType()->getNumParams()
<< " args\n");
// Get the formal argument and return nodes for the called function and
// merge them with the cloned subgraph.
DSCallSite T1 = DSG->getCallSiteForArguments(CF);
RC.mergeCallSite(T1, CS);
++NumTDInlines;
EdgesFromCaller.pop_back();
} while (!EdgesFromCaller.empty() &&
EdgesFromCaller.back().CallerGraph == CallerGraph);
}
{
DSGraph* GG = DSG->getGlobalsGraph();
ReachabilityCloner RC(GG, DSG,
DSGraph::DontCloneCallNodes |
DSGraph::DontCloneAuxCallNodes);
for (DSScalarMap::global_iterator
GI = DSG->getScalarMap().global_begin(),
E = DSG->getScalarMap().global_end(); GI != E; ++GI)
RC.getClonedNH(DSG->getNodeForValue(*GI));
}
// Next, now that this graph is finalized, we need to recompute the
// incompleteness markers for this graph and remove unreachable nodes.
DSG->maskIncompleteMarkers();
// If any of the functions has incomplete incoming arguments, don't mark any
// of them as complete.
bool HasIncompleteArgs = false;
for (DSGraph::retnodes_iterator I = DSG->retnodes_begin(),
E = DSG->retnodes_end(); I != E; ++I)
if (ArgsRemainIncomplete.count(I->first)) {
HasIncompleteArgs = true;
break;
}
// Recompute the Incomplete markers. Depends on whether args are complete
unsigned Flags
//.........这里部分代码省略.........
示例10: replaceCall
void RTAssociate::replaceCall(CallSite CS, FuncInfo& FI, DataStructures* DS) {
const Function *CF = CS.getCalledFunction();
Instruction *TheCall = CS.getInstruction();
// 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 (ConstantExpr *CE = dyn_cast<ConstantExpr>(CS.getCalledValue()))
if (CE->getOpcode() == Instruction::BitCast &&
isa<Function>(CE->getOperand(0)))
CF = cast<Function>(CE->getOperand(0));
if (isa<InlineAsm>(TheCall->getOperand(0))) {
errs() << "INLINE ASM: ignoring. Hoping that's safe.\n";
return;
}
// Ignore calls to NULL pointers.
if (isa<ConstantPointerNull>(CS.getCalledValue())) {
errs() << "WARNING: Ignoring call using NULL function pointer.\n";
return;
}
// We need to figure out which local pool descriptors correspond to the pool
// descriptor arguments passed into the function call. Calculate a mapping
// from callee DSNodes to caller DSNodes. We construct a partial isomophism
// between the graphs to figure out which pool descriptors need to be passed
// in. The roots of this mapping is found from arguments and return values.
//
DSGraph::NodeMapTy NodeMapping;
Instruction *NewCall;
Value *NewCallee;
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);
FuncInfo *CFI = getFuncInfo(CF);
if (CFI == 0 || CFI->Clone == 0) // Nothing to transform...
return;
NewCallee = CFI->Clone;
ArgNodes = CFI->ArgNodes;
assert ((DS->hasDSGraph (*CF)) && "Function has no ECGraph!\n");
CalleeGraph = DS->getDSGraph(*CF);
} else {
DEBUG(errs() << " Handling indirect call: " << *TheCall);
// 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>(FI.getOldValueIfAvailable(CS.getInstruction()));
DSCallGraph::callee_iterator I = DS->getCallGraph().callee_begin(CS);
if (I != DS->getCallGraph().callee_end(CS))
CF = *I;
// If we didn't find the callee in the constructed call graph, try
// checking in the DSNode itself.
// This isn't ideal as it means that this call site didn't have inlining
// happen.
if (!CF) {
DSGraph* dg = DS->getDSGraph(*OrigInst->getParent()->getParent());
DSNode* d = dg->getNodeForValue(OrigInst->getOperand(0)).getNode();
assert (d && "No DSNode!\n");
std::vector<const Function*> g;
d->addFullFunctionList(g);
if (g.size()) {
EquivalenceClasses< const GlobalValue *> & EC = dg->getGlobalECs();
for(std::vector<const Function*>::const_iterator ii = g.begin(), ee = g.end();
!CF && ii != ee; ++ii) {
for (EquivalenceClasses<const GlobalValue *>::member_iterator MI = EC.findLeader(*ii);
MI != EC.member_end(); ++MI) // Loop over members in this set.
if ((CF = dyn_cast<Function>(*MI))) {
break;
}
}
}
}
//
// Do an assert unless we're bugpointing something.
//
// if ((UsingBugpoint) && (!CF)) return;
if (!CF)
errs() << "No Graph for CallSite in "
<< TheCall->getParent()->getParent()->getName().str()
<< " originally "
<< OrigInst->getParent()->getParent()->getName().str()
<< "\n";
assert (CF && "No call graph info");
// Get the common graph for the set of functions this call may invoke.
// if (UsingBugpoint && (!(Graphs.hasDSGraph(*CF)))) return;
assert ((DS->hasDSGraph(*CF)) && "Function has no DSGraph!\n");
//.........这里部分代码省略.........
示例11:
DSNode * ConvertUnsafeAllocas::getDSNode(const Value *V, Function *F) {
DSGraph * TDG = budsPass->getDSGraph(*F);
DSNode *DSN = TDG->getNodeForValue((Value *)V).getNode();
return DSN;
}
示例12: assert
//
// Method: TransformCSSAllocasToMallocs()
//
// Description:
// This method is given the set of DSNodes from the stack safety pass that
// have been marked for promotion. It then finds all alloca instructions
// that have not been marked type-unknown and promotes them to heap
// allocations.
//
void
ConvertUnsafeAllocas::TransformCSSAllocasToMallocs (Module & M,
std::set<DSNode *> & cssAllocaNodes) {
for (Module::iterator FI = M.begin(); FI != M.end(); ++FI) {
//
// Skip functions that have no DSGraph. These are probably functions with
// no function body and are, hence, cannot be analyzed.
//
if (!(budsPass->hasDSGraph (*FI))) continue;
//
// Get the DSGraph for the current function.
//
DSGraph *DSG = budsPass->getDSGraph(*FI);
//
// Search for alloca instructions that need promotion and add them to the
// worklist.
//
std::vector<AllocaInst *> Worklist;
for (Function::iterator BB = FI->begin(); BB != FI->end(); ++BB) {
for (BasicBlock::iterator ii = BB->begin(); ii != BB->end(); ++ii) {
Instruction * I = ii;
if (AllocaInst * AI = dyn_cast<AllocaInst>(I)) {
//
// Get the DSNode for the allocation.
//
DSNode *DSN = DSG->getNodeForValue(AI).getNode();
assert (DSN && "No DSNode for alloca!\n");
//
// If the alloca is type-known, we do not need to promote it, so
// don't bother with it.
//
if (DSN->isNodeCompletelyFolded()) continue;
//
// Determine if the DSNode for the alloca is one of those marked as
// unsafe by the stack safety analysis pass. If not, then we do not
// need to promote it.
//
if (cssAllocaNodes.find(DSN) == cssAllocaNodes.end()) continue;
//
// If the DSNode for this alloca is already listed in the
// unsafeAllocaNode vector, remove it since we are processing it here
//
std::list<DSNode *>::iterator NodeI = find (unsafeAllocaNodes.begin(),
unsafeAllocaNodes.end(),
DSN);
if (NodeI != unsafeAllocaNodes.end()) {
unsafeAllocaNodes.erase(NodeI);
}
//
// This alloca needs to be changed to a malloc. Add it to the
// worklist.
//
Worklist.push_back (AI);
}
}
}
//
// Update the statistics.
//
if (Worklist.size())
ConvAllocas += Worklist.size();
//
// Convert everything in the worklist into a malloc instruction.
//
while (Worklist.size()) {
//
// Grab an alloca from the worklist.
//
AllocaInst * AI = Worklist.back();
Worklist.pop_back();
//
// Get the DSNode for this alloca.
//
DSNode *DSN = DSG->getNodeForValue(AI).getNode();
assert (DSN && "No DSNode for alloca!\n");
//
// Promote the alloca and remove it from the program.
//
promoteAlloca (AI, DSN);
AI->getParent()->getInstList().erase(AI);
//.........这里部分代码省略.........
示例13: processFunction
void StdLibDataStructures::processFunction(int x, Function *F) {
for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
ii != ee; ++ii)
if (CallInst* CI = dyn_cast<CallInst>(*ii)){
if (CI->getCalledValue() == F) {
DSGraph* Graph = getDSGraph(*CI->getParent()->getParent());
//
// Set the read, write, and heap markers on the return value
// as appropriate.
//
if(isa<PointerType>((CI)->getType())){
if(Graph->hasNodeForValue(CI)){
if (recFuncs[x].action.read[0])
Graph->getNodeForValue(CI).getNode()->setReadMarker();
if (recFuncs[x].action.write[0])
Graph->getNodeForValue(CI).getNode()->setModifiedMarker();
if (recFuncs[x].action.heap[0])
Graph->getNodeForValue(CI).getNode()->setHeapMarker();
}
}
//
// Set the read, write, and heap markers on the actual arguments
// as appropriate.
//
for (unsigned y = 0; y < CI->getNumArgOperands(); ++y)
if (isa<PointerType>(CI->getArgOperand(y)->getType())){
if (Graph->hasNodeForValue(CI->getArgOperand(y))){
if (recFuncs[x].action.read[y + 1])
Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker();
if (recFuncs[x].action.write[y + 1])
Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker();
if (recFuncs[x].action.heap[y + 1])
Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setHeapMarker();
}
}
//
// Merge the DSNoes for return values and parameters as
// appropriate.
//
std::vector<DSNodeHandle> toMerge;
if (recFuncs[x].action.mergeNodes[0])
if (isa<PointerType>(CI->getType()))
if (Graph->hasNodeForValue(CI))
toMerge.push_back(Graph->getNodeForValue(CI));
for (unsigned y = 0; y < CI->getNumArgOperands(); ++y)
if (recFuncs[x].action.mergeNodes[y + 1])
if (isa<PointerType>(CI->getArgOperand(y)->getType()))
if (Graph->hasNodeForValue(CI->getArgOperand(y)))
toMerge.push_back(Graph->getNodeForValue(CI->getArgOperand(y)));
for (unsigned y = 1; y < toMerge.size(); ++y)
toMerge[0].mergeWith(toMerge[y]);
//
// Collapse (fold) the DSNode of the return value and the actual
// arguments if directed to do so.
//
if (!noStdLibFold && recFuncs[x].action.collapse) {
if (isa<PointerType>(CI->getType())){
if (Graph->hasNodeForValue(CI))
Graph->getNodeForValue(CI).getNode()->foldNodeCompletely();
NumNodesFoldedInStdLib++;
}
for (unsigned y = 0; y < CI->getNumArgOperands(); ++y){
if (isa<PointerType>(CI->getArgOperand(y)->getType())){
if (Graph->hasNodeForValue(CI->getArgOperand(y))){
Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->foldNodeCompletely();
NumNodesFoldedInStdLib++;
}
}
}
}
}
} else if (InvokeInst* CI = dyn_cast<InvokeInst>(*ii)){
if (CI->getCalledValue() == F) {
DSGraph* Graph = getDSGraph(*CI->getParent()->getParent());
//
// Set the read, write, and heap markers on the return value
// as appropriate.
//
if(isa<PointerType>((CI)->getType())){
if(Graph->hasNodeForValue(CI)){
if (recFuncs[x].action.read[0])
Graph->getNodeForValue(CI).getNode()->setReadMarker();
if (recFuncs[x].action.write[0])
Graph->getNodeForValue(CI).getNode()->setModifiedMarker();
if (recFuncs[x].action.heap[0])
Graph->getNodeForValue(CI).getNode()->setHeapMarker();
}
}
//
// Set the read, write, and heap markers on the actual arguments
// as appropriate.
//
for (unsigned y = 0; y < CI->getNumArgOperands(); ++y)
if (isa<PointerType>(CI->getArgOperand(y)->getType())){
//.........这里部分代码省略.........
示例14: IV
//.........这里部分代码省略.........
DSNode *CalleeNode = const_cast<DSNode*>(MI->first);
unsigned CalleeNodeOffset = MI->second.getOffset();
while (NLVI->first == MI->second.getNode()) {
// Figure out what offset in the callee this field would land.
unsigned FieldOff = NLVI->second->getFieldOffset()+CalleeNodeOffset;
// If the field is not within the callee node, ignore it.
if (FieldOff >= CalleeNode->getSize()) {
++NLVI;
continue;
}
// Okay, check to see if we have a lattice value for the field at offset
// FieldOff in the callee node.
const LatticeValue *CalleeLV = 0;
std::multimap<DSNode*, LatticeValue*>::iterator CFI =
CalleeFacts.lower_bound(CalleeNode);
for (; CFI != CalleeFacts.end() && CFI->first == CalleeNode; ++CFI)
if (CFI->second->getFieldOffset() == FieldOff) {
CalleeLV = CFI->second; // Found it!
break;
}
// If we don't, the lattice value hit bottom and we should remove the
// lattice value in the caller.
if (!CalleeLV) {
delete NLVI->second; // The lattice value hit bottom.
NodeLVs.erase(NLVI++);
continue;
}
// Finally, if we did find a corresponding entry, merge the information
// into the caller's lattice value and keep going.
if (NLVI->second->mergeInValue(CalleeLV)) {
// Okay, merging these two caused the caller value to hit bottom.
// Remove it.
delete NLVI->second; // The lattice value hit bottom.
NodeLVs.erase(NLVI++);
}
++NLVI; // We successfully merged in some information!
}
// If we ran out of facts to prove, just exit.
if (NodeLVs.empty()) return;
}
}
// The local analysis pass inconveniently discards many local function calls
// from the graph if they are to known functions. Loop over direct function
// calls not handled above and visit them as appropriate.
while (!IV.DirectCallSites.empty()) {
Instruction *Call = *IV.DirectCallSites.begin();
IV.DirectCallSites.erase(IV.DirectCallSites.begin());
// Is this one actually handled by DSA?
if (CalleesHandled.count(cast<Function>(Call->getOperand(0))))
continue;
// Collect the pointers involved in this call.
std::vector<Value*> Pointers;
if (isa<PointerType>(Call->getType()))
Pointers.push_back(Call);
for (unsigned i = 1, e = Call->getNumOperands(); i != e; ++i)
if (isa<PointerType>(Call->getOperand(i)->getType()))
Pointers.push_back(Call->getOperand(i));
// If this is an intrinsic function call, figure out which one.
unsigned IID = cast<Function>(Call->getOperand(0))->getIntrinsicID();
for (unsigned i = 0, e = Pointers.size(); i != e; ++i) {
// If any of our lattice values are passed into this call, which is
// specially handled by the local analyzer, inform the lattice function.
DSNode *N = DSG.getNodeForValue(Pointers[i]).getNode();
for (std::multimap<DSNode*, LatticeValue*>::iterator LVI =
NodeLVs.lower_bound(N); LVI != NodeLVs.end() && LVI->first == N;) {
bool AtBottom = false;
switch (IID) {
default:
AtBottom = LVI->second->visitRecognizedCall(*Call);
break;
case Intrinsic::memset:
if (Callbacks & Visit::Stores)
AtBottom = LVI->second->visitMemSet(*cast<CallInst>(Call));
break;
}
if (AtBottom) {
delete LVI->second;
NodeLVs.erase(LVI++);
} else {
++LVI;
}
}
}
}
}
示例15: visitCallSite
//
// Method: visitCallSite()
//
// Description:
// This method transforms a call site. A call site may either be a call
// instruction or an invoke instruction.
//
// Inputs:
// CS - The call site representing the instruction that should be transformed.
//
void FuncTransform::visitCallSite(CallSite& CS) {
const Function *CF = CS.getCalledFunction();
Instruction *TheCall = CS.getInstruction();
bool thread_creation_point = false;
//
// Get the value that is called at this call site. Strip away any pointer
// casts that do not change the representation of the data (i.e., are
// lossless casts).
//
Value * CalledValue = CS.getCalledValue()->stripPointerCasts();
//
// The CallSite::getCalledFunction() method is not guaranteed to strip off
// pointer casts. If no called function was found, manually strip pointer
// casts off of the called value and see if we get a function. If so, this
// is a direct call, and we want to update CF accordingly.
//
if (!CF) CF = dyn_cast<Function>(CalledValue);
//
// Do not change any inline assembly code.
//
if (isa<InlineAsm>(TheCall->getOperand(0))) {
errs() << "INLINE ASM: ignoring. Hoping that's safe.\n";
return;
}
//
// Ignore calls to NULL pointers or undefined values.
//
if ((isa<ConstantPointerNull>(CalledValue)) ||
(isa<UndefValue>(CalledValue))) {
errs() << "WARNING: Ignoring call using NULL/Undef function pointer.\n";
return;
}
// If this function is one of the memory manipulating functions built into
// libc, emulate it with pool calls as appropriate.
if (CF && CF->isDeclaration()) {
std::string Name = CF->getName();
if (Name == "free" || Name == "cfree") {
visitFreeCall(CS);
return;
} else if (Name == "malloc") {
visitMallocCall(CS);
return;
} else if (Name == "calloc") {
visitCallocCall(CS);
return;
} else if (Name == "realloc") {
visitReallocCall(CS);
return;
} else if (Name == "memalign" || Name == "posix_memalign") {
visitMemAlignCall(CS);
return;
} else if (Name == "strdup") {
visitStrdupCall(CS);
return;
} else if (Name == "valloc") {
errs() << "VALLOC USED BUT NOT HANDLED!\n";
abort();
} else if (unsigned PoolArgc = PAInfo.getNumInitialPoolArguments(Name)) {
visitRuntimeCheck(CS, PoolArgc);
return;
} else if (Name == "pthread_create") {
thread_creation_point = true;
//
// Get DSNode representing the DSNode of the function pointer Value of
// the pthread_create call
//
DSNode* thread_callee_node = G->getNodeForValue(CS.getArgument(2)).getNode();
if (!thread_callee_node) {
assert(0 && "apparently you need this code");
FuncInfo *CFI = PAInfo.getFuncInfo(*CF);
thread_callee_node = G->getNodeForValue(CFI->MapValueToOriginal(CS.getArgument(2))).getNode();
}
// Fill in CF with the name of one of the functions in thread_callee_node
CF = const_cast<Function*>(dyn_cast<Function>(*thread_callee_node->globals_begin()));
}
}
//
// We need to figure out which local pool descriptors correspond to the pool
// descriptor arguments passed into the function call. Calculate a mapping
// from callee DSNodes to caller DSNodes. We construct a partial isomophism
// between the graphs to figure out which pool descriptors need to be passed
//.........这里部分代码省略.........