1 //===- Local.h - Functions to perform local transformations -----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This family of functions perform various local transformations to the
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_ANALYSIS_UTILS_LOCAL_H
15 #define LLVM_ANALYSIS_UTILS_LOCAL_H
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/GetElementPtrTypeIterator.h"
22 /// Given a getelementptr instruction/constantexpr, emit the code necessary to
23 /// compute the offset from the base pointer (without adding in the base
24 /// pointer). Return the result as a signed integer of intptr size.
25 /// When NoAssumptions is true, no assumptions about index computation not
26 /// overflowing is made.
27 template <typename IRBuilderTy
>
28 Value
*EmitGEPOffset(IRBuilderTy
*Builder
, const DataLayout
&DL
, User
*GEP
,
29 bool NoAssumptions
= false) {
30 GEPOperator
*GEPOp
= cast
<GEPOperator
>(GEP
);
31 Type
*IntPtrTy
= DL
.getIntPtrType(GEP
->getType());
32 Value
*Result
= Constant::getNullValue(IntPtrTy
);
34 // If the GEP is inbounds, we know that none of the addressing operations will
35 // overflow in a signed sense.
36 bool isInBounds
= GEPOp
->isInBounds() && !NoAssumptions
;
38 // Build a mask for high order bits.
39 unsigned IntPtrWidth
= IntPtrTy
->getScalarType()->getIntegerBitWidth();
40 uint64_t PtrSizeMask
=
41 std::numeric_limits
<uint64_t>::max() >> (64 - IntPtrWidth
);
43 gep_type_iterator GTI
= gep_type_begin(GEP
);
44 for (User::op_iterator i
= GEP
->op_begin() + 1, e
= GEP
->op_end(); i
!= e
;
47 uint64_t Size
= DL
.getTypeAllocSize(GTI
.getIndexedType()) & PtrSizeMask
;
48 if (Constant
*OpC
= dyn_cast
<Constant
>(Op
)) {
49 if (OpC
->isZeroValue())
52 // Handle a struct index, which adds its field offset to the pointer.
53 if (StructType
*STy
= GTI
.getStructTypeOrNull()) {
54 uint64_t OpValue
= OpC
->getUniqueInteger().getZExtValue();
55 Size
= DL
.getStructLayout(STy
)->getElementOffset(OpValue
);
58 Result
= Builder
->CreateAdd(Result
, ConstantInt::get(IntPtrTy
, Size
),
59 GEP
->getName()+".offs");
63 // Splat the constant if needed.
64 if (IntPtrTy
->isVectorTy() && !OpC
->getType()->isVectorTy())
65 OpC
= ConstantVector::getSplat(IntPtrTy
->getVectorNumElements(), OpC
);
67 Constant
*Scale
= ConstantInt::get(IntPtrTy
, Size
);
68 Constant
*OC
= ConstantExpr::getIntegerCast(OpC
, IntPtrTy
, true /*SExt*/);
70 ConstantExpr::getMul(OC
, Scale
, false /*NUW*/, isInBounds
/*NSW*/);
71 // Emit an add instruction.
72 Result
= Builder
->CreateAdd(Result
, Scale
, GEP
->getName()+".offs");
76 // Splat the index if needed.
77 if (IntPtrTy
->isVectorTy() && !Op
->getType()->isVectorTy())
78 Op
= Builder
->CreateVectorSplat(IntPtrTy
->getVectorNumElements(), Op
);
80 // Convert to correct type.
81 if (Op
->getType() != IntPtrTy
)
82 Op
= Builder
->CreateIntCast(Op
, IntPtrTy
, true, Op
->getName()+".c");
84 // We'll let instcombine(mul) convert this to a shl if possible.
85 Op
= Builder
->CreateMul(Op
, ConstantInt::get(IntPtrTy
, Size
),
86 GEP
->getName() + ".idx", false /*NUW*/,
90 // Emit an add instruction.
91 Result
= Builder
->CreateAdd(Op
, Result
, GEP
->getName()+".offs");
98 #endif // LLVM_TRANSFORMS_UTILS_LOCAL_H