-
Notifications
You must be signed in to change notification settings - Fork 11.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promote the Pseudo Opcode of instructions that deduce the sign extension for extsw from 32 bits to 64 bits when eliminating the extsw instruction in PPCMIPeepholes optimization. #85451
base: main
Are you sure you want to change the base?
Changes from 3 commits
79aaf13
d4b4abc
affb9bf
75494c3
489cccc
1ece68c
56b04f5
692138b
95267f5
4482b29
8e98ab8
9b0b9c8
8550317
9a4e4d0
3798b03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5234,6 +5234,218 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const { | |
// We limit the max depth to track incoming values of PHIs or binary ops | ||
// (e.g. AND) to avoid excessive cost. | ||
const unsigned MAX_BINOP_DEPTH = 1; | ||
|
||
void PPCInstrInfo::replaceInstrAfterElimExt32To64(const Register &Reg, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a comment to describe this function. |
||
MachineRegisterInfo *MRI, | ||
unsigned BinOpDepth, | ||
LiveVariables *LV) const { | ||
MachineInstr *MI = MRI->getVRegDef(Reg); | ||
if (!MI) | ||
return; | ||
|
||
unsigned Opcode = MI->getOpcode(); | ||
bool IsReplaceInstr = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we update the name of this variable? Something like |
||
int NewOpcode = -1; | ||
|
||
auto SetNewOpcode = [&](int NewOpc) { | ||
if (!IsReplaceInstr) { | ||
NewOpcode = NewOpc; | ||
IsReplaceInstr = true; | ||
} | ||
}; | ||
|
||
switch (Opcode) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are all the cases for opcode switch statements in PromoteInstr32To64ForEmliEXTSW coming from the union of definedBySignExtendingOp() and isSignExtended()/isSignOrZeroExtended()? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes,
--> --> |
||
case PPC::OR: | ||
SetNewOpcode(PPC::OR8); | ||
[[fallthrough]]; | ||
case PPC::ISEL: | ||
SetNewOpcode(PPC::ISEL8); | ||
[[fallthrough]]; | ||
case PPC::OR8: | ||
case PPC::PHI: | ||
if (BinOpDepth < MAX_BINOP_DEPTH) { | ||
unsigned OperandEnd = 3, OperandStride = 1; | ||
if (Opcode == PPC::PHI) { | ||
OperandEnd = MI->getNumOperands(); | ||
OperandStride = 2; | ||
} | ||
|
||
for (unsigned I = 1; I != OperandEnd; I += OperandStride) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better to use |
||
assert(MI->getOperand(I).isReg() && "Operand must be register"); | ||
Register SrcReg = MI->getOperand(I).getReg(); | ||
replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth + 1, LV); | ||
} | ||
|
||
if (!IsReplaceInstr) | ||
return; | ||
} | ||
break; | ||
case PPC::COPY: { | ||
Register SrcReg = MI->getOperand(1).getReg(); | ||
const MachineFunction *MF = MI->getMF(); | ||
if (!MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should copy the explanation comments for these conditions from |
||
replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth, LV); | ||
return; | ||
} | ||
// From here on everything is SVR4ABI | ||
if (MI->getParent()->getBasicBlock() == &MF->getFunction().getEntryBlock()) | ||
return; | ||
|
||
if (SrcReg != PPC::X3) { | ||
replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth, LV); | ||
return; | ||
} | ||
} | ||
return; | ||
case PPC::ORI: | ||
SetNewOpcode(PPC::ORI8); | ||
[[fallthrough]]; | ||
case PPC::XORI: | ||
SetNewOpcode(PPC::XORI8); | ||
[[fallthrough]]; | ||
case PPC::ORIS: | ||
SetNewOpcode(PPC::ORIS8); | ||
[[fallthrough]]; | ||
case PPC::XORIS: | ||
SetNewOpcode(PPC::XORIS8); | ||
[[fallthrough]]; | ||
case PPC::ORI8: | ||
case PPC::XORI8: | ||
case PPC::ORIS8: | ||
case PPC::XORIS8: { | ||
Register SrcReg = MI->getOperand(1).getReg(); | ||
replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth, LV); | ||
|
||
if (!IsReplaceInstr) | ||
return; | ||
break; | ||
} | ||
case PPC::AND: | ||
SetNewOpcode(PPC::AND8); | ||
[[fallthrough]]; | ||
case PPC::AND8: { | ||
if (BinOpDepth < MAX_BINOP_DEPTH) { | ||
Register SrcReg1 = MI->getOperand(1).getReg(); | ||
replaceInstrAfterElimExt32To64(SrcReg1, MRI, BinOpDepth, LV); | ||
Register SrcReg2 = MI->getOperand(2).getReg(); | ||
replaceInstrAfterElimExt32To64(SrcReg2, MRI, BinOpDepth, LV); | ||
if (!IsReplaceInstr) | ||
return; | ||
} | ||
break; | ||
} | ||
case PPC::RLWINM: | ||
SetNewOpcode(PPC::RLWINM8); | ||
break; | ||
case PPC::RLWINM_rec: | ||
SetNewOpcode(PPC::RLWINM8_rec); | ||
break; | ||
case PPC::RLWNM: | ||
SetNewOpcode(PPC ::RLWNM8); | ||
break; | ||
case PPC::RLWNM_rec: | ||
SetNewOpcode(PPC::RLWNM8_rec); | ||
break; | ||
case PPC::ANDC_rec: | ||
SetNewOpcode(PPC::ANDC8_rec); | ||
break; | ||
case PPC::ANDIS_rec: | ||
SetNewOpcode(PPC::ANDIS8_rec); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
amy-kwan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const PPCInstrInfo *TII = | ||
MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo(); | ||
amy-kwan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if ((definedBySignExtendingOp(Reg, MRI) && !TII->isZExt32To64(Opcode) && | ||
!isOpZeroOfSubwordPreincLoad(Opcode)) || | ||
IsReplaceInstr) { | ||
|
||
const TargetRegisterClass *RC = MRI->getRegClass(Reg); | ||
|
||
if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass) | ||
return; | ||
|
||
if (!IsReplaceInstr) | ||
NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode); | ||
|
||
assert(NewOpcode != -1 && | ||
"Must have a 64-bit opcode to map the 32-bit opcode!"); | ||
|
||
const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo(); | ||
const MCInstrDesc &MCID = TII->get(NewOpcode); | ||
|
||
Register SrcReg = MI->getOperand(0).getReg(); | ||
const TargetRegisterClass *NewRC = | ||
TRI->getRegClass(MCID.operands()[0].RegClass); | ||
const TargetRegisterClass *SrcRC = MRI->getRegClass(SrcReg); | ||
|
||
if (NewRC == SrcRC) | ||
return; | ||
|
||
DebugLoc DL = MI->getDebugLoc(); | ||
auto MBB = MI->getParent(); | ||
|
||
// Since the pseudo-opcode of the instruction is promoted from 32-bit to | ||
// 64-bit, if the operand of the original instruction belongs to | ||
// PPC::GRCRegClass or PPC::GPRC_and_GPRC_NOR0RegClass, we need to promote | ||
// the operand to PPC::G8CRegClass or PPC::G8RC_and_G8RC_NOR0RegClass, | ||
// respectively. | ||
DenseMap<unsigned, Register> PromoteRegs; | ||
DenseMap<unsigned, Register> ReCalRegs; | ||
for (unsigned i = 1; i < MI->getNumOperands(); i++) { | ||
MachineOperand &Operand = MI->getOperand(i); | ||
if (Operand.isReg()) { | ||
Register OperandReg = Operand.getReg(); | ||
if (!OperandReg.isVirtual()) | ||
continue; | ||
|
||
const TargetRegisterClass *RC = | ||
TRI->getRegClass(MCID.operands()[i].RegClass); | ||
const TargetRegisterClass *OrgRC = MRI->getRegClass(OperandReg); | ||
if (RC != MRI->getRegClass(OperandReg) && | ||
(OrgRC == &PPC::GPRCRegClass || | ||
OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) { | ||
Register TmpReg = MRI->createVirtualRegister(RC); | ||
Register DstTmpReg = MRI->createVirtualRegister(RC); | ||
BuildMI(*MBB, MI, DL, TII->get(PPC::IMPLICIT_DEF), TmpReg); | ||
BuildMI(*MBB, MI, DL, TII->get(PPC::INSERT_SUBREG), DstTmpReg) | ||
.addReg(TmpReg) | ||
.addReg(OperandReg) | ||
.addImm(PPC::sub_32); | ||
PromoteRegs[i] = DstTmpReg; | ||
ReCalRegs[i] = DstTmpReg; | ||
} else { | ||
ReCalRegs[i] = OperandReg; | ||
} | ||
} | ||
} | ||
|
||
Register NewReg = MRI->createVirtualRegister(NewRC); | ||
|
||
BuildMI(*MBB, MI, DL, TII->get(NewOpcode), NewReg); | ||
MachineBasicBlock::instr_iterator Iter(MI); | ||
--Iter; | ||
for (unsigned i = 1; i < MI->getNumOperands(); i++) | ||
if (PromoteRegs.find(i) != PromoteRegs.end()) | ||
MachineInstrBuilder(*Iter->getMF(), Iter) | ||
.addReg(PromoteRegs[i], RegState::Kill); | ||
else | ||
Iter->addOperand(MI->getOperand(i)); | ||
|
||
for (auto Iter = ReCalRegs.begin(); Iter != ReCalRegs.end(); Iter++) | ||
LV->recomputeForSingleDefVirtReg(Iter->second); | ||
MI->eraseFromParent(); | ||
|
||
BuildMI(*MBB, ++Iter, DL, TII->get(PPC::COPY), SrcReg) | ||
.addReg(NewReg, RegState::Kill, PPC::sub_32); | ||
LV->recomputeForSingleDefVirtReg(NewReg); | ||
return; | ||
} | ||
return; | ||
} | ||
|
||
// The isSignOrZeroExtended function is recursive. The parameter BinOpDepth | ||
// does not count all of the recursions. The parameter BinOpDepth is incremented | ||
// only when isSignOrZeroExtended calls itself more than once. This is done to | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1051,6 +1051,7 @@ bool PPCMIPeephole::simplifyCode() { | |
TII->isSignExtended(NarrowReg, MRI)) { | ||
// We can eliminate EXTSW if the input is known to be already | ||
// sign-extended. | ||
TII->replaceInstrAfterElimExt32To64(NarrowReg, MRI, 0, LV); | ||
kamaub marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A couple comments regarding this line:
|
||
LLVM_DEBUG(dbgs() << "Removing redundant sign-extension\n"); | ||
Register TmpReg = | ||
MF->getRegInfo().createVirtualRegister(&PPC::G8RCRegClass); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "form a column" mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
means we will deal with the instruction which only has flag
SExt32To64
means that if two instruction has the same Pseduo Opcode will be on the same row.
means that the instruction for 64bit is one column, 32-bit is another column.
it will generate something like this