mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-06 04:31:08 +00:00
Handle ARM MOVCC optimization in PeepholeOptimizer.
Use the target independent select analysis hooks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162060 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f2c64ef519
commit
053b5b0b3c
@ -1570,9 +1570,8 @@ ARMBaseInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
|
||||
|
||||
/// Identify instructions that can be folded into a MOVCC instruction, and
|
||||
/// return the corresponding opcode for the predicated pseudo-instruction.
|
||||
unsigned llvm::canFoldARMInstrIntoMOVCC(unsigned Reg,
|
||||
MachineInstr *&MI,
|
||||
const MachineRegisterInfo &MRI) {
|
||||
static unsigned canFoldIntoMOVCC(unsigned Reg, MachineInstr *&MI,
|
||||
const MachineRegisterInfo &MRI) {
|
||||
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||
return 0;
|
||||
if (!MRI.hasOneNonDBGUse(Reg))
|
||||
@ -1617,6 +1616,68 @@ unsigned llvm::canFoldARMInstrIntoMOVCC(unsigned Reg,
|
||||
}
|
||||
}
|
||||
|
||||
bool ARMBaseInstrInfo::analyzeSelect(const MachineInstr *MI,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
unsigned &TrueOp, unsigned &FalseOp,
|
||||
bool &Optimizable) const {
|
||||
assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
|
||||
"Unknown select instruction");
|
||||
// MOVCC operands:
|
||||
// 0: Def.
|
||||
// 1: True use.
|
||||
// 2: False use.
|
||||
// 3: Condition code.
|
||||
// 4: CPSR use.
|
||||
TrueOp = 1;
|
||||
FalseOp = 2;
|
||||
Cond.push_back(MI->getOperand(3));
|
||||
Cond.push_back(MI->getOperand(4));
|
||||
// We can always fold a def.
|
||||
Optimizable = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
MachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI,
|
||||
bool PreferFalse) const {
|
||||
assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
|
||||
"Unknown select instruction");
|
||||
const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
|
||||
MachineInstr *DefMI = 0;
|
||||
unsigned Opc = canFoldIntoMOVCC(MI->getOperand(2).getReg(), DefMI, MRI);
|
||||
bool Invert = !Opc;
|
||||
if (!Opc)
|
||||
Opc = canFoldIntoMOVCC(MI->getOperand(1).getReg(), DefMI, MRI);
|
||||
if (!Opc)
|
||||
return 0;
|
||||
|
||||
// Create a new predicated version of DefMI.
|
||||
// Rfalse is the first use.
|
||||
MachineInstrBuilder NewMI = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
|
||||
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));
|
||||
|
||||
// DefMI is not the -S version that sets CPSR, so add an optional %noreg.
|
||||
if (NewMI->hasOptionalDef())
|
||||
AddDefaultCC(NewMI);
|
||||
|
||||
// The caller will erase MI, but not DefMI.
|
||||
DefMI->eraseFromParent();
|
||||
return NewMI;
|
||||
}
|
||||
|
||||
/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether the
|
||||
/// instruction is encoded with an 'S' bit is determined by the optional CPSR
|
||||
/// def operand.
|
||||
|
@ -202,6 +202,13 @@ public:
|
||||
unsigned SrcReg2, int CmpMask, int CmpValue,
|
||||
const MachineRegisterInfo *MRI) const;
|
||||
|
||||
virtual bool analyzeSelect(const MachineInstr *MI,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
unsigned &TrueOp, unsigned &FalseOp,
|
||||
bool &Optimizable) const;
|
||||
|
||||
virtual MachineInstr *optimizeSelect(MachineInstr *MI, bool) const;
|
||||
|
||||
/// FoldImmediate - 'Reg' is known to be defined by a move immediate
|
||||
/// instruction, try to fold the immediate into the use instruction.
|
||||
virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
|
||||
|
@ -6762,54 +6762,6 @@ 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.
|
||||
|
@ -3939,7 +3939,7 @@ def BCCZi64 : PseudoInst<(outs),
|
||||
// a two-value operand where a dag node expects two operands. :(
|
||||
let neverHasSideEffects = 1 in {
|
||||
|
||||
let isCommutable = 1, usesCustomInserter = 1 in
|
||||
let isCommutable = 1, isSelect = 1 in
|
||||
def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p),
|
||||
4, IIC_iCMOVr,
|
||||
[/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
|
||||
|
@ -2938,7 +2938,7 @@ defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
|
||||
// a two-value operand where a dag node expects two operands. :(
|
||||
let neverHasSideEffects = 1 in {
|
||||
|
||||
let isCommutable = 1, usesCustomInserter = 1 in
|
||||
let isCommutable = 1, isSelect = 1 in
|
||||
def t2MOVCCr : t2PseudoInst<(outs rGPR:$Rd),
|
||||
(ins rGPR:$false, rGPR:$Rm, pred:$p),
|
||||
4, IIC_iCMOVr,
|
||||
|
Loading…
Reference in New Issue
Block a user