aboutsummaryrefslogtreecommitdiffstats
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
parent40827bc716e9eda3e70460207696f2ec10dd67ad (diff)
downloadexternal_llvm-6ffbf6ea8fe7fbe2166b07a88004baac163aa3c5.zip
external_llvm-6ffbf6ea8fe7fbe2166b07a88004baac163aa3c5.tar.gz
external_llvm-6ffbf6ea8fe7fbe2166b07a88004baac163aa3c5.tar.bz2
[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
-rw-r--r--lib/Target/XCore/Disassembler/XCoreDisassembler.cpp10
-rw-r--r--lib/Target/XCore/InstPrinter/XCoreInstPrinter.cpp11
-rw-r--r--lib/Target/XCore/XCoreISelDAGToDAG.cpp44
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp42
-rw-r--r--lib/Target/XCore/XCoreISelLowering.h2
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.td30
6 files changed, 41 insertions, 98 deletions
diff --git a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
index 7b99967..7282f2f 100644
--- a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
+++ b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
@@ -97,9 +97,6 @@ static DecodeStatus DecodeRRegsRegisterClass(MCInst &Inst,
static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder);
-static DecodeStatus DecodeMEMiiOperand(MCInst &Inst, unsigned Val,
- uint64_t Address, const void *Decoder);
-
static DecodeStatus Decode2RInstruction(MCInst &Inst,
unsigned Insn,
uint64_t Address,
@@ -242,13 +239,6 @@ static DecodeStatus DecodeBitpOperand(MCInst &Inst, unsigned Val,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeMEMiiOperand(MCInst &Inst, unsigned Val,
- uint64_t Address, const void *Decoder) {
- Inst.addOperand(MCOperand::CreateImm(Val));
- Inst.addOperand(MCOperand::CreateImm(0));
- return MCDisassembler::Success;
-}
-
static DecodeStatus
Decode2OpInstruction(unsigned Insn, unsigned &Op1, unsigned &Op2) {
unsigned Combined = fieldFromInstruction(Insn, 6, 5);
diff --git a/lib/Target/XCore/InstPrinter/XCoreInstPrinter.cpp b/lib/Target/XCore/InstPrinter/XCoreInstPrinter.cpp
index 1592351..9ae8c0d 100644
--- a/lib/Target/XCore/InstPrinter/XCoreInstPrinter.cpp
+++ b/lib/Target/XCore/InstPrinter/XCoreInstPrinter.cpp
@@ -84,14 +84,3 @@ printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
assert(Op.isExpr() && "unknown operand kind in printOperand");
printExpr(Op.getExpr(), O);
}
-
-void XCoreInstPrinter::
-printMemOperand(const MCInst *MI, int opNum, raw_ostream &O) {
- printOperand(MI, opNum, O);
-
- if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
- return;
-
- O << "+";
- printOperand(MI, opNum+1, O);
-}
diff --git a/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
index d16811c..eb29b50 100644
--- a/lib/Target/XCore/XCoreISelDAGToDAG.cpp
+++ b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
@@ -68,8 +68,6 @@ namespace {
// Complex Pattern Selectors.
bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
- bool SelectADDRdpii(SDValue Addr, SDValue &Base, SDValue &Offset);
- bool SelectADDRcpii(SDValue Addr, SDValue &Base, SDValue &Offset);
virtual const char *getPassName() const {
return "XCore DAG->DAG Pattern Instruction Selection";
@@ -110,48 +108,6 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base,
return false;
}
-bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Addr, SDValue &Base,
- SDValue &Offset) {
- if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) {
- Base = Addr.getOperand(0);
- Offset = CurDAG->getTargetConstant(0, MVT::i32);
- return true;
- }
- if (Addr.getOpcode() == ISD::ADD) {
- ConstantSDNode *CN = 0;
- if ((Addr.getOperand(0).getOpcode() == XCoreISD::DPRelativeWrapper)
- && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
- && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
- // Constant word offset from a object in the data region
- Base = Addr.getOperand(0).getOperand(0);
- Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
- return true;
- }
- }
- return false;
-}
-
-bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Addr, SDValue &Base,
- SDValue &Offset) {
- if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) {
- Base = Addr.getOperand(0);
- Offset = CurDAG->getTargetConstant(0, MVT::i32);
- return true;
- }
- if (Addr.getOpcode() == ISD::ADD) {
- ConstantSDNode *CN = 0;
- if ((Addr.getOperand(0).getOpcode() == XCoreISD::CPRelativeWrapper)
- && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
- && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
- // Constant word offset from a object in the data region
- Base = Addr.getOperand(0).getOperand(0);
- Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
- return true;
- }
- }
- return false;
-}
-
SDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
switch (N->getOpcode()) {
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index 357af79..dfa8ad7 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
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h
index 4ea5d9f..c7dfa26 100644
--- a/lib/Target/XCore/XCoreISelLowering.h
+++ b/lib/Target/XCore/XCoreISelLowering.h
@@ -106,8 +106,6 @@ namespace llvm {
virtual bool isLegalAddressingMode(const AddrMode &AM,
Type *Ty) const;
- virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
-
private:
const XCoreTargetMachine &TM;
const XCoreSubtarget &Subtarget;
diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td
index 03653cb..61334c6 100644
--- a/lib/Target/XCore/XCoreInstrInfo.td
+++ b/lib/Target/XCore/XCoreInstrInfo.td
@@ -174,15 +174,9 @@ def pclabel : Operand<i32>;
// Addressing modes
def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>;
-def ADDRdpii : ComplexPattern<i32, 2, "SelectADDRdpii", [add, dprelwrapper],
- []>;
-def ADDRcpii : ComplexPattern<i32, 2, "SelectADDRcpii", [add, cprelwrapper],
- []>;
// Address operands
def MEMii : Operand<i32> {
- let PrintMethod = "printMemOperand";
- let DecoderMethod = "DecodeMEMiiOperand";
let MIOperandInfo = (ops i32imm, i32imm);
}
@@ -515,29 +509,29 @@ def LMUL_l6r : _FL6R<
//let Uses = [DP] in ...
let neverHasSideEffects = 1, isReMaterializable = 1 in
-def LDAWDP_ru6: _FRU6<0b011000, (outs RRegs:$a), (ins MEMii:$b),
+def LDAWDP_ru6: _FRU6<0b011000, (outs RRegs:$a), (ins i32imm:$b),
"ldaw $a, dp[$b]", []>;
let isReMaterializable = 1 in
-def LDAWDP_lru6: _FLRU6<0b011000, (outs RRegs:$a), (ins MEMii:$b),
+def LDAWDP_lru6: _FLRU6<0b011000, (outs RRegs:$a), (ins i32imm:$b),
"ldaw $a, dp[$b]",
- [(set RRegs:$a, ADDRdpii:$b)]>;
+ [(set RRegs:$a, (dprelwrapper tglobaladdr:$b))]>;
let mayLoad=1 in
-def LDWDP_ru6: _FRU6<0b010110, (outs RRegs:$a), (ins MEMii:$b),
+def LDWDP_ru6: _FRU6<0b010110, (outs RRegs:$a), (ins i32imm:$b),
"ldw $a, dp[$b]", []>;
-def LDWDP_lru6: _FLRU6<0b010110, (outs RRegs:$a), (ins MEMii:$b),
+def LDWDP_lru6: _FLRU6<0b010110, (outs RRegs:$a), (ins i32imm:$b),
"ldw $a, dp[$b]",
- [(set RRegs:$a, (load ADDRdpii:$b))]>;
+ [(set RRegs:$a, (load (dprelwrapper tglobaladdr:$b)))]>;
let mayStore=1 in
-def STWDP_ru6 : _FRU6<0b010100, (outs), (ins RRegs:$a, MEMii:$b),
+def STWDP_ru6 : _FRU6<0b010100, (outs), (ins RRegs:$a, i32imm:$b),
"stw $a, dp[$b]", []>;
-def STWDP_lru6 : _FLRU6<0b010100, (outs), (ins RRegs:$a, MEMii:$b),
+def STWDP_lru6 : _FLRU6<0b010100, (outs), (ins RRegs:$a, i32imm:$b),
"stw $a, dp[$b]",
- [(store RRegs:$a, ADDRdpii:$b)]>;
+ [(store RRegs:$a, (dprelwrapper tglobaladdr:$b))]>;
//let Uses = [CP] in ..
let mayLoad = 1, isReMaterializable = 1, neverHasSideEffects = 1 in
@@ -626,12 +620,12 @@ def BRFU_lu6 : _FLU6<0b0111001100, (outs), (ins brtarget:$a), "bu $a", []>;
//let Uses = [CP] in ...
let Defs = [R11], neverHasSideEffects = 1, isReMaterializable = 1 in
-def LDAWCP_u6: _FU6<0b0111111101, (outs), (ins MEMii:$a), "ldaw r11, cp[$a]",
+def LDAWCP_u6: _FU6<0b0111111101, (outs), (ins i32imm:$a), "ldaw r11, cp[$a]",
[]>;
let Defs = [R11], isReMaterializable = 1 in
-def LDAWCP_lu6: _FLU6<0b0111111101, (outs), (ins MEMii:$a), "ldaw r11, cp[$a]",
- [(set R11, ADDRcpii:$a)]>;
+def LDAWCP_lu6: _FLU6<0b0111111101, (outs), (ins i32imm:$a), "ldaw r11, cp[$a]",
+ [(set R11, (cprelwrapper tglobaladdr:$a))]>;
let Defs = [R11] in
defm GETSR : FU6_LU6_np<0b0111111100, "getsr r11,">;