1 //==- llvm/CodeGen/SelectionDAGAddressAnalysis.cpp - DAG Address Analysis --==// 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 #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h" 11 #include "llvm/CodeGen/ISDOpcodes.h" 12 #include "llvm/CodeGen/MachineFrameInfo.h" 13 #include "llvm/CodeGen/MachineFunction.h" 14 #include "llvm/CodeGen/SelectionDAG.h" 15 #include "llvm/CodeGen/SelectionDAGNodes.h" 16 #include "llvm/CodeGen/TargetLowering.h" 17 #include "llvm/Support/Casting.h" 18 #include <cstdint> 19 20 using namespace llvm; 21 22 bool BaseIndexOffset::equalBaseIndex(const BaseIndexOffset &Other, 23 const SelectionDAG &DAG, 24 int64_t &Off) const { 25 // Conservatively fail if we a match failed.. 26 if (!Base.getNode() || !Other.Base.getNode()) 27 return false; 28 // Initial Offset difference. 29 Off = Other.Offset - Offset; 30 31 if ((Other.Index == Index) && (Other.IsIndexSignExt == IsIndexSignExt)) { 32 // Trivial match. 33 if (Other.Base == Base) 34 return true; 35 36 // Match GlobalAddresses 37 if (auto *A = dyn_cast<GlobalAddressSDNode>(Base)) 38 if (auto *B = dyn_cast<GlobalAddressSDNode>(Other.Base)) 39 if (A->getGlobal() == B->getGlobal()) { 40 Off += B->getOffset() - A->getOffset(); 41 return true; 42 } 43 44 // Match Constants 45 if (auto *A = dyn_cast<ConstantPoolSDNode>(Base)) 46 if (auto *B = dyn_cast<ConstantPoolSDNode>(Other.Base)) { 47 bool IsMatch = 48 A->isMachineConstantPoolEntry() == B->isMachineConstantPoolEntry(); 49 if (IsMatch) { 50 if (A->isMachineConstantPoolEntry()) 51 IsMatch = A->getMachineCPVal() == B->getMachineCPVal(); 52 else 53 IsMatch = A->getConstVal() == B->getConstVal(); 54 } 55 if (IsMatch) { 56 Off += B->getOffset() - A->getOffset(); 57 return true; 58 } 59 } 60 61 const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); 62 63 // Match non-equal FrameIndexes - If both frame indices are fixed 64 // we know their relative offsets and can compare them. Otherwise 65 // we must be conservative. 66 if (auto *A = dyn_cast<FrameIndexSDNode>(Base)) 67 if (auto *B = dyn_cast<FrameIndexSDNode>(Other.Base)) 68 if (MFI.isFixedObjectIndex(A->getIndex()) && 69 MFI.isFixedObjectIndex(B->getIndex())) { 70 Off += MFI.getObjectOffset(B->getIndex()) - 71 MFI.getObjectOffset(A->getIndex()); 72 return true; 73 } 74 } 75 return false; 76 } 77 78 /// Parses tree in Ptr for base, index, offset addresses. 79 BaseIndexOffset BaseIndexOffset::match(const LSBaseSDNode *N, 80 const SelectionDAG &DAG) { 81 SDValue Ptr = N->getBasePtr(); 82 83 // (((B + I*M) + c)) + c ... 84 SDValue Base = DAG.getTargetLoweringInfo().unwrapAddress(Ptr); 85 SDValue Index = SDValue(); 86 int64_t Offset = 0; 87 bool IsIndexSignExt = false; 88 89 // pre-inc/pre-dec ops are components of EA. 90 if (N->getAddressingMode() == ISD::PRE_INC) { 91 if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset())) 92 Offset += C->getSExtValue(); 93 else // If unknown, give up now. 94 return BaseIndexOffset(SDValue(), SDValue(), 0, false); 95 } else if (N->getAddressingMode() == ISD::PRE_DEC) { 96 if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset())) 97 Offset -= C->getSExtValue(); 98 else // If unknown, give up now. 99 return BaseIndexOffset(SDValue(), SDValue(), 0, false); 100 } 101 102 // Consume constant adds & ors with appropriate masking. 103 while (true) { 104 switch (Base->getOpcode()) { 105 case ISD::OR: 106 // Only consider ORs which act as adds. 107 if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) 108 if (DAG.MaskedValueIsZero(Base->getOperand(0), C->getAPIntValue())) { 109 Offset += C->getSExtValue(); 110 Base = Base->getOperand(0); 111 continue; 112 } 113 break; 114 case ISD::ADD: 115 if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) { 116 Offset += C->getSExtValue(); 117 Base = Base->getOperand(0); 118 continue; 119 } 120 break; 121 case ISD::LOAD: 122 case ISD::STORE: { 123 auto *LSBase = cast<LSBaseSDNode>(Base.getNode()); 124 unsigned int IndexResNo = (Base->getOpcode() == ISD::LOAD) ? 1 : 0; 125 if (LSBase->isIndexed() && Base.getResNo() == IndexResNo) 126 if (auto *C = dyn_cast<ConstantSDNode>(LSBase->getOffset())) { 127 auto Off = C->getSExtValue(); 128 if (LSBase->getAddressingMode() == ISD::PRE_DEC || 129 LSBase->getAddressingMode() == ISD::POST_DEC) 130 Offset -= Off; 131 else 132 Offset += Off; 133 Base = LSBase->getBasePtr(); 134 continue; 135 } 136 break; 137 } 138 } 139 // If we get here break out of the loop. 140 break; 141 } 142 143 if (Base->getOpcode() == ISD::ADD) { 144 // TODO: The following code appears to be needless as it just 145 // bails on some Ptrs early, reducing the cases where we 146 // find equivalence. We should be able to remove this. 147 // Inside a loop the current BASE pointer is calculated using an ADD and a 148 // MUL instruction. In this case Base is the actual BASE pointer. 149 // (i64 add (i64 %array_ptr) 150 // (i64 mul (i64 %induction_var) 151 // (i64 %element_size))) 152 if (Base->getOperand(1)->getOpcode() == ISD::MUL) 153 return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt); 154 155 // Look at Base + Index + Offset cases. 156 Index = Base->getOperand(1); 157 SDValue PotentialBase = Base->getOperand(0); 158 159 // Skip signextends. 160 if (Index->getOpcode() == ISD::SIGN_EXTEND) { 161 Index = Index->getOperand(0); 162 IsIndexSignExt = true; 163 } 164 165 // Check if Index Offset pattern 166 if (Index->getOpcode() != ISD::ADD || 167 !isa<ConstantSDNode>(Index->getOperand(1))) 168 return BaseIndexOffset(PotentialBase, Index, Offset, IsIndexSignExt); 169 170 Offset += cast<ConstantSDNode>(Index->getOperand(1))->getSExtValue(); 171 Index = Index->getOperand(0); 172 if (Index->getOpcode() == ISD::SIGN_EXTEND) { 173 Index = Index->getOperand(0); 174 IsIndexSignExt = true; 175 } else 176 IsIndexSignExt = false; 177 Base = PotentialBase; 178 } 179 return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt); 180 } 181