aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-15 22:16:39 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-08-15 22:16:39 +0000
commit2860b7ea3a1d60213ee7228bd274bc4f8b170772 (patch)
treeb01f0e59fa7da8121848824f06495d6a0509f57c /lib/Target/ARM/ARMISelLowering.cpp
parent8dd2e5bf8331f55e099763bab2b95f7509649b84 (diff)
downloadexternal_llvm-2860b7ea3a1d60213ee7228bd274bc4f8b170772.zip
external_llvm-2860b7ea3a1d60213ee7228bd274bc4f8b170772.tar.gz
external_llvm-2860b7ea3a1d60213ee7228bd274bc4f8b170772.tar.bz2
Fold predicable instructions into MOVCC / t2MOVCC.
The ARM select instructions are just predicated moves. If the select is the only use of an operand, the instruction defining the operand can be predicated instead, saving one instruction and decreasing register pressure. This implementation can turn AND/ORR/EOR instructions into their corresponding ANDCC/ORRCC/EORCC variants. Ideally, we should be able to predicate any instruction, but we don't yet support predicated instructions in SSA form. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161994 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 77181cf..a0284e6 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -6762,6 +6762,54 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
return BB;
}
+ case ARM::MOVCCr:
+ case ARM::t2MOVCCr: {
+ // MOVCCr instructions can fold one of its operands as a predicated
+ // instruction:
+ //
+ // %v1 = AND %v2, %v3
+ // %v4 = MOVCCr %v5, %v1, CC
+ //
+ // Becomes:
+ //
+ // %v4 = ANDCCrr %v5, %v2, %v3, CC
+ //
+ const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
+ MachineInstr *DefMI = 0;
+ unsigned Opc = canFoldARMInstrIntoMOVCC(MI->getOperand(2).getReg(),
+ DefMI, MRI);
+ bool Invert = !Opc;
+ if (!Opc)
+ Opc = canFoldARMInstrIntoMOVCC(MI->getOperand(1).getReg(), DefMI, MRI);
+ if (!Opc)
+ return BB;
+
+ // Create a new predicated version of DefMI.
+ // Rfalse is the first use.
+ MachineInstrBuilder NewMI = BuildMI(*BB, MI, dl, TII->get(Opc),
+ MI->getOperand(0).getReg())
+ .addOperand(MI->getOperand(Invert ? 2 : 1));
+
+ // Copy all the DefMI operands, excluding its (null) predicate.
+ const MCInstrDesc &DefDesc = DefMI->getDesc();
+ for (unsigned i = 1, e = DefDesc.getNumOperands();
+ i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
+ NewMI.addOperand(DefMI->getOperand(i));
+
+ unsigned CondCode = MI->getOperand(3).getImm();
+ if (Invert)
+ NewMI.addImm(ARMCC::getOppositeCondition(ARMCC::CondCodes(CondCode)));
+ else
+ NewMI.addImm(CondCode);
+ NewMI.addOperand(MI->getOperand(4));
+
+ AddDefaultCC(NewMI);
+
+ DefMI->eraseFromParent();
+ MI->eraseFromParent();
+ return BB;
+ }
+
case ARM::BCCi64:
case ARM::BCCZi64: {
// If there is an unconditional branch to the other successor, remove it.