Beispiel #1
0
void GraphBuilder::visitInsertValueInst(InsertValueInst& I) {
  setDestTo(I, createNode()->setAllocaMarker());

  Type *StoredTy = I.getInsertedValueOperand()->getType();
  DSNodeHandle Dest = getValueDest(&I);
  Dest.mergeWith(getValueDest(I.getAggregateOperand()));

  // Mark that the node is written to...
  Dest.getNode()->setModifiedMarker();
  unsigned Offset = 0;
  Type* STy = I.getAggregateOperand()->getType();
  llvm::InsertValueInst::idx_iterator i = I.idx_begin(), e = I.idx_end(); 
  for (; i != e; i++) {
    const StructLayout *SL = TD.getStructLayout(cast<StructType>(STy));
    Offset += SL->getElementOffset(*i);
    STy = (cast<StructType>(STy))->getTypeAtIndex(*i);
  }

  // Ensure a type-record exists...
  Dest.getNode()->mergeTypeInfo(StoredTy, Offset); 

  // Avoid adding edges from null, or processing non-"pointer" stores
  if (isa<PointerType>(StoredTy))
    Dest.addEdgeTo(getValueDest(I.getInsertedValueOperand()));
}
Beispiel #2
0
void GraphBuilder::visitStoreInst(StoreInst &SI) {
  Type *StoredTy = SI.getOperand(0)->getType();
  DSNodeHandle Dest = getValueDest(SI.getOperand(1));
  if (Dest.isNull()) return;

  // Mark that the node is written to...
  Dest.getNode()->setModifiedMarker();

  // Ensure a type-record exists...
  Dest.getNode()->growSizeForType(StoredTy, Dest.getOffset());

  // Avoid adding edges from null, or processing non-"pointer" stores
  if (isa<PointerType>(StoredTy))
    Dest.addEdgeTo(getValueDest(SI.getOperand(0)));

  if(TypeInferenceOptimize)
    if(SI.getOperand(0)->hasOneUse())
      if(isa<LoadInst>(SI.getOperand(0))){
        ++NumIgnoredInst;
        return;
      }
  Dest.getNode()->mergeTypeInfo(StoredTy, Dest.getOffset());
}
Beispiel #3
0
//
// Function: MergeConstantInitIntoNode()
//
// Description:
//  Merge the specified constant into the specified DSNode.
//
void
GraphBuilder::MergeConstantInitIntoNode(DSNodeHandle &NH,
                                        Type* Ty,
                                        Constant *C) {
  //
  // Ensure a type-record exists...
  //
  DSNode *NHN = NH.getNode();
  //NHN->mergeTypeInfo(Ty, NH.getOffset());

  //
  // If we've found something of pointer type, create or find its DSNode and
  // make a link from the specified DSNode to the new DSNode describing the
  // pointer we've just found.
  //
  if (isa<PointerType>(Ty)) {
    NHN->mergeTypeInfo(Ty, NH.getOffset());
    NH.addEdgeTo(getValueDest(C));
    return;
  }

  //
  // If the type of the object (array element, structure field, etc.) is an
  // integer or floating point type, then just ignore it.  It has no DSNode.
  //
  if (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy()) return;

  //
  // Handle aggregate constants.
  //
  if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
    //
    // For an array, we don't worry about different elements pointing to
    // different objects; we essentially pretend that all array elements alias.
    //
    Type * ElementType = cast<ArrayType>(Ty)->getElementType();
    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
      Constant * ConstElement = cast<Constant>(CA->getOperand(i));
      MergeConstantInitIntoNode(NH, ElementType, ConstElement);
    }
  } else if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
    //
    // For a structure, we need to merge each element of the constant structure
    // into the specified DSNode.  However, we must also handle structures that
    // end with a zero-length array ([0 x sbyte]); this is a common C idiom
    // that continues to plague the world.
    //
    //NHN->mergeTypeInfo(Ty, NH.getOffset());

    const StructLayout *SL = TD.getStructLayout(cast<StructType>(Ty));

    for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
      DSNode *NHN = NH.getNode();
      if (SL->getElementOffset(i) < SL->getSizeInBytes()) {
        //
        // Get the type and constant value of this particular element of the
        // constant structure.
        //
        Type * ElementType = cast<StructType>(Ty)->getElementType(i);
        Constant * ConstElement = cast<Constant>(CS->getOperand(i));

        //
        // Get the offset (in bytes) into the memory object that we're
        // analyzing.
        //
        unsigned offset = NH.getOffset()+(unsigned)SL->getElementOffset(i);
        NHN->mergeTypeInfo(ElementType, offset);
        //
        // Create a new DSNodeHandle.  This DSNodeHandle will point to the same
        // DSNode as the one we're constructing for our caller; however, it
        // will point into a different offset into that DSNode.
        //
        DSNodeHandle NewNH (NHN, offset);
        assert ((NHN->isNodeCompletelyFolded() || (NewNH.getOffset() == offset))
                && "Need to resize DSNode!");

        //
        // Recursively merge in this element of the constant struture into the
        // DSNode.
        //
        MergeConstantInitIntoNode(NewNH, ElementType, ConstElement);
      } else if (SL->getElementOffset(i) == SL->getSizeInBytes()) {
        //
        // If this is one of those cute structures that ends with a zero-length
        // array, just fold the DSNode now and get it over with.
        //
        DEBUG(errs() << "Zero size element at end of struct\n" );
        NHN->foldNodeCompletely();
      } else {
        assert(0 && "type was smaller than offsets of struct layout indicate");
      }
    }
  } else if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) {
    //
    // Undefined values and NULL pointers have no DSNodes, so they do nothing.
    //
  } else {
    assert(0 && "Unknown constant type!");
  }
}