aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp13
-rw-r--r--lib/Target/ARM/NEONPreAllocPass.cpp28
2 files changed, 39 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 36a1827ce6e8..616942c00343 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -27,6 +27,7 @@
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -34,6 +35,10 @@
using namespace llvm;
+static cl::opt<bool>
+UseRegSeq("neon-reg-sequence", cl::Hidden,
+ cl::desc("Use reg_sequence to model ld / st of multiple neon regs"));
+
//===--------------------------------------------------------------------===//
/// ARMDAGToDAGISel - ARM specific code to select ARM machine
/// instructions for SelectionDAG operations.
@@ -939,10 +944,14 @@ SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) {
/// form a quad register.
SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) {
DebugLoc dl = V0.getNode()->getDebugLoc();
- SDValue Undef =
- SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0);
SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32);
SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32);
+ if (UseRegSeq) {
+ const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 };
+ return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4);
+ }
+ SDValue Undef =
+ SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0);
SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
VT, Undef, V0, SubReg0);
return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl,
diff --git a/lib/Target/ARM/NEONPreAllocPass.cpp b/lib/Target/ARM/NEONPreAllocPass.cpp
index 7334259bf574..ef6bf3a132bb 100644
--- a/lib/Target/ARM/NEONPreAllocPass.cpp
+++ b/lib/Target/ARM/NEONPreAllocPass.cpp
@@ -12,12 +12,14 @@
#include "ARMInstrInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
using namespace llvm;
namespace {
class NEONPreAllocPass : public MachineFunctionPass {
const TargetInstrInfo *TII;
+ MachineRegisterInfo *MRI;
public:
static char ID;
@@ -30,6 +32,8 @@ namespace {
}
private:
+ bool FormsRegSequence(MachineInstr *MI,
+ unsigned FirstOpnd, unsigned NumRegs);
bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
};
@@ -334,6 +338,27 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
return false;
}
+bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
+ unsigned FirstOpnd, unsigned NumRegs) {
+ MachineInstr *RegSeq = 0;
+ for (unsigned R = 0; R < NumRegs; ++R) {
+ MachineOperand &MO = MI->getOperand(FirstOpnd + R);
+ assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
+ unsigned VirtReg = MO.getReg();
+ assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
+ "expected a virtual register");
+ if (!MRI->hasOneNonDBGUse(VirtReg))
+ return false;
+ MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
+ if (UseMI->getOpcode() != TargetOpcode::REG_SEQUENCE)
+ return false;
+ if (RegSeq && RegSeq != UseMI)
+ return false;
+ RegSeq = UseMI;
+ }
+ return true;
+}
+
bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
bool Modified = false;
@@ -343,6 +368,8 @@ bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
unsigned FirstOpnd, NumRegs, Offset, Stride;
if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
continue;
+ if (FormsRegSequence(MI, FirstOpnd, NumRegs))
+ continue;
MachineBasicBlock::iterator NextI = llvm::next(MBBI);
for (unsigned R = 0; R < NumRegs; ++R) {
@@ -382,6 +409,7 @@ bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getTarget().getInstrInfo();
+ MRI = &MF.getRegInfo();
bool Modified = false;
for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;