mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[mips][microMIPS] Extending size reduction pass with XOR16
Author: milena.vujosevic.janicic Reviewers: sdardis The patch extends size reduction pass for MicroMIPS. XOR instruction is transformed into 16-bit instruction XOR16, if possible. Differential Revision: https://reviews.llvm.org/D34239 llvm-svn: 310579
This commit is contained in:
parent
f727f5bf00
commit
3a6251381a
@ -34,6 +34,7 @@ enum OperandTransfer {
|
||||
OT_OperandsAll, ///< Transfer all operands
|
||||
OT_Operands02, ///< Transfer operands 0 and 2
|
||||
OT_Operand2, ///< Transfer just operand 2
|
||||
OT_OperandsXOR, ///< Transfer operands for XOR16
|
||||
};
|
||||
|
||||
/// Reduction type
|
||||
@ -158,6 +159,10 @@ private:
|
||||
static bool ReduceADDIUToADDIUR1SP(MachineInstr *MI,
|
||||
const ReduceEntry &Entry);
|
||||
|
||||
// Attempts to reduce XOR into XOR16 instruction,
|
||||
// returns true on success.
|
||||
static bool ReduceXORtoXOR16(MachineInstr *MI, const ReduceEntry &Entry);
|
||||
|
||||
// Changes opcode of an instruction.
|
||||
static bool ReplaceInstruction(MachineInstr *MI, const ReduceEntry &Entry);
|
||||
|
||||
@ -221,7 +226,10 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
|
||||
OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
|
||||
{RT_OneInstr, OpCodes(Mips::SW_MM, Mips::SWSP_MM), ReduceXWtoXWSP,
|
||||
OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
|
||||
};
|
||||
{RT_OneInstr, OpCodes(Mips::XOR, Mips::XOR16_MM), ReduceXORtoXOR16,
|
||||
OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)},
|
||||
{RT_OneInstr, OpCodes(Mips::XOR_MM, Mips::XOR16_MM), ReduceXORtoXOR16,
|
||||
OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)}};
|
||||
} // namespace
|
||||
|
||||
// Returns true if the machine operand MO is register SP.
|
||||
@ -395,6 +403,20 @@ bool MicroMipsSizeReduce::ReduceSXtoSX16(MachineInstr *MI,
|
||||
return ReplaceInstruction(MI, Entry);
|
||||
}
|
||||
|
||||
bool MicroMipsSizeReduce::ReduceXORtoXOR16(MachineInstr *MI,
|
||||
const ReduceEntry &Entry) {
|
||||
if (!isMMThreeBitGPRegister(MI->getOperand(0)) ||
|
||||
!isMMThreeBitGPRegister(MI->getOperand(1)) ||
|
||||
!isMMThreeBitGPRegister(MI->getOperand(2)))
|
||||
return false;
|
||||
|
||||
if (!(MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) &&
|
||||
!(MI->getOperand(0).getReg() == MI->getOperand(1).getReg()))
|
||||
return false;
|
||||
|
||||
return ReplaceInstruction(MI, Entry);
|
||||
}
|
||||
|
||||
bool MicroMipsSizeReduce::ReduceMBB(MachineBasicBlock &MBB) {
|
||||
bool Modified = false;
|
||||
MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),
|
||||
@ -434,14 +456,30 @@ bool MicroMipsSizeReduce::ReplaceInstruction(MachineInstr *MI,
|
||||
const MCInstrDesc &NewMCID = MipsII->get(Entry.NarrowOpc());
|
||||
DebugLoc dl = MI->getDebugLoc();
|
||||
MachineInstrBuilder MIB = BuildMI(MBB, MI, dl, NewMCID);
|
||||
|
||||
if (OpTransfer == OT_Operand2)
|
||||
switch (OpTransfer) {
|
||||
case OT_Operand2:
|
||||
MIB.add(MI->getOperand(2));
|
||||
else if (OpTransfer == OT_Operands02) {
|
||||
break;
|
||||
case OT_Operands02: {
|
||||
MIB.add(MI->getOperand(0));
|
||||
MIB.add(MI->getOperand(2));
|
||||
} else
|
||||
break;
|
||||
}
|
||||
case OT_OperandsXOR: {
|
||||
if (MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) {
|
||||
MIB.add(MI->getOperand(0));
|
||||
MIB.add(MI->getOperand(1));
|
||||
MIB.add(MI->getOperand(2));
|
||||
} else {
|
||||
MIB.add(MI->getOperand(0));
|
||||
MIB.add(MI->getOperand(2));
|
||||
MIB.add(MI->getOperand(1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("Unknown operand transfer!");
|
||||
}
|
||||
|
||||
// Transfer MI flags.
|
||||
MIB.setMIFlags(MI->getFlags());
|
||||
|
14
test/CodeGen/Mips/micromips-sizereduction/micromips-xor16.ll
Normal file
14
test/CodeGen/Mips/micromips-sizereduction/micromips-xor16.ll
Normal file
@ -0,0 +1,14 @@
|
||||
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs < %s | FileCheck %s
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
define i1 @fun(i32 %a, i32 %b) {
|
||||
entry:
|
||||
; CHECK-LABEL: fun:
|
||||
; CHECK: xor16
|
||||
%reg1 = or i32 %a, %b
|
||||
%reg2 = xor i32 %reg1, -1
|
||||
%bool1 = icmp ne i32 %a, -1
|
||||
%bool1.ext = zext i1 %bool1 to i32
|
||||
%bool2 = icmp eq i32 %bool1.ext, %reg2
|
||||
ret i1 %bool2
|
||||
}
|
Loading…
Reference in New Issue
Block a user