blob: acbdf5dca32c79eed2ba4364247f0b8fdc8145a2 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- Local.h - Functions to perform local transformations -----*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This family of functions perform various local transformations to the
10// program.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_UTILS_LOCAL_H
15#define LLVM_ANALYSIS_UTILS_LOCAL_H
16
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010017#include "llvm/IR/DataLayout.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010018#include "llvm/IR/GetElementPtrTypeIterator.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010019
20namespace llvm {
21
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022/// 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.
27template <typename IRBuilderTy>
28Value *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);
33
34 // If the GEP is inbounds, we know that none of the addressing operations will
35 // overflow in an unsigned sense.
36 bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
37
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);
42
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;
45 ++i, ++GTI) {
46 Value *Op = *i;
47 uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
48 if (Constant *OpC = dyn_cast<Constant>(Op)) {
49 if (OpC->isZeroValue())
50 continue;
51
52 // Handle a struct index, which adds its field offset to the pointer.
53 if (StructType *STy = GTI.getStructTypeOrNull()) {
54 if (OpC->getType()->isVectorTy())
55 OpC = OpC->getSplatValue();
56
57 uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue();
58 Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
59
60 if (Size)
61 Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
62 GEP->getName()+".offs");
63 continue;
64 }
65
66 Constant *Scale = ConstantInt::get(IntPtrTy, Size);
67 Constant *OC = ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
68 Scale = ConstantExpr::getMul(OC, Scale, isInBounds/*NUW*/);
69 // Emit an add instruction.
70 Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs");
71 continue;
72 }
73 // Convert to correct type.
74 if (Op->getType() != IntPtrTy)
75 Op = Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c");
76 if (Size != 1) {
77 // We'll let instcombine(mul) convert this to a shl if possible.
78 Op = Builder->CreateMul(Op, ConstantInt::get(IntPtrTy, Size),
79 GEP->getName()+".idx", isInBounds /*NUW*/);
80 }
81
82 // Emit an add instruction.
83 Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs");
84 }
85 return Result;
86}
87
Andrew Scullcdfcccc2018-10-05 20:58:37 +010088}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010089
90#endif // LLVM_TRANSFORMS_UTILS_LOCAL_H