LLVM API Documentation
00001 //===- TransformInternals.cpp - Implement shared functions for transforms -===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines shared functions used by the different components of the 00011 // Transforms library. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "TransformInternals.h" 00016 #include "llvm/Type.h" 00017 #include "llvm/Analysis/Expressions.h" 00018 #include "llvm/Function.h" 00019 #include "llvm/Instructions.h" 00020 using namespace llvm; 00021 00022 static const Type *getStructOffsetStep(const StructType *STy, uint64_t &Offset, 00023 std::vector<Value*> &Indices, 00024 const TargetData &TD) { 00025 assert(Offset < TD.getTypeSize(STy) && "Offset not in composite!"); 00026 const StructLayout *SL = TD.getStructLayout(STy); 00027 00028 // This loop terminates always on a 0 <= i < MemberOffsets.size() 00029 unsigned i; 00030 for (i = 0; i < SL->MemberOffsets.size()-1; ++i) 00031 if (Offset >= SL->MemberOffsets[i] && Offset < SL->MemberOffsets[i+1]) 00032 break; 00033 00034 assert(Offset >= SL->MemberOffsets[i] && 00035 (i == SL->MemberOffsets.size()-1 || Offset < SL->MemberOffsets[i+1])); 00036 00037 // Make sure to save the current index... 00038 Indices.push_back(ConstantUInt::get(Type::UIntTy, i)); 00039 Offset = SL->MemberOffsets[i]; 00040 return STy->getContainedType(i); 00041 } 00042 00043 00044 // getStructOffsetType - Return a vector of offsets that are to be used to index 00045 // into the specified struct type to get as close as possible to index as we 00046 // can. Note that it is possible that we cannot get exactly to Offset, in which 00047 // case we update offset to be the offset we actually obtained. The resultant 00048 // leaf type is returned. 00049 // 00050 // If StopEarly is set to true (the default), the first object with the 00051 // specified type is returned, even if it is a struct type itself. In this 00052 // case, this routine will not drill down to the leaf type. Set StopEarly to 00053 // false if you want a leaf 00054 // 00055 const Type *llvm::getStructOffsetType(const Type *Ty, unsigned &Offset, 00056 std::vector<Value*> &Indices, 00057 const TargetData &TD, bool StopEarly) { 00058 if (Offset == 0 && StopEarly && !Indices.empty()) 00059 return Ty; // Return the leaf type 00060 00061 uint64_t ThisOffset; 00062 const Type *NextType; 00063 if (const StructType *STy = dyn_cast<StructType>(Ty)) { 00064 if (STy->getNumElements()) { 00065 Offset = 0; 00066 return STy; 00067 } 00068 00069 ThisOffset = Offset; 00070 NextType = getStructOffsetStep(STy, ThisOffset, Indices, TD); 00071 } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { 00072 assert(Offset == 0 || Offset < TD.getTypeSize(ATy) && 00073 "Offset not in composite!"); 00074 00075 NextType = ATy->getElementType(); 00076 unsigned ChildSize = TD.getTypeSize(NextType); 00077 if (ConstantSInt::isValueValidForType(Type::IntTy, Offset/ChildSize)) 00078 Indices.push_back(ConstantSInt::get(Type::IntTy, Offset/ChildSize)); 00079 else 00080 Indices.push_back(ConstantSInt::get(Type::LongTy, Offset/ChildSize)); 00081 ThisOffset = (Offset/ChildSize)*ChildSize; 00082 } else { 00083 Offset = 0; // Return the offset that we were able to achieve 00084 return Ty; // Return the leaf type 00085 } 00086 00087 unsigned SubOffs = Offset - ThisOffset; 00088 const Type *LeafTy = getStructOffsetType(NextType, SubOffs, 00089 Indices, TD, StopEarly); 00090 Offset = ThisOffset + SubOffs; 00091 return LeafTy; 00092 } 00093 00094 // ConvertibleToGEP - This function returns true if the specified value V is 00095 // a valid index into a pointer of type Ty. If it is valid, Idx is filled in 00096 // with the values that would be appropriate to make this a getelementptr 00097 // instruction. The type returned is the root type that the GEP would point to 00098 // 00099 const Type *llvm::ConvertibleToGEP(const Type *Ty, Value *OffsetVal, 00100 std::vector<Value*> &Indices, 00101 const TargetData &TD, 00102 BasicBlock::iterator *BI) { 00103 return 0; 00104 } 00105