From 83fceb948165adb50c450ff28d51d0a99615b854 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Wed, 21 Oct 2009 19:17:55 +0000 Subject: [PATCH] RMW preprocessing stuff was incorrect. Grab the stuff from x86 backend and disable some tests until it will be clever enough to handle them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84775 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 126 +++++++++++++---------- lib/Target/MSP430/MSP430InstrInfo.cpp | 1 - test/CodeGen/MSP430/Inst16mm.ll | 1 + test/CodeGen/MSP430/Inst8mm.ll | 1 + 4 files changed, 75 insertions(+), 54 deletions(-) diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index 4195a88f8de..fb841ba006c 100644 --- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -151,28 +151,15 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, /// 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 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(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 @@ static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load, 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 @@ static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address, } /// 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) { diff --git a/lib/Target/MSP430/MSP430InstrInfo.cpp b/lib/Target/MSP430/MSP430InstrInfo.cpp index f983a7a2969..a6d9638cf59 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.cpp +++ b/lib/Target/MSP430/MSP430InstrInfo.cpp @@ -169,7 +169,6 @@ unsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { return Count; } - bool MSP430InstrInfo:: ReverseBranchCondition(SmallVectorImpl &Cond) const { assert(Cond.size() == 1 && "Invalid Xbranch condition!"); diff --git a/test/CodeGen/MSP430/Inst16mm.ll b/test/CodeGen/MSP430/Inst16mm.ll index 510afe37349..608dfc2a4c5 100644 --- a/test/CodeGen/MSP430/Inst16mm.ll +++ b/test/CodeGen/MSP430/Inst16mm.ll @@ -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 diff --git a/test/CodeGen/MSP430/Inst8mm.ll b/test/CodeGen/MSP430/Inst8mm.ll index a2987ac9b46..cc040a35873 100644 --- a/test/CodeGen/MSP430/Inst8mm.ll +++ b/test/CodeGen/MSP430/Inst8mm.ll @@ -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" -- 2.34.1