예제 #1
0
 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);
   }
 }
예제 #2
0
void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) {
  DSGraph* GG = G->getGlobalsGraph();
  ReachabilityCloner RC(GG, G, 0);

  for(DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end();
      ii != ee; ++ii) {
    //cerr << "Pushing " << ii->getCallSite().getInstruction()->getOperand(0) << "\n";
    //If we can, merge with an existing call site for this instruction
    if (GG->hasNodeForValue(ii->getCallSite().getInstruction()->getOperand(0))) {
      DSGraph::afc_iterator GGii;
      for(GGii = GG->afc_begin(); GGii != GG->afc_end(); ++GGii)
        if (GGii->getCallSite().getInstruction()->getOperand(0) ==
            ii->getCallSite().getInstruction()->getOperand(0))
          break;
      if (GGii != GG->afc_end())
        RC.cloneCallSite(*ii).mergeWith(*GGii);
      else
        GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
    } else {
      GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
    }
  }
}
예제 #3
0
//
// Method: CloneAuxIntoGlobal()
//
// Description:
//  This method takes the specified graph and processes each unresolved call
//  site (a call site for which all targets are not yet known). For each
//  unresolved call site, it adds it to the globals graph and merges
//  information about the call site if the globals graph already had the call
//  site in its own list of unresolved call sites.
//
void BUDataStructures::CloneAuxIntoGlobal(DSGraph* G) {
  //
  // If this DSGraph has no unresolved call sites, do nothing.  We do enough
  // work that wastes time even when the list is empty that this extra check
  // is probably worth it.
  //
  if (G->afc_begin() == G->afc_end())
    return;

  DSGraph* GG = G->getGlobalsGraph();
  ReachabilityCloner RC(GG, G, 0);

  //
  // Determine which called values are both within the local graph DSCallsites
  // and the global graph DSCallsites.  Note that we require that the global
  // graph have a DSNode for the called value.
  //
  std::map<Value *, DSCallSite *> CommonCallValues;
  for (DSGraph::afc_iterator ii = G->afc_begin(), ee = G->afc_end();
       ii != ee;
       ++ii) {
    //
    // If the globals graph has a DSNode for the LLVM value used in the local
    // unresolved call site, then it might have a DSCallSite for it, too.
    // Record this call site as a potential call site that will need to be
    // merged.
    //
    // Otherwise, just add the call site to the globals graph.
    //
    Value * V = ii->getCallSite().getCalledValue();
    if (GG->hasNodeForValue(V)) {
      DSCallSite & DS = *ii;
      CommonCallValues[V] = &DS;
    } else {
      GG->addAuxFunctionCall(RC.cloneCallSite(*ii));
    }
  }

  //
  // Scan through all the unresolved call sites in the globals graph and see if
  // the local graph has a call using the same LLVM value.  If so, merge the
  // call sites.
  //
  DSGraph::afc_iterator GGii = GG->afc_begin();
  for (; GGii != GG->afc_end(); ++GGii) {
    //
    // Determine if this unresolved call site is also in the local graph.
    // If so, then merge it.
    //
    Value * CalledValue = GGii->getCallSite().getCalledValue();
    std::map<Value *, DSCallSite *>::iterator v;
    v = CommonCallValues.find (CalledValue);
    if (v != CommonCallValues.end()) {
      //
      // Merge the unresolved call site into the globals graph.
      //
      RC.cloneCallSite(*(v->second)).mergeWith(*GGii);

      //
      // Mark that this call site was merged by removing the called LLVM value
      // from the set of values common to both the local and global DSGraphs.
      //
      CommonCallValues.erase (v);
    }
  }

  //
  // We've now merged all DSCallSites that were known both to the local graph
  // and the globals graph.  Now, there are still some local call sites that
  // need to be *added* to the globals graph; they are in DSCallSites remaining
  // in CommonCallValues.
  //
  std::map<Value *, DSCallSite *>::iterator v = CommonCallValues.begin ();
  for (; v != CommonCallValues.end(); ++v) {
    GG->addAuxFunctionCall(RC.cloneCallSite(*(v->second)));
  }

  return;
}
예제 #4
0
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())){
            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(ConstantExpr *CE = dyn_cast<ConstantExpr>(*ii)) {
      if(CE->isCast()) 
        for (Value::use_iterator ci = CE->use_begin(), ce = CE->use_end();
             ci != ce; ++ci) {

          if (CallInst* CI = dyn_cast<CallInst>(*ci)){
            if (CI->getCalledValue() == CE) {
              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 (recFuncs[x].action.read[y + 1]){
                  if (isa<PointerType>(CI->getArgOperand(y)->getType())){
                    if (Graph->hasNodeForValue(CI->getArgOperand(y)))
                      Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setReadMarker();
                    if (Graph->hasNodeForValue(CI->getArgOperand(y)))
                      Graph->getNodeForValue(CI->getArgOperand(y)).getNode()->setModifiedMarker();
                    if (Graph->hasNodeForValue(CI->getArgOperand(y)))
                      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))){
                      DSNode * Node=Graph->getNodeForValue(CI->getArgOperand(y)).getNode();
                      Node->foldNodeCompletely();
                      NumNodesFoldedInStdLib++;
                    }
                  }
              }
            }
          }
        }
    }

  //
  // Pretend that this call site does not call this function anymore.
  //
  eraseCallsTo(F);
}