1 //===- Local.cpp - Functions to perform local transformations -------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This family of functions perform various local transformations to the 10 // program. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Analysis/Utils/Local.h" 15 #include "llvm/ADT/Twine.h" 16 #include "llvm/IR/DataLayout.h" 17 #include "llvm/IR/GetElementPtrTypeIterator.h" 18 #include "llvm/IR/IRBuilder.h" 19 20 using namespace llvm; 21 22 Value *llvm::emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, 23 User *GEP, bool NoAssumptions) { 24 GEPOperator *GEPOp = cast<GEPOperator>(GEP); 25 Type *IntIdxTy = DL.getIndexType(GEP->getType()); 26 Value *Result = nullptr; 27 28 // If the GEP is inbounds, we know that none of the addressing operations will 29 // overflow in a signed sense. 30 bool isInBounds = GEPOp->isInBounds() && !NoAssumptions; 31 32 // Build a mask for high order bits. 33 unsigned IntPtrWidth = IntIdxTy->getScalarType()->getIntegerBitWidth(); 34 uint64_t PtrSizeMask = 35 std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth); 36 37 gep_type_iterator GTI = gep_type_begin(GEP); 38 for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; 39 ++i, ++GTI) { 40 Value *Op = *i; 41 uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask; 42 Value *Offset; 43 if (Constant *OpC = dyn_cast<Constant>(Op)) { 44 if (OpC->isZeroValue()) 45 continue; 46 47 // Handle a struct index, which adds its field offset to the pointer. 48 if (StructType *STy = GTI.getStructTypeOrNull()) { 49 uint64_t OpValue = OpC->getUniqueInteger().getZExtValue(); 50 Size = DL.getStructLayout(STy)->getElementOffset(OpValue); 51 if (!Size) 52 continue; 53 54 Offset = ConstantInt::get(IntIdxTy, Size); 55 } else { 56 // Splat the constant if needed. 57 if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy()) 58 OpC = ConstantVector::getSplat( 59 cast<VectorType>(IntIdxTy)->getElementCount(), OpC); 60 61 Constant *Scale = ConstantInt::get(IntIdxTy, Size); 62 Constant *OC = 63 ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/); 64 Offset = 65 ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/); 66 } 67 } else { 68 // Splat the index if needed. 69 if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy()) 70 Op = Builder->CreateVectorSplat( 71 cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op); 72 73 // Convert to correct type. 74 if (Op->getType() != IntIdxTy) 75 Op = Builder->CreateIntCast(Op, IntIdxTy, 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(IntIdxTy, Size), 79 GEP->getName() + ".idx", false /*NUW*/, 80 isInBounds /*NSW*/); 81 } 82 Offset = Op; 83 } 84 85 if (Result) 86 Result = Builder->CreateAdd(Result, Offset, GEP->getName() + ".offs", 87 false /*NUW*/, isInBounds /*NSW*/); 88 else 89 Result = Offset; 90 } 91 return Result ? Result : Constant::getNullValue(IntIdxTy); 92 } 93