From 119da2eb20fffce88fa659d761ef5cea43f09ab6 Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Mon, 27 May 2013 02:06:39 +0000 Subject: PPC: Add a isConsecutiveLS utility function isConsecutiveLS is a slightly more general form of SelectionDAG::isConsecutiveLoad. Aside from also handling stores, it also does not assume equality of the chain operands is necessary. In the case of the PPC backend, this chain condition is checked in a more general way by the surrounding code. Mostly, this part of the refactoring in preparation for supporting optimized unaligned stores. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182723 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelLowering.cpp | 44 ++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'lib/Target/PowerPC/PPCISelLowering.cpp') diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 87b63a8f0f..ddf31bdd8c 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -6781,6 +6781,46 @@ SDValue PPCTargetLowering::DAGCombineFastRecipFSQRT(SDValue Op, return SDValue(); } +// Like SelectionDAG::isConsecutiveLoad, but also works for stores, and does +// not enforce equality of the chain operands. +static bool isConsecutiveLS(LSBaseSDNode *LS, LSBaseSDNode *Base, + unsigned Bytes, int Dist, + SelectionDAG &DAG) { + EVT VT = LS->getMemoryVT(); + if (VT.getSizeInBits() / 8 != Bytes) + return false; + + SDValue Loc = LS->getBasePtr(); + SDValue BaseLoc = Base->getBasePtr(); + if (Loc.getOpcode() == ISD::FrameIndex) { + if (BaseLoc.getOpcode() != ISD::FrameIndex) + return false; + const MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + int FI = cast(Loc)->getIndex(); + int BFI = cast(BaseLoc)->getIndex(); + int FS = MFI->getObjectSize(FI); + int BFS = MFI->getObjectSize(BFI); + if (FS != BFS || FS != (int)Bytes) return false; + return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Bytes); + } + + // Handle X+C + if (DAG.isBaseWithConstantOffset(Loc) && Loc.getOperand(0) == BaseLoc && + cast(Loc.getOperand(1))->getSExtValue() == Dist*Bytes) + return true; + + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + const GlobalValue *GV1 = NULL; + const GlobalValue *GV2 = NULL; + int64_t Offset1 = 0; + int64_t Offset2 = 0; + bool isGA1 = TLI.isGAPlusOffset(Loc.getNode(), GV1, Offset1); + bool isGA2 = TLI.isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2); + if (isGA1 && isGA2 && GV1 == GV2) + return Offset1 == (Offset2 + Dist*Bytes); + return false; +} + // Return true is there is a nearyby consecutive load to the one provided // (regardless of alignment). We search up and down the chain, looking though // token factors and other loads (but nothing else). As a result, a true @@ -6803,7 +6843,7 @@ static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG) { continue; if (LoadSDNode *ChainLD = dyn_cast(ChainNext)) { - if (DAG.isConsecutiveLoad(ChainLD, LD, VT.getStoreSize(), 1)) + if (isConsecutiveLS(ChainLD, LD, VT.getStoreSize(), 1, DAG)) return true; if (!Visited.count(ChainLD->getChain().getNode())) @@ -6835,7 +6875,7 @@ static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG) { continue; if (LoadSDNode *ChainLD = dyn_cast(LoadRoot)) - if (DAG.isConsecutiveLoad(ChainLD, LD, VT.getStoreSize(), 1)) + if (isConsecutiveLS(ChainLD, LD, VT.getStoreSize(), 1, DAG)) return true; for (SDNode::use_iterator UI = LoadRoot->use_begin(), -- cgit v1.2.3