[llvm-commits] [llvm] r84775 - in /llvm/trunk: lib/Target/MSP430/MSP430ISelDAGToDAG.cpp lib/Target/MSP430/MSP430InstrInfo.cpp test/CodeGen/MSP430/Inst16mm.ll test/CodeGen/MSP430/Inst8mm.ll
Anton Korobeynikov
asl at math.spbu.ru
Wed Oct 21 12:17:55 PDT 2009
Author: asl
Date: Wed Oct 21 14:17:55 2009
New Revision: 84775
URL: http://llvm.org/viewvc/llvm-project?rev=84775&view=rev
Log:
RMW preprocessing stuff was incorrect. Grab the stuff from x86 backend and disable some tests until it will be clever enough to handle them.
Modified:
llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp
llvm/trunk/test/CodeGen/MSP430/Inst16mm.ll
llvm/trunk/test/CodeGen/MSP430/Inst8mm.ll
Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp?rev=84775&r1=84774&r2=84775&view=diff
==============================================================================
--- llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp Wed Oct 21 14:17:55 2009
@@ -151,28 +151,15 @@
/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
/// and move load below the TokenFactor. Replace store's chain operand with
/// load's chain result.
-/// Shamelessly stolen from X86.
static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load,
SDValue Store, SDValue TF) {
SmallVector<SDValue, 4> Ops;
- bool isRMW = false;
- SDValue TF0, TF1, NewTF;
for (unsigned i = 0, e = TF.getNode()->getNumOperands(); i != e; ++i)
- if (Load.getNode() == TF.getOperand(i).getNode()) {
- TF0 = Load.getOperand(0);
- Ops.push_back(TF0);
- } else {
- TF1 = TF.getOperand(i);
- Ops.push_back(TF1);
- if (LoadSDNode* LD = dyn_cast<LoadSDNode>(TF1))
- isRMW = !LD->isVolatile();
- }
-
- if (isRMW && TF1.getOperand(0).getNode() == TF0.getNode())
- NewTF = TF0;
- else
- NewTF = CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size());
-
+ if (Load.getNode() == TF.getOperand(i).getNode())
+ Ops.push_back(Load.getOperand(0));
+ else
+ Ops.push_back(TF.getOperand(i));
+ SDValue NewTF = CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size());
SDValue NewLoad = CurDAG->UpdateNodeOperands(Load, NewTF,
Load.getOperand(1),
Load.getOperand(2));
@@ -180,10 +167,9 @@
Store.getOperand(2), Store.getOperand(3));
}
-/// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG. The chain
-/// produced by the load must only be used by the store's chain operand,
-/// otherwise this may produce a cycle in the DAG.
-/// Shamelessly stolen from X86. FIXME: Should we make this function common?
+/// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG.
+/// The chain produced by the load must only be used by the store's chain
+/// operand, otherwise this may produce a cycle in the DAG.
static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
SDValue &Load) {
if (N.getOpcode() == ISD::BIT_CONVERT)
@@ -210,52 +196,86 @@
}
/// PreprocessForRMW - Preprocess the DAG to make instruction selection better.
-/// Shamelessly stolen from X86.
+/// This is only run if not in -O0 mode.
+/// This allows the instruction selector to pick more read-modify-write
+/// instructions. This is a common case:
+///
+/// [Load chain]
+/// ^
+/// |
+/// [Load]
+/// ^ ^
+/// | |
+/// / \-
+/// / |
+/// [TokenFactor] [Op]
+/// ^ ^
+/// | |
+/// \ /
+/// \ /
+/// [Store]
+///
+/// The fact the store's chain operand != load's chain will prevent the
+/// (store (op (load))) instruction from being selected. We can transform it to:
+///
+/// [Load chain]
+/// ^
+/// |
+/// [TokenFactor]
+/// ^
+/// |
+/// [Load]
+/// ^ ^
+/// | |
+/// | \-
+/// | |
+/// | [Op]
+/// | ^
+/// | |
+/// \ /
+/// \ /
+/// [Store]
void MSP430DAGToDAGISel::PreprocessForRMW() {
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
E = CurDAG->allnodes_end(); I != E; ++I) {
if (!ISD::isNON_TRUNCStore(I))
continue;
-
SDValue Chain = I->getOperand(0);
+
if (Chain.getNode()->getOpcode() != ISD::TokenFactor)
continue;
- SDValue N1 = I->getOperand(1); // Value to store
- SDValue N2 = I->getOperand(2); // Address of store
-
- if (!N1.hasOneUse())
+ SDValue N1 = I->getOperand(1);
+ SDValue N2 = I->getOperand(2);
+ if ((N1.getValueType().isFloatingPoint() &&
+ !N1.getValueType().isVector()) ||
+ !N1.hasOneUse())
continue;
bool RModW = false;
SDValue Load;
unsigned Opcode = N1.getNode()->getOpcode();
switch (Opcode) {
- case ISD::ADD:
- case ISD::AND:
- case ISD::OR:
- case ISD::XOR:
- case ISD::ADDC:
- case ISD::ADDE: {
- SDValue N10 = N1.getOperand(0);
- SDValue N11 = N1.getOperand(1);
- RModW = isRMWLoad(N10, Chain, N2, Load);
-
- if (!RModW && isRMWLoad(N11, Chain, N2, Load)) {
- // Swap the operands, making the RMW load the first operand seems
- // to help selection and prevent token chain loops.
- N1 = CurDAG->UpdateNodeOperands(N1, N11, N10);
- RModW = true;
- }
- break;
- }
- case ISD::SUB:
- case ISD::SUBC:
- case ISD::SUBE: {
- SDValue N10 = N1.getOperand(0);
- RModW = isRMWLoad(N10, Chain, N2, Load);
- break;
- }
+ case ISD::ADD:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::ADDC:
+ case ISD::ADDE: {
+ SDValue N10 = N1.getOperand(0);
+ SDValue N11 = N1.getOperand(1);
+ RModW = isRMWLoad(N10, Chain, N2, Load);
+ if (!RModW)
+ RModW = isRMWLoad(N11, Chain, N2, Load);
+ break;
+ }
+ case ISD::SUB:
+ case ISD::SUBC:
+ case ISD::SUBE: {
+ SDValue N10 = N1.getOperand(0);
+ RModW = isRMWLoad(N10, Chain, N2, Load);
+ break;
+ }
}
if (RModW) {
Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp?rev=84775&r1=84774&r2=84775&view=diff
==============================================================================
--- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp Wed Oct 21 14:17:55 2009
@@ -169,7 +169,6 @@
return Count;
}
-
bool MSP430InstrInfo::
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
assert(Cond.size() == 1 && "Invalid Xbranch condition!");
Modified: llvm/trunk/test/CodeGen/MSP430/Inst16mm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/Inst16mm.ll?rev=84775&r1=84774&r2=84775&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/Inst16mm.ll (original)
+++ llvm/trunk/test/CodeGen/MSP430/Inst16mm.ll Wed Oct 21 14:17:55 2009
@@ -1,4 +1,5 @@
; RUN: llc -march=msp430 < %s | FileCheck %s
+; XFAIL
target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"
target triple = "msp430-generic-generic"
@foo = common global i16 0, align 2
Modified: llvm/trunk/test/CodeGen/MSP430/Inst8mm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/Inst8mm.ll?rev=84775&r1=84774&r2=84775&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/Inst8mm.ll (original)
+++ llvm/trunk/test/CodeGen/MSP430/Inst8mm.ll Wed Oct 21 14:17:55 2009
@@ -1,4 +1,5 @@
; RUN: llc -march=msp430 < %s | FileCheck %s
+; XFAIL
target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"
target triple = "msp430-generic-generic"
More information about the llvm-commits
mailing list