TransformInternals.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. //===- TransformInternals.cpp - Implement shared functions for transforms -===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file was developed by the LLVM research group and is distributed under
  6. // the University of Illinois Open Source License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines shared functions used by the different components of the
  11. // Transforms library.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "TransformInternals.h"
  15. #include "llvm/Type.h"
  16. #include "llvm/Analysis/Expressions.h"
  17. #include "llvm/Function.h"
  18. #include "llvm/iOther.h"
  19. using namespace llvm;
  20. static const Type *getStructOffsetStep(const StructType *STy, uint64_t &Offset,
  21. std::vector<Value*> &Indices,
  22. const TargetData &TD) {
  23. assert(Offset < TD.getTypeSize(STy) && "Offset not in composite!");
  24. const StructLayout *SL = TD.getStructLayout(STy);
  25. // This loop terminates always on a 0 <= i < MemberOffsets.size()
  26. unsigned i;
  27. for (i = 0; i < SL->MemberOffsets.size()-1; ++i)
  28. if (Offset >= SL->MemberOffsets[i] && Offset < SL->MemberOffsets[i+1])
  29. break;
  30. assert(Offset >= SL->MemberOffsets[i] &&
  31. (i == SL->MemberOffsets.size()-1 || Offset < SL->MemberOffsets[i+1]));
  32. // Make sure to save the current index...
  33. Indices.push_back(ConstantUInt::get(Type::UIntTy, i));
  34. Offset = SL->MemberOffsets[i];
  35. return STy->getContainedType(i);
  36. }
  37. // getStructOffsetType - Return a vector of offsets that are to be used to index
  38. // into the specified struct type to get as close as possible to index as we
  39. // can. Note that it is possible that we cannot get exactly to Offset, in which
  40. // case we update offset to be the offset we actually obtained. The resultant
  41. // leaf type is returned.
  42. //
  43. // If StopEarly is set to true (the default), the first object with the
  44. // specified type is returned, even if it is a struct type itself. In this
  45. // case, this routine will not drill down to the leaf type. Set StopEarly to
  46. // false if you want a leaf
  47. //
  48. const Type *llvm::getStructOffsetType(const Type *Ty, unsigned &Offset,
  49. std::vector<Value*> &Indices,
  50. const TargetData &TD, bool StopEarly) {
  51. if (Offset == 0 && StopEarly && !Indices.empty())
  52. return Ty; // Return the leaf type
  53. uint64_t ThisOffset;
  54. const Type *NextType;
  55. if (const StructType *STy = dyn_cast<StructType>(Ty)) {
  56. if (STy->getNumElements()) {
  57. Offset = 0;
  58. return STy;
  59. }
  60. ThisOffset = Offset;
  61. NextType = getStructOffsetStep(STy, ThisOffset, Indices, TD);
  62. } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
  63. assert(Offset == 0 || Offset < TD.getTypeSize(ATy) &&
  64. "Offset not in composite!");
  65. NextType = ATy->getElementType();
  66. unsigned ChildSize = TD.getTypeSize(NextType);
  67. if (ConstantSInt::isValueValidForType(Type::IntTy, Offset/ChildSize))
  68. Indices.push_back(ConstantSInt::get(Type::IntTy, Offset/ChildSize));
  69. else
  70. Indices.push_back(ConstantSInt::get(Type::LongTy, Offset/ChildSize));
  71. ThisOffset = (Offset/ChildSize)*ChildSize;
  72. } else {
  73. Offset = 0; // Return the offset that we were able to achieve
  74. return Ty; // Return the leaf type
  75. }
  76. unsigned SubOffs = Offset - ThisOffset;
  77. const Type *LeafTy = getStructOffsetType(NextType, SubOffs,
  78. Indices, TD, StopEarly);
  79. Offset = ThisOffset + SubOffs;
  80. return LeafTy;
  81. }
  82. // ConvertibleToGEP - This function returns true if the specified value V is
  83. // a valid index into a pointer of type Ty. If it is valid, Idx is filled in
  84. // with the values that would be appropriate to make this a getelementptr
  85. // instruction. The type returned is the root type that the GEP would point to
  86. //
  87. const Type *llvm::ConvertibleToGEP(const Type *Ty, Value *OffsetVal,
  88. std::vector<Value*> &Indices,
  89. const TargetData &TD,
  90. BasicBlock::iterator *BI) {
  91. return 0;
  92. }