|
14 | 14 | #ifndef LLVM_ANALYSIS_UTILS_LOCAL_H
|
15 | 15 | #define LLVM_ANALYSIS_UTILS_LOCAL_H
|
16 | 16 |
|
17 |
| -#include "llvm/ADT/StringRef.h" |
18 |
| -#include "llvm/IR/DataLayout.h" |
19 |
| -#include "llvm/IR/GetElementPtrTypeIterator.h" |
20 |
| - |
21 | 17 | namespace llvm {
|
22 | 18 |
|
| 19 | +class DataLayout; |
| 20 | +class IRBuilderBase; |
| 21 | +class User; |
| 22 | +class Value; |
| 23 | + |
23 | 24 | /// Given a getelementptr instruction/constantexpr, emit the code necessary to
|
24 | 25 | /// compute the offset from the base pointer (without adding in the base
|
25 | 26 | /// pointer). Return the result as a signed integer of intptr size.
|
26 | 27 | /// When NoAssumptions is true, no assumptions about index computation not
|
27 | 28 | /// overflowing is made.
|
28 |
| -template <typename IRBuilderTy> |
29 |
| -Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP, |
30 |
| - bool NoAssumptions = false) { |
31 |
| - GEPOperator *GEPOp = cast<GEPOperator>(GEP); |
32 |
| - Type *IntIdxTy = DL.getIndexType(GEP->getType()); |
33 |
| - Value *Result = nullptr; |
34 |
| - |
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 |
| - |
39 |
| - // Build a mask for high order bits. |
40 |
| - unsigned IntPtrWidth = IntIdxTy->getScalarType()->getIntegerBitWidth(); |
41 |
| - uint64_t PtrSizeMask = |
42 |
| - std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth); |
43 |
| - |
44 |
| - gep_type_iterator GTI = gep_type_begin(GEP); |
45 |
| - for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; |
46 |
| - ++i, ++GTI) { |
47 |
| - Value *Op = *i; |
48 |
| - uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; |
49 |
| - Value *Offset; |
50 |
| - if (Constant *OpC = dyn_cast<Constant>(Op)) { |
51 |
| - if (OpC->isZeroValue()) |
52 |
| - continue; |
53 |
| - |
54 |
| - // Handle a struct index, which adds its field offset to the pointer. |
55 |
| - if (StructType *STy = GTI.getStructTypeOrNull()) { |
56 |
| - uint64_t OpValue = OpC->getUniqueInteger().getZExtValue(); |
57 |
| - Size = DL.getStructLayout(STy)->getElementOffset(OpValue); |
58 |
| - if (!Size) |
59 |
| - continue; |
60 |
| - |
61 |
| - Offset = ConstantInt::get(IntIdxTy, Size); |
62 |
| - } else { |
63 |
| - // Splat the constant if needed. |
64 |
| - if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy()) |
65 |
| - OpC = ConstantVector::getSplat( |
66 |
| - cast<VectorType>(IntIdxTy)->getElementCount(), OpC); |
67 |
| - |
68 |
| - Constant *Scale = ConstantInt::get(IntIdxTy, Size); |
69 |
| - Constant *OC = |
70 |
| - ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/); |
71 |
| - Offset = |
72 |
| - ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/); |
73 |
| - } |
74 |
| - } else { |
75 |
| - // Splat the index if needed. |
76 |
| - if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy()) |
77 |
| - Op = Builder->CreateVectorSplat( |
78 |
| - cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op); |
79 |
| - |
80 |
| - // Convert to correct type. |
81 |
| - if (Op->getType() != IntIdxTy) |
82 |
| - Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName().str()+".c"); |
83 |
| - if (Size != 1) { |
84 |
| - // We'll let instcombine(mul) convert this to a shl if possible. |
85 |
| - Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size), |
86 |
| - GEP->getName().str() + ".idx", false /*NUW*/, |
87 |
| - isInBounds /*NSW*/); |
88 |
| - } |
89 |
| - Offset = Op; |
90 |
| - } |
91 |
| - |
92 |
| - if (Result) |
93 |
| - Result = Builder->CreateAdd(Result, Offset, GEP->getName().str()+".offs", |
94 |
| - false /*NUW*/, isInBounds /*NSW*/); |
95 |
| - else |
96 |
| - Result = Offset; |
97 |
| - } |
98 |
| - return Result ? Result : Constant::getNullValue(IntIdxTy); |
99 |
| -} |
| 29 | +Value *emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP, |
| 30 | + bool NoAssumptions = false); |
100 | 31 |
|
101 |
| -} |
| 32 | +} // namespace llvm |
102 | 33 |
|
103 | 34 | #endif // LLVM_ANALYSIS_UTILS_LOCAL_H
|
0 commit comments