void GraphBuilder::visitVAArgInst(VAArgInst &I) { Module *M = FB->getParent(); Triple TargetTriple(M->getTargetTriple()); Triple::ArchType Arch = TargetTriple.getArch(); switch(Arch) { case Triple::x86_64: { // On x86_64, we have va_list as a struct {i32, i32, i8*, i8* } // The first i8* is where arguments generally go, but the second i8* can // be used also to pass arguments by register. // We model this by having both the i8*'s point to an array of pointers // to the arguments. DSNodeHandle Ptr = G.getVANodeFor(*FB); DSNodeHandle Dest = getValueDest(&I); if (Ptr.isNull()) return; // Make that the node is read and written Ptr.getNode()->setReadMarker()->setModifiedMarker(); // Not updating type info, as it is already a collapsed node if (isa<PointerType>(I.getType())) Dest.mergeWith(Ptr); return; } default: { assert(0 && "What frontend generates this?"); DSNodeHandle Ptr = getValueDest(I.getOperand(0)); //FIXME: also updates the argument if (Ptr.isNull()) return; // Make that the node is read and written Ptr.getNode()->setReadMarker()->setModifiedMarker(); // Ensure a type record exists. DSNode *PtrN = Ptr.getNode(); PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset()); if (isa<PointerType>(I.getType())) setDestTo(I, getLink(Ptr)); } } }
// // 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!"); } }