diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-15 22:16:39 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-08-15 22:16:39 +0000 |
commit | 2860b7ea3a1d60213ee7228bd274bc4f8b170772 (patch) | |
tree | b01f0e59fa7da8121848824f06495d6a0509f57c /lib/Target/ARM/ARMISelLowering.cpp | |
parent | 8dd2e5bf8331f55e099763bab2b95f7509649b84 (diff) | |
download | external_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.cpp | 48 |
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. |