summaryrefslogtreecommitdiff
path: root/lib/Target/XCore/XCoreISelLowering.cpp
diff options
context:
space:
mode:
authorRichard Osborne <richard@xmos.com>2013-05-04 17:24:33 +0000
committerRichard Osborne <richard@xmos.com>2013-05-04 17:24:33 +0000
commit6ffbf6ea8fe7fbe2166b07a88004baac163aa3c5 (patch)
tree3866b286f1f4b9d1a2f78eeee5a973a62bc64f56 /lib/Target/XCore/XCoreISelLowering.cpp
parent40827bc716e9eda3e70460207696f2ec10dd67ad (diff)
downloadllvm-6ffbf6ea8fe7fbe2166b07a88004baac163aa3c5.tar.gz
llvm-6ffbf6ea8fe7fbe2166b07a88004baac163aa3c5.tar.bz2
llvm-6ffbf6ea8fe7fbe2166b07a88004baac163aa3c5.tar.xz
[XCore] Make use of the target independent global address offset folding.
This let us to remove some custom code that matched constant offsets from globals at instruction selection time as a special addressing mode. No intended functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181126 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/XCore/XCoreISelLowering.cpp')
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp42
1 files changed, 29 insertions, 13 deletions
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index 357af79b6b..dfa8ad732f 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -36,6 +36,8 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
using namespace llvm;
const char *XCoreTargetLowering::
@@ -241,9 +243,20 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV,
SDValue XCoreTargetLowering::
LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
{
- const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
- SDValue GA = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(), MVT::i32);
- return getGlobalAddressWrapper(GA, GV, DAG);
+ DebugLoc DL = Op.getDebugLoc();
+ const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
+ const GlobalValue *GV = GN->getGlobal();
+ int64_t Offset = GN->getOffset();
+ // We can only fold positive offsets that are a multiple of the word size.
+ int64_t FoldedOffset = std::max(Offset & ~3, 0LL);
+ SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset);
+ GA = getGlobalAddressWrapper(GA, GV, DAG);
+ // Handle the rest of the offset.
+ if (Offset != FoldedOffset) {
+ SDValue Remaining = DAG.getConstant(Offset - FoldedOffset, MVT::i32);
+ GA = DAG.getNode(ISD::ADD, DL, MVT::i32, GA, Remaining);
+ }
+ return GA;
}
static inline SDValue BuildGetId(SelectionDAG &DAG, DebugLoc dl) {
@@ -319,10 +332,19 @@ lowerLoadWordFromAlignedBasePlusOffset(DebugLoc DL, SDValue Chain, SDValue Base,
// Lower to pair of consecutive word aligned loads plus some bit shifting.
int32_t HighOffset = RoundUpToAlignment(Offset, 4);
int32_t LowOffset = HighOffset - 4;
- SDValue LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
- DAG.getConstant(LowOffset, MVT::i32));
- SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
- DAG.getConstant(HighOffset, MVT::i32));
+ SDValue LowAddr, HighAddr;
+ if (GlobalAddressSDNode *GASD =
+ dyn_cast<GlobalAddressSDNode>(Base.getNode())) {
+ LowAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(),
+ LowOffset);
+ HighAddr = DAG.getGlobalAddress(GASD->getGlobal(), DL, Base.getValueType(),
+ HighOffset);
+ } else {
+ LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
+ DAG.getConstant(LowOffset, MVT::i32));
+ HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base,
+ DAG.getConstant(HighOffset, MVT::i32));
+ }
SDValue LowShift = DAG.getConstant((Offset - LowOffset) * 8, MVT::i32);
SDValue HighShift = DAG.getConstant((HighOffset - Offset) * 8, MVT::i32);
@@ -1553,12 +1575,6 @@ XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM,
}
}
-bool XCoreTargetLowering::
-isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
- // The XCore target isn't yet aware of offsets.
- return false;
-}
-
//===----------------------------------------------------------------------===//
// XCore Inline Assembly Support
//===----------------------------------------------------------------------===//