LCOV - code coverage report
Current view: top level - lib/CodeGen/SelectionDAG - SelectionDAGAddressAnalysis.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 45 45 100.0 %
Date: 2017-09-14 15:23:50 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- llvm/CodeGen/SelectionDAGAddressAnalysis.cpp ------- DAG Address
       2             : //Analysis ---*- C++ -*-===//
       3             : //
       4             : //                     The LLVM Compiler Infrastructure
       5             : //
       6             : // This file is distributed under the University of Illinois Open Source
       7             : // License. See LICENSE.TXT for details.
       8             : //
       9             : //===----------------------------------------------------------------------===//
      10             : //
      11             : 
      12             : #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h"
      13             : #include "llvm/CodeGen/ISDOpcodes.h"
      14             : #include "llvm/CodeGen/MachineFrameInfo.h"
      15             : #include "llvm/CodeGen/SelectionDAG.h"
      16             : #include "llvm/CodeGen/SelectionDAGNodes.h"
      17             : #include "llvm/Target/TargetLowering.h"
      18             : 
      19             : namespace llvm {
      20             : 
      21     7897372 : bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other,
      22             :                                      const SelectionDAG &DAG, int64_t &Off) {
      23             :   // Initial Offset difference.
      24     7897372 :   Off = Other.Offset - Offset;
      25             : 
      26    14359516 :   if ((Other.Index == Index) && (Other.IsIndexSignExt == IsIndexSignExt)) {
      27             :     // Trivial match.
      28     9410272 :     if (Other.Base == Base)
      29             :       return true;
      30             : 
      31             :     // Match GlobalAddresses
      32     5054335 :     if (auto *A = dyn_cast<GlobalAddressSDNode>(Base))
      33     4067428 :       if (auto *B = dyn_cast<GlobalAddressSDNode>(Other.Base))
      34     1961234 :         if (A->getGlobal() == B->getGlobal()) {
      35        6478 :           Off += B->getOffset() - A->getOffset();
      36        6478 :           return true;
      37             :         }
      38             : 
      39     2941663 :     const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
      40             : 
      41             :     // Match non-equal FrameIndexes - If both frame indices are fixed
      42             :     // we know their relative offsets and can compare them. Otherwise
      43             :     // we must be conservative.
      44     3105915 :     if (auto *A = dyn_cast<FrameIndexSDNode>(Base))
      45      202544 :       if (auto *B = dyn_cast<FrameIndexSDNode>(Other.Base))
      46       47966 :         if (MFI.isFixedObjectIndex(A->getIndex()) &&
      47       19018 :             MFI.isFixedObjectIndex(B->getIndex())) {
      48       28032 :           Off += MFI.getObjectOffset(B->getIndex()) -
      49       18688 :                  MFI.getObjectOffset(A->getIndex());
      50        9344 :           return true;
      51             :         }
      52             :   }
      53             :   return false;
      54             : }
      55             : 
      56             : /// Parses tree in Ptr for base, index, offset addresses.
      57    15222812 : BaseIndexOffset BaseIndexOffset::match(SDValue Ptr, const SelectionDAG &DAG) {
      58             :   // (((B + I*M) + c)) + c ...
      59    15222812 :   SDValue Base = DAG.getTargetLoweringInfo().unwrapAddress(Ptr);
      60    15222812 :   SDValue Index = SDValue();
      61    15222812 :   int64_t Offset = 0;
      62    15222812 :   bool IsIndexSignExt = false;
      63             : 
      64             :   // Consume constant adds & ors with appropriate masking.
      65    73941079 :   while (Base->getOpcode() == ISD::ADD || Base->getOpcode() == ISD::OR) {
      66    64284106 :     if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) {
      67             :       // Only consider ORs which act as adds.
      68    14991396 :       if (Base->getOpcode() == ISD::OR &&
      69      985822 :           !DAG.MaskedValueIsZero(Base->getOperand(0), C->getAPIntValue()))
      70             :         break;
      71    14498485 :       Offset += C->getSExtValue();
      72    28996970 :       Base = Base->getOperand(0);
      73             :       continue;
      74             :     }
      75             :     break;
      76             :   }
      77             : 
      78    15222812 :   if (Base->getOpcode() == ISD::ADD) {
      79             :     // TODO: The following code appears to be needless as it just
      80             :     //       bails on some Ptrs early, reducing the cases where we
      81             :     //       find equivalence. We should be able to remove this.
      82             :     // Inside a loop the current BASE pointer is calculated using an ADD and a
      83             :     // MUL instruction. In this case Base is the actual BASE pointer.
      84             :     // (i64 add (i64 %array_ptr)
      85             :     //          (i64 mul (i64 %induction_var)
      86             :     //                   (i64 %element_size)))
      87     9367296 :     if (Base->getOperand(1)->getOpcode() == ISD::MUL)
      88       25942 :       return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
      89             : 
      90             :     // Look at Base + Index + Offset cases.
      91     6192980 :     Index = Base->getOperand(1);
      92     6192980 :     SDValue PotentialBase = Base->getOperand(0);
      93             : 
      94             :     // Skip signextends.
      95     3096490 :     if (Index->getOpcode() == ISD::SIGN_EXTEND) {
      96         810 :       Index = Index->getOperand(0);
      97         405 :       IsIndexSignExt = true;
      98             :     }
      99             : 
     100             :     // Check if Index Offset pattern
     101     3096490 :     if (Index->getOpcode() != ISD::ADD ||
     102        2756 :         !isa<ConstantSDNode>(Index->getOperand(1)))
     103     3095221 :       return BaseIndexOffset(PotentialBase, Index, Offset, IsIndexSignExt);
     104             : 
     105        5076 :     Offset += cast<ConstantSDNode>(Index->getOperand(1))->getSExtValue();
     106        2538 :     Index = Index->getOperand(0);
     107        1269 :     if (Index->getOpcode() == ISD::SIGN_EXTEND) {
     108         132 :       Index = Index->getOperand(0);
     109          66 :       IsIndexSignExt = true;
     110             :     } else
     111             :       IsIndexSignExt = false;
     112             :     Base = PotentialBase;
     113             :   }
     114    12101649 :   return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt);
     115             : }
     116             : } // end namespace llvm

Generated by: LCOV version 1.13