Local.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Local.h - Functions to perform local transformations -----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This family of functions perform various local transformations to the
  15. // program.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_ANALYSIS_UTILS_LOCAL_H
  19. #define LLVM_ANALYSIS_UTILS_LOCAL_H
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/IR/DataLayout.h"
  22. #include "llvm/IR/GetElementPtrTypeIterator.h"
  23. namespace llvm {
  24. /// Given a getelementptr instruction/constantexpr, emit the code necessary to
  25. /// compute the offset from the base pointer (without adding in the base
  26. /// pointer). Return the result as a signed integer of intptr size.
  27. /// When NoAssumptions is true, no assumptions about index computation not
  28. /// overflowing is made.
  29. template <typename IRBuilderTy>
  30. Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
  31. bool NoAssumptions = false) {
  32. GEPOperator *GEPOp = cast<GEPOperator>(GEP);
  33. Type *IntIdxTy = DL.getIndexType(GEP->getType());
  34. Value *Result = nullptr;
  35. // If the GEP is inbounds, we know that none of the addressing operations will
  36. // overflow in a signed sense.
  37. bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
  38. // Build a mask for high order bits.
  39. unsigned IntPtrWidth = IntIdxTy->getScalarType()->getIntegerBitWidth();
  40. uint64_t PtrSizeMask =
  41. std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth);
  42. gep_type_iterator GTI = gep_type_begin(GEP);
  43. for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
  44. ++i, ++GTI) {
  45. Value *Op = *i;
  46. uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
  47. Value *Offset;
  48. if (Constant *OpC = dyn_cast<Constant>(Op)) {
  49. if (OpC->isZeroValue())
  50. continue;
  51. // Handle a struct index, which adds its field offset to the pointer.
  52. if (StructType *STy = GTI.getStructTypeOrNull()) {
  53. uint64_t OpValue = OpC->getUniqueInteger().getZExtValue();
  54. Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
  55. if (!Size)
  56. continue;
  57. Offset = ConstantInt::get(IntIdxTy, Size);
  58. } else {
  59. // Splat the constant if needed.
  60. if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy())
  61. OpC = ConstantVector::getSplat(
  62. cast<VectorType>(IntIdxTy)->getElementCount(), OpC);
  63. Constant *Scale = ConstantInt::get(IntIdxTy, Size);
  64. Constant *OC =
  65. ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/);
  66. Offset =
  67. ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/);
  68. }
  69. } else {
  70. // Splat the index if needed.
  71. if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy())
  72. Op = Builder->CreateVectorSplat(
  73. cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op);
  74. // Convert to correct type.
  75. if (Op->getType() != IntIdxTy)
  76. Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName().str()+".c");
  77. if (Size != 1) {
  78. // We'll let instcombine(mul) convert this to a shl if possible.
  79. Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size),
  80. GEP->getName().str() + ".idx", false /*NUW*/,
  81. isInBounds /*NSW*/);
  82. }
  83. Offset = Op;
  84. }
  85. if (Result)
  86. Result = Builder->CreateAdd(Result, Offset, GEP->getName().str()+".offs",
  87. false /*NUW*/, isInBounds /*NSW*/);
  88. else
  89. Result = Offset;
  90. }
  91. return Result ? Result : Constant::getNullValue(IntIdxTy);
  92. }
  93. }
  94. #endif // LLVM_TRANSFORMS_UTILS_LOCAL_H
  95. #ifdef __GNUC__
  96. #pragma GCC diagnostic pop
  97. #endif