mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 07:34:45 +01:00
[PowerPC] refactor convertToImmediateForm - NFC
This is a NFC patch to make convertToImmediateForm a light wrapper for converting xform and imm form instructions on PowerPC. Reviewed By: Steven.zhang Differential Revision: https://reviews.llvm.org/D80907
This commit is contained in:
@@ -2643,7 +2643,6 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
|
||||
"The forwarding operand needs to be valid at this point");
|
||||
bool IsForwardingOperandKilled = MI.getOperand(ForwardingOperand).isKill();
|
||||
bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
|
||||
Register ForwardingOperandReg = MI.getOperand(ForwardingOperand).getReg();
|
||||
if (KilledDef && KillFwdDefMI)
|
||||
*KilledDef = DefMI;
|
||||
|
||||
@@ -2660,228 +2659,17 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
|
||||
KillFwdDefMI))
|
||||
return true;
|
||||
|
||||
if ((DefMI->getOpcode() != PPC::LI && DefMI->getOpcode() != PPC::LI8) ||
|
||||
!DefMI->getOperand(1).isImm())
|
||||
return false;
|
||||
|
||||
int64_t Immediate = DefMI->getOperand(1).getImm();
|
||||
// Sign-extend to 64-bits.
|
||||
int64_t SExtImm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ?
|
||||
(Immediate | 0xFFFFFFFFFFFF0000) : Immediate;
|
||||
|
||||
// If this is a reg+reg instruction that has a reg+imm form,
|
||||
// and one of the operands is produced by LI, convert it now.
|
||||
if (HasImmForm)
|
||||
return transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI, SExtImm);
|
||||
|
||||
bool ReplaceWithLI = false;
|
||||
bool Is64BitLI = false;
|
||||
int64_t NewImm = 0;
|
||||
bool SetCR = false;
|
||||
unsigned Opc = MI.getOpcode();
|
||||
switch (Opc) {
|
||||
default: return false;
|
||||
|
||||
// FIXME: Any branches conditional on such a comparison can be made
|
||||
// unconditional. At this time, this happens too infrequently to be worth
|
||||
// the implementation effort, but if that ever changes, we could convert
|
||||
// such a pattern here.
|
||||
case PPC::CMPWI:
|
||||
case PPC::CMPLWI:
|
||||
case PPC::CMPDI:
|
||||
case PPC::CMPLDI: {
|
||||
// Doing this post-RA would require dataflow analysis to reliably find uses
|
||||
// of the CR register set by the compare.
|
||||
// No need to fixup killed/dead flag since this transformation is only valid
|
||||
// before RA.
|
||||
if (PostRA)
|
||||
return false;
|
||||
// If a compare-immediate is fed by an immediate and is itself an input of
|
||||
// an ISEL (the most common case) into a COPY of the correct register.
|
||||
bool Changed = false;
|
||||
Register DefReg = MI.getOperand(0).getReg();
|
||||
int64_t Comparand = MI.getOperand(2).getImm();
|
||||
int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0 ?
|
||||
(Comparand | 0xFFFFFFFFFFFF0000) : Comparand;
|
||||
|
||||
for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
|
||||
unsigned UseOpc = CompareUseMI.getOpcode();
|
||||
if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
|
||||
continue;
|
||||
unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
|
||||
Register TrueReg = CompareUseMI.getOperand(1).getReg();
|
||||
Register FalseReg = CompareUseMI.getOperand(2).getReg();
|
||||
unsigned RegToCopy = selectReg(SExtImm, SExtComparand, Opc, TrueReg,
|
||||
FalseReg, CRSubReg);
|
||||
if (RegToCopy == PPC::NoRegister)
|
||||
continue;
|
||||
// Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.
|
||||
if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
|
||||
CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
|
||||
replaceInstrOperandWithImm(CompareUseMI, 1, 0);
|
||||
CompareUseMI.RemoveOperand(3);
|
||||
CompareUseMI.RemoveOperand(2);
|
||||
continue;
|
||||
}
|
||||
LLVM_DEBUG(
|
||||
dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
|
||||
LLVM_DEBUG(DefMI->dump(); MI.dump(); CompareUseMI.dump());
|
||||
LLVM_DEBUG(dbgs() << "Is converted to:\n");
|
||||
// Convert to copy and remove unneeded operands.
|
||||
CompareUseMI.setDesc(get(PPC::COPY));
|
||||
CompareUseMI.RemoveOperand(3);
|
||||
CompareUseMI.RemoveOperand(RegToCopy == TrueReg ? 2 : 1);
|
||||
CmpIselsConverted++;
|
||||
Changed = true;
|
||||
LLVM_DEBUG(CompareUseMI.dump());
|
||||
}
|
||||
if (Changed)
|
||||
return true;
|
||||
// This may end up incremented multiple times since this function is called
|
||||
// during a fixed-point transformation, but it is only meant to indicate the
|
||||
// presence of this opportunity.
|
||||
MissedConvertibleImmediateInstrs++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Immediate forms - may simply be convertable to an LI.
|
||||
case PPC::ADDI:
|
||||
case PPC::ADDI8: {
|
||||
// Does the sum fit in a 16-bit signed field?
|
||||
int64_t Addend = MI.getOperand(2).getImm();
|
||||
if (isInt<16>(Addend + SExtImm)) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc == PPC::ADDI8;
|
||||
NewImm = Addend + SExtImm;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case PPC::RLDICL:
|
||||
case PPC::RLDICL_rec:
|
||||
case PPC::RLDICL_32:
|
||||
case PPC::RLDICL_32_64: {
|
||||
// Use APInt's rotate function.
|
||||
int64_t SH = MI.getOperand(2).getImm();
|
||||
int64_t MB = MI.getOperand(3).getImm();
|
||||
APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec) ? 64 : 32,
|
||||
SExtImm, true);
|
||||
InVal = InVal.rotl(SH);
|
||||
uint64_t Mask = MB == 0 ? -1LLU : (1LLU << (63 - MB + 1)) - 1;
|
||||
InVal &= Mask;
|
||||
// Can't replace negative values with an LI as that will sign-extend
|
||||
// and not clear the left bits. If we're setting the CR bit, we will use
|
||||
// ANDI_rec which won't sign extend, so that's safe.
|
||||
if (isUInt<15>(InVal.getSExtValue()) ||
|
||||
(Opc == PPC::RLDICL_rec && isUInt<16>(InVal.getSExtValue()))) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc != PPC::RLDICL_32;
|
||||
NewImm = InVal.getSExtValue();
|
||||
SetCR = Opc == PPC::RLDICL_rec;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case PPC::RLWINM:
|
||||
case PPC::RLWINM8:
|
||||
case PPC::RLWINM_rec:
|
||||
case PPC::RLWINM8_rec: {
|
||||
int64_t SH = MI.getOperand(2).getImm();
|
||||
int64_t MB = MI.getOperand(3).getImm();
|
||||
int64_t ME = MI.getOperand(4).getImm();
|
||||
APInt InVal(32, SExtImm, true);
|
||||
InVal = InVal.rotl(SH);
|
||||
// Set the bits ( MB + 32 ) to ( ME + 32 ).
|
||||
uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
|
||||
InVal &= Mask;
|
||||
// Can't replace negative values with an LI as that will sign-extend
|
||||
// and not clear the left bits. If we're setting the CR bit, we will use
|
||||
// ANDI_rec which won't sign extend, so that's safe.
|
||||
bool ValueFits = isUInt<15>(InVal.getSExtValue());
|
||||
ValueFits |= ((Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec) &&
|
||||
isUInt<16>(InVal.getSExtValue()));
|
||||
if (ValueFits) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8_rec;
|
||||
NewImm = InVal.getSExtValue();
|
||||
SetCR = Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case PPC::ORI:
|
||||
case PPC::ORI8:
|
||||
case PPC::XORI:
|
||||
case PPC::XORI8: {
|
||||
int64_t LogicalImm = MI.getOperand(2).getImm();
|
||||
int64_t Result = 0;
|
||||
if (Opc == PPC::ORI || Opc == PPC::ORI8)
|
||||
Result = LogicalImm | SExtImm;
|
||||
else
|
||||
Result = LogicalImm ^ SExtImm;
|
||||
if (isInt<16>(Result)) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
|
||||
NewImm = Result;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ReplaceWithLI) {
|
||||
// We need to be careful with CR-setting instructions we're replacing.
|
||||
if (SetCR) {
|
||||
// We don't know anything about uses when we're out of SSA, so only
|
||||
// replace if the new immediate will be reproduced.
|
||||
bool ImmChanged = (SExtImm & NewImm) != NewImm;
|
||||
if (PostRA && ImmChanged)
|
||||
return false;
|
||||
|
||||
if (!PostRA) {
|
||||
// If the defining load-immediate has no other uses, we can just replace
|
||||
// the immediate with the new immediate.
|
||||
if (MRI->hasOneUse(DefMI->getOperand(0).getReg()))
|
||||
DefMI->getOperand(1).setImm(NewImm);
|
||||
|
||||
// If we're not using the GPR result of the CR-setting instruction, we
|
||||
// just need to and with zero/non-zero depending on the new immediate.
|
||||
else if (MRI->use_empty(MI.getOperand(0).getReg())) {
|
||||
if (NewImm) {
|
||||
assert(Immediate && "Transformation converted zero to non-zero?");
|
||||
NewImm = Immediate;
|
||||
}
|
||||
}
|
||||
else if (ImmChanged)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
LLVM_DEBUG(dbgs() << "Fed by:\n");
|
||||
LLVM_DEBUG(DefMI->dump());
|
||||
LoadImmediateInfo LII;
|
||||
LII.Imm = NewImm;
|
||||
LII.Is64Bit = Is64BitLI;
|
||||
LII.SetCR = SetCR;
|
||||
// If we're setting the CR, the original load-immediate must be kept (as an
|
||||
// operand to ANDI_rec/ANDI8_rec).
|
||||
if (KilledDef && SetCR)
|
||||
*KilledDef = nullptr;
|
||||
replaceInstrWithLI(MI, LII);
|
||||
|
||||
// Fixup killed/dead flag after transformation.
|
||||
// Pattern:
|
||||
// ForwardingOperandReg = LI imm1
|
||||
// y = op2 imm2, ForwardingOperandReg(killed)
|
||||
if (IsForwardingOperandKilled)
|
||||
fixupIsDeadOrKill(*DefMI, MI, ForwardingOperandReg);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "With:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
if (HasImmForm &&
|
||||
transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI))
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this is not a reg+reg, but the DefMI is LI/LI8, check if its user MI
|
||||
// can be simpified to LI.
|
||||
if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3496,6 +3284,236 @@ bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PPCInstrInfo::simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,
|
||||
unsigned OpNoForForwarding,
|
||||
MachineInstr **KilledDef) const {
|
||||
if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
|
||||
!DefMI.getOperand(1).isImm())
|
||||
return false;
|
||||
|
||||
MachineFunction *MF = MI.getParent()->getParent();
|
||||
MachineRegisterInfo *MRI = &MF->getRegInfo();
|
||||
bool PostRA = !MRI->isSSA();
|
||||
|
||||
int64_t Immediate = DefMI.getOperand(1).getImm();
|
||||
// Sign-extend to 64-bits.
|
||||
int64_t SExtImm = SignExtend64<16>(Immediate);
|
||||
|
||||
bool IsForwardingOperandKilled = MI.getOperand(OpNoForForwarding).isKill();
|
||||
Register ForwardingOperandReg = MI.getOperand(OpNoForForwarding).getReg();
|
||||
|
||||
bool ReplaceWithLI = false;
|
||||
bool Is64BitLI = false;
|
||||
int64_t NewImm = 0;
|
||||
bool SetCR = false;
|
||||
unsigned Opc = MI.getOpcode();
|
||||
switch (Opc) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
// FIXME: Any branches conditional on such a comparison can be made
|
||||
// unconditional. At this time, this happens too infrequently to be worth
|
||||
// the implementation effort, but if that ever changes, we could convert
|
||||
// such a pattern here.
|
||||
case PPC::CMPWI:
|
||||
case PPC::CMPLWI:
|
||||
case PPC::CMPDI:
|
||||
case PPC::CMPLDI: {
|
||||
// Doing this post-RA would require dataflow analysis to reliably find uses
|
||||
// of the CR register set by the compare.
|
||||
// No need to fixup killed/dead flag since this transformation is only valid
|
||||
// before RA.
|
||||
if (PostRA)
|
||||
return false;
|
||||
// If a compare-immediate is fed by an immediate and is itself an input of
|
||||
// an ISEL (the most common case) into a COPY of the correct register.
|
||||
bool Changed = false;
|
||||
Register DefReg = MI.getOperand(0).getReg();
|
||||
int64_t Comparand = MI.getOperand(2).getImm();
|
||||
int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0
|
||||
? (Comparand | 0xFFFFFFFFFFFF0000)
|
||||
: Comparand;
|
||||
|
||||
for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
|
||||
unsigned UseOpc = CompareUseMI.getOpcode();
|
||||
if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
|
||||
continue;
|
||||
unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
|
||||
Register TrueReg = CompareUseMI.getOperand(1).getReg();
|
||||
Register FalseReg = CompareUseMI.getOperand(2).getReg();
|
||||
unsigned RegToCopy =
|
||||
selectReg(SExtImm, SExtComparand, Opc, TrueReg, FalseReg, CRSubReg);
|
||||
if (RegToCopy == PPC::NoRegister)
|
||||
continue;
|
||||
// Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.
|
||||
if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
|
||||
CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
|
||||
replaceInstrOperandWithImm(CompareUseMI, 1, 0);
|
||||
CompareUseMI.RemoveOperand(3);
|
||||
CompareUseMI.RemoveOperand(2);
|
||||
continue;
|
||||
}
|
||||
LLVM_DEBUG(
|
||||
dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
|
||||
LLVM_DEBUG(DefMI.dump(); MI.dump(); CompareUseMI.dump());
|
||||
LLVM_DEBUG(dbgs() << "Is converted to:\n");
|
||||
// Convert to copy and remove unneeded operands.
|
||||
CompareUseMI.setDesc(get(PPC::COPY));
|
||||
CompareUseMI.RemoveOperand(3);
|
||||
CompareUseMI.RemoveOperand(RegToCopy == TrueReg ? 2 : 1);
|
||||
CmpIselsConverted++;
|
||||
Changed = true;
|
||||
LLVM_DEBUG(CompareUseMI.dump());
|
||||
}
|
||||
if (Changed)
|
||||
return true;
|
||||
// This may end up incremented multiple times since this function is called
|
||||
// during a fixed-point transformation, but it is only meant to indicate the
|
||||
// presence of this opportunity.
|
||||
MissedConvertibleImmediateInstrs++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Immediate forms - may simply be convertable to an LI.
|
||||
case PPC::ADDI:
|
||||
case PPC::ADDI8: {
|
||||
// Does the sum fit in a 16-bit signed field?
|
||||
int64_t Addend = MI.getOperand(2).getImm();
|
||||
if (isInt<16>(Addend + SExtImm)) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc == PPC::ADDI8;
|
||||
NewImm = Addend + SExtImm;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case PPC::RLDICL:
|
||||
case PPC::RLDICL_rec:
|
||||
case PPC::RLDICL_32:
|
||||
case PPC::RLDICL_32_64: {
|
||||
// Use APInt's rotate function.
|
||||
int64_t SH = MI.getOperand(2).getImm();
|
||||
int64_t MB = MI.getOperand(3).getImm();
|
||||
APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec) ? 64 : 32,
|
||||
SExtImm, true);
|
||||
InVal = InVal.rotl(SH);
|
||||
uint64_t Mask = MB == 0 ? -1LLU : (1LLU << (63 - MB + 1)) - 1;
|
||||
InVal &= Mask;
|
||||
// Can't replace negative values with an LI as that will sign-extend
|
||||
// and not clear the left bits. If we're setting the CR bit, we will use
|
||||
// ANDI_rec which won't sign extend, so that's safe.
|
||||
if (isUInt<15>(InVal.getSExtValue()) ||
|
||||
(Opc == PPC::RLDICL_rec && isUInt<16>(InVal.getSExtValue()))) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc != PPC::RLDICL_32;
|
||||
NewImm = InVal.getSExtValue();
|
||||
SetCR = Opc == PPC::RLDICL_rec;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case PPC::RLWINM:
|
||||
case PPC::RLWINM8:
|
||||
case PPC::RLWINM_rec:
|
||||
case PPC::RLWINM8_rec: {
|
||||
int64_t SH = MI.getOperand(2).getImm();
|
||||
int64_t MB = MI.getOperand(3).getImm();
|
||||
int64_t ME = MI.getOperand(4).getImm();
|
||||
APInt InVal(32, SExtImm, true);
|
||||
InVal = InVal.rotl(SH);
|
||||
// Set the bits ( MB + 32 ) to ( ME + 32 ).
|
||||
uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
|
||||
InVal &= Mask;
|
||||
// Can't replace negative values with an LI as that will sign-extend
|
||||
// and not clear the left bits. If we're setting the CR bit, we will use
|
||||
// ANDI_rec which won't sign extend, so that's safe.
|
||||
bool ValueFits = isUInt<15>(InVal.getSExtValue());
|
||||
ValueFits |= ((Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec) &&
|
||||
isUInt<16>(InVal.getSExtValue()));
|
||||
if (ValueFits) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8_rec;
|
||||
NewImm = InVal.getSExtValue();
|
||||
SetCR = Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case PPC::ORI:
|
||||
case PPC::ORI8:
|
||||
case PPC::XORI:
|
||||
case PPC::XORI8: {
|
||||
int64_t LogicalImm = MI.getOperand(2).getImm();
|
||||
int64_t Result = 0;
|
||||
if (Opc == PPC::ORI || Opc == PPC::ORI8)
|
||||
Result = LogicalImm | SExtImm;
|
||||
else
|
||||
Result = LogicalImm ^ SExtImm;
|
||||
if (isInt<16>(Result)) {
|
||||
ReplaceWithLI = true;
|
||||
Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
|
||||
NewImm = Result;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ReplaceWithLI) {
|
||||
// We need to be careful with CR-setting instructions we're replacing.
|
||||
if (SetCR) {
|
||||
// We don't know anything about uses when we're out of SSA, so only
|
||||
// replace if the new immediate will be reproduced.
|
||||
bool ImmChanged = (SExtImm & NewImm) != NewImm;
|
||||
if (PostRA && ImmChanged)
|
||||
return false;
|
||||
|
||||
if (!PostRA) {
|
||||
// If the defining load-immediate has no other uses, we can just replace
|
||||
// the immediate with the new immediate.
|
||||
if (MRI->hasOneUse(DefMI.getOperand(0).getReg()))
|
||||
DefMI.getOperand(1).setImm(NewImm);
|
||||
|
||||
// If we're not using the GPR result of the CR-setting instruction, we
|
||||
// just need to and with zero/non-zero depending on the new immediate.
|
||||
else if (MRI->use_empty(MI.getOperand(0).getReg())) {
|
||||
if (NewImm) {
|
||||
assert(Immediate && "Transformation converted zero to non-zero?");
|
||||
NewImm = Immediate;
|
||||
}
|
||||
} else if (ImmChanged)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
LLVM_DEBUG(dbgs() << "Fed by:\n");
|
||||
LLVM_DEBUG(DefMI.dump());
|
||||
LoadImmediateInfo LII;
|
||||
LII.Imm = NewImm;
|
||||
LII.Is64Bit = Is64BitLI;
|
||||
LII.SetCR = SetCR;
|
||||
// If we're setting the CR, the original load-immediate must be kept (as an
|
||||
// operand to ANDI_rec/ANDI8_rec).
|
||||
if (KilledDef && SetCR)
|
||||
*KilledDef = nullptr;
|
||||
replaceInstrWithLI(MI, LII);
|
||||
|
||||
// Fixup killed/dead flag after transformation.
|
||||
// Pattern:
|
||||
// ForwardingOperandReg = LI imm1
|
||||
// y = op2 imm2, ForwardingOperandReg(killed)
|
||||
if (IsForwardingOperandKilled)
|
||||
fixupIsDeadOrKill(DefMI, MI, ForwardingOperandReg);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "With:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// If an X-Form instruction is fed by an add-immediate and one of its operands
|
||||
// is the literal zero, attempt to forward the source of the add-immediate to
|
||||
// the corresponding D-Form instruction with the displacement coming from
|
||||
@@ -3615,8 +3633,15 @@ bool PPCInstrInfo::transformToImmFormFedByAdd(
|
||||
bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
|
||||
const ImmInstrInfo &III,
|
||||
unsigned ConstantOpNo,
|
||||
MachineInstr &DefMI,
|
||||
int64_t Imm) const {
|
||||
MachineInstr &DefMI) const {
|
||||
// DefMI must be LI or LI8.
|
||||
if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
|
||||
!DefMI.getOperand(1).isImm())
|
||||
return false;
|
||||
|
||||
// Get Imm operand and Sign-extend to 64-bits.
|
||||
int64_t Imm = SignExtend64<16>(DefMI.getOperand(1).getImm());
|
||||
|
||||
MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
|
||||
bool PostRA = !MRI.isSSA();
|
||||
// Exit early if we can't convert this.
|
||||
|
||||
@@ -187,13 +187,17 @@ class PPCInstrInfo : public PPCGenInstrInfo {
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr *> &NewMIs) const;
|
||||
|
||||
// If the inst has imm-form and one of its operand is produced by a LI,
|
||||
// put the imm into the inst directly and remove the LI if possible.
|
||||
// Replace the instruction with single LI if possible. \p DefMI must be LI or
|
||||
// LI8.
|
||||
bool simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,
|
||||
unsigned OpNoForForwarding, MachineInstr **KilledDef) const;
|
||||
// If the inst is x-form and has imm-form and one of its operand is produced
|
||||
// by a LI, put the imm into the inst directly and remove the LI if possible.
|
||||
bool transformToImmFormFedByLI(MachineInstr &MI, const ImmInstrInfo &III,
|
||||
unsigned ConstantOpNo, MachineInstr &DefMI,
|
||||
int64_t Imm) const;
|
||||
// If the inst has imm-form and one of its operand is produced by an
|
||||
// add-immediate, try to transform it when possible.
|
||||
unsigned ConstantOpNo,
|
||||
MachineInstr &DefMI) const;
|
||||
// If the inst is x-form and has imm-form and one of its operand is produced
|
||||
// by an add-immediate, try to transform it when possible.
|
||||
bool transformToImmFormFedByAdd(MachineInstr &MI, const ImmInstrInfo &III,
|
||||
unsigned ConstantOpNo, MachineInstr &DefMI,
|
||||
bool KillDefMI) const;
|
||||
|
||||
Reference in New Issue
Block a user