diff options
Diffstat (limited to 'gnu/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp')
| -rw-r--r-- | gnu/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/gnu/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/gnu/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp index 0d69441ebb7..da1574f6052 100644 --- a/gnu/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp +++ b/gnu/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp @@ -1,5 +1,4 @@ -//===-- llvm/CodeGen/SelectionDAGAddressAnalysis.cpp ------- DAG Address -//Analysis ---*- C++ -*-===// +//==- llvm/CodeGen/SelectionDAGAddressAnalysis.cpp - DAG Address Analysis --==// // // The LLVM Compiler Infrastructure // @@ -7,18 +6,24 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h" #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/Support/Casting.h" +#include <cstdint> -namespace llvm { +using namespace llvm; bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG, int64_t &Off) { + // Conservatively fail if we a match failed.. + if (!Base.getNode() || !Other.Base.getNode()) + return false; // Initial Offset difference. Off = Other.Offset - Offset; @@ -35,6 +40,23 @@ bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other, return true; } + // Match Constants + if (auto *A = dyn_cast<ConstantPoolSDNode>(Base)) + if (auto *B = dyn_cast<ConstantPoolSDNode>(Other.Base)) { + bool IsMatch = + A->isMachineConstantPoolEntry() == B->isMachineConstantPoolEntry(); + if (IsMatch) { + if (A->isMachineConstantPoolEntry()) + IsMatch = A->getMachineCPVal() == B->getMachineCPVal(); + else + IsMatch = A->getConstVal() == B->getConstVal(); + } + if (IsMatch) { + Off += B->getOffset() - A->getOffset(); + return true; + } + } + const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); // Match non-equal FrameIndexes - If both frame indices are fixed @@ -53,13 +75,29 @@ bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other, } /// Parses tree in Ptr for base, index, offset addresses. -BaseIndexOffset BaseIndexOffset::match(SDValue Ptr, const SelectionDAG &DAG) { +BaseIndexOffset BaseIndexOffset::match(LSBaseSDNode *N, + const SelectionDAG &DAG) { + SDValue Ptr = N->getBasePtr(); + // (((B + I*M) + c)) + c ... - SDValue Base = Ptr; + SDValue Base = DAG.getTargetLoweringInfo().unwrapAddress(Ptr); SDValue Index = SDValue(); int64_t Offset = 0; bool IsIndexSignExt = false; + // pre-inc/pre-dec ops are components of EA. + if (N->getAddressingMode() == ISD::PRE_INC) { + if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset())) + Offset += C->getSExtValue(); + else // If unknown, give up now. + return BaseIndexOffset(SDValue(), SDValue(), 0, false); + } else if (N->getAddressingMode() == ISD::PRE_DEC) { + if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset())) + Offset -= C->getSExtValue(); + else // If unknown, give up now. + return BaseIndexOffset(SDValue(), SDValue(), 0, false); + } + // Consume constant adds & ors with appropriate masking. while (Base->getOpcode() == ISD::ADD || Base->getOpcode() == ISD::OR) { if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) { @@ -112,4 +150,3 @@ BaseIndexOffset BaseIndexOffset::match(SDValue Ptr, const SelectionDAG &DAG) { } return BaseIndexOffset(Base, Index, Offset, IsIndexSignExt); } -} // end namespace llvm |
