LCOV - code coverage report
Current view: top level - include/llvm/Analysis/Utils - Local.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 32 32 100.0 %
Date: 2018-10-20 13:21:21 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- Local.h - Functions to perform local transformations -----*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This family of functions perform various local transformations to the
      11             : // program.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_ANALYSIS_UTILS_LOCAL_H
      16             : #define LLVM_ANALYSIS_UTILS_LOCAL_H
      17             : 
      18             : #include "llvm/IR/DataLayout.h"
      19             : #include "llvm/IR/GetElementPtrTypeIterator.h"
      20             : 
      21             : namespace llvm {
      22             : 
      23             : /// Given a getelementptr instruction/constantexpr, emit the code necessary to
      24             : /// compute the offset from the base pointer (without adding in the base
      25             : /// pointer). Return the result as a signed integer of intptr size.
      26             : /// When NoAssumptions is true, no assumptions about index computation not
      27             : /// overflowing is made.
      28             : template <typename IRBuilderTy>
      29         181 : Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
      30             :                      bool NoAssumptions = false) {
      31             :   GEPOperator *GEPOp = cast<GEPOperator>(GEP);
      32         181 :   Type *IntPtrTy = DL.getIntPtrType(GEP->getType());
      33         181 :   Value *Result = Constant::getNullValue(IntPtrTy);
      34             : 
      35             :   // If the GEP is inbounds, we know that none of the addressing operations will
      36             :   // overflow in an unsigned sense.
      37         181 :   bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
      38             : 
      39             :   // Build a mask for high order bits.
      40             :   unsigned IntPtrWidth = IntPtrTy->getScalarType()->getIntegerBitWidth();
      41         181 :   uint64_t PtrSizeMask =
      42         181 :       std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth);
      43             : 
      44         181 :   gep_type_iterator GTI = gep_type_begin(GEP);
      45         427 :   for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
      46         246 :        ++i, ++GTI) {
      47         246 :     Value *Op = *i;
      48         246 :     uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
      49             :     if (Constant *OpC = dyn_cast<Constant>(Op)) {
      50          81 :       if (OpC->isZeroValue())
      51             :         continue;
      52             : 
      53             :       // Handle a struct index, which adds its field offset to the pointer.
      54           3 :       if (StructType *STy = GTI.getStructTypeOrNull()) {
      55           6 :         if (OpC->getType()->isVectorTy())
      56           3 :           OpC = OpC->getSplatValue();
      57             : 
      58             :         uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue();
      59           3 :         Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
      60             : 
      61           3 :         if (Size)
      62           3 :           Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
      63           6 :                                       GEP->getName()+".offs");
      64           3 :         continue;
      65             :       }
      66             : 
      67          20 :       Constant *Scale = ConstantInt::get(IntPtrTy, Size);
      68          20 :       Constant *OC = ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
      69          20 :       Scale = ConstantExpr::getMul(OC, Scale, isInBounds/*NUW*/);
      70             :       // Emit an add instruction.
      71          20 :       Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs");
      72          20 :       continue;
      73             :     }
      74             :     // Convert to correct type.
      75         165 :     if (Op->getType() != IntPtrTy)
      76           3 :       Op = Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c");
      77         165 :     if (Size != 1) {
      78             :       // We'll let instcombine(mul) convert this to a shl if possible.
      79          66 :       Op = Builder->CreateMul(Op, ConstantInt::get(IntPtrTy, Size),
      80         132 :                               GEP->getName()+".idx", isInBounds /*NUW*/);
      81             :     }
      82             : 
      83             :     // Emit an add instruction.
      84         165 :     Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs");
      85             :   }
      86         181 :   return Result;
      87             : }
      88             : 
      89             : }
      90             : 
      91             : #endif // LLVM_TRANSFORMS_UTILS_LOCAL_H

Generated by: LCOV version 1.13