Changeset View
Standalone View
llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
Show First 20 Lines • Show All 3,225 Lines • ▼ Show 20 Lines | bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI, | ||||
// If this is not a reg+reg, but the DefMI is LI/LI8, check if its user MI | // If this is not a reg+reg, but the DefMI is LI/LI8, check if its user MI | ||||
// can be simpified to LI. | // can be simpified to LI. | ||||
if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef)) | if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef)) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
} | } | ||||
bool PPCInstrInfo::combineRLWINM(MachineInstr &MI, | // This function tries to combine two RLWINMs. We not only perform such | ||||
MachineInstr **ToErase) const { | // optimization in SSA, but also after RA, since some RLWINM is generated after | ||||
// RA. | |||||
bool PPCInstrInfo::simplifyRotateAndMaskInstr(MachineInstr &MI, | |||||
MachineInstr *&ToErase) const { | |||||
steven.zhang: How about use the MachineInstr *&ToErase to avoid the null check and default arguments ? | |||||
bool Is64Bit = false; | |||||
Not Done ReplyInline ActionsCan we initial Is64Bit to true or false and then we only need to handle 32-bit or 64-bit opcodes in following switch? shchenz: Can we initial Is64Bit to true or false and then we only need to handle 32-bit or 64-bit… | |||||
switch (MI.getOpcode()) { | |||||
case PPC::RLWINM: | |||||
case PPC::RLWINM_rec: | |||||
break; | |||||
case PPC::RLWINM8: | |||||
case PPC::RLWINM8_rec: | |||||
Is64Bit = true; | |||||
break; | |||||
default: | |||||
return false; | |||||
} | |||||
Not Done ReplyInline ActionsComments need to be updated. steven.zhang: Comments need to be updated. | |||||
Not Done ReplyInline ActionsThe strange character before "We" shchenz: The strange character before "We" | |||||
MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo(); | MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo(); | ||||
unsigned FoldingReg = MI.getOperand(1).getReg(); | Register FoldingReg = MI.getOperand(1).getReg(); | ||||
MachineInstr *SrcMI = nullptr; | |||||
It is preferred to initialize the stack variable. steven.zhang: It is preferred to initialize the stack variable. | |||||
bool CanErase = false; | |||||
Remove such kind of comments as the code is self explained. steven.zhang: Remove such kind of comments as the code is self explained. | |||||
bool OtherIntermediateUse = true; | |||||
if (MRI->isSSA()) { | |||||
if (!Register::isVirtualRegister(FoldingReg)) | if (!Register::isVirtualRegister(FoldingReg)) | ||||
return false; | return false; | ||||
MachineInstr *SrcMI = MRI->getVRegDef(FoldingReg); | SrcMI = MRI->getVRegDef(FoldingReg); | ||||
Common line 3209 and 3217 then, add a check in 3220 steven.zhang: Common line 3209 and 3217 then, add a check in 3220 | |||||
if (SrcMI->getOpcode() != PPC::RLWINM && | } else { | ||||
Not Done ReplyInline ActionsThis is redundant or can be changed to an assert? shchenz: This is redundant or can be changed to an assert? | |||||
lkailUnsubmitted Not Done ReplyInline ActionsI suggest checking Register::isPhysicalRegister explicitly, since Reg might also be a stackslot. lkail: I suggest checking `Register::isPhysicalRegister` explicitly, since `Reg` might also be a… | |||||
shchenzUnsubmitted Not Done ReplyInline ActionsCould you please explain more here? this is after RA, if FoldingReg is a stackslot, we should get r1/x1? I don't understand how Register::isPhysicalRegister would change the semantic here? Thanks. shchenz: Could you please explain more here? this is after RA, if `FoldingReg` is a stackslot, we should… | |||||
lkailUnsubmitted Not Done ReplyInline ActionsIf it's the case, an assertion here would be better. lkail: If it's the case, an assertion here would be better. | |||||
SrcMI->getOpcode() != PPC::RLWINM_rec && | SrcMI = getDefMIPostRA(FoldingReg, MI, OtherIntermediateUse); | ||||
SrcMI->getOpcode() != PPC::RLWINM8 && | } | ||||
SrcMI->getOpcode() != PPC::RLWINM8_rec) | if (!SrcMI) | ||||
Not Done ReplyInline ActionsAny special reason that we don't do the folding after RA when there are multiple uses for SrcMI? Before RA, we do such kind of transformation as it is still benefit. We eliminate the dependancy between SrcMI and MI. shchenz: Any special reason that we don't do the folding after RA when there are multiple uses for SrcMI? | |||||
return false; | return false; | ||||
// TODO: The pairs of RLWINM8(RLWINM) or RLWINM(RLWINM8) never occur before | |||||
// RA, but after RA. And We can fold RLWINM8(RLWINM) -> RLWINM8, or | |||||
// RLWINM(RLWINM8) -> RLWINM. | |||||
switch (SrcMI->getOpcode()) { | |||||
Not Done ReplyInline ActionsWhat case will have rlwinm input is rlwinm8 or rlwinm8 input is rlwinm? Just curious. shchenz: What case will have rlwinm input is rlwinm8 or rlwinm8 input is rlwinm? Just curious. | |||||
There is a case in llvm/test/CodeGen/PowerPC/popcnt-zext.ll declare i16 @llvm.ctpop.i16(i16) nounwind readnone define i64 @popa_i16_i64(i16 %x) { %pop = call i16 @llvm.ctpop.i16(i16 %x) %z = zext i16 %pop to i64 ; SimplifyDemandedBits may turn zext (or sext) into aext %a = and i64 %z, 16 ret i64 %a } llc -verify-machineinstrs -mtriple=powerpc64-- -mattr=+slow-popcntd < cnt16.ll -debug 368B %22:gprc = RLWINM %21:gprc, 8, 24, 31 384B undef %23.sub_32:g8rc = COPY %22:gprc 400B %25:g8rc = RLWINM8 %23:g8rc, 0, 27, 27 416B $x3 = COPY %25:g8rc To undef %23.sub_32:g8rc = RLWINM %21:gprc, 8, 24, 31 %25:g8rc = RLWINM8 %23:g8rc, 0, 27, 27 $x3 = COPY %25:g8rc After RA renamable $r3 = RLWINM killed renamable $r3, 8, 24, 31, implicit-def $x3 renamable $x3 = RLWINM8 killed renamable $x3, 0, 27, 27 We will treat them as DefMI and MI after RA, but they shouldn't be folded. Please correct me if I'm wrong. Esme: There is a case in llvm/test/CodeGen/PowerPC/popcnt-zext.ll
```
declare i16 @llvm.ctpop.i16… | |||||
Not Done ReplyInline ActionsThanks, I see, this is just a post-ra issue. Before RA, there are always register copy instructions between RLWINM and RLWINM8. After Post-RA, shchenz: Thanks, I see, this is just a post-ra issue. Before RA, there are always register copy… | |||||
Thanks! I will mark this as a follow-up work after this patch submitted. Esme: Thanks! I will mark this as a follow-up work after this patch submitted. | |||||
Not Done ReplyInline Actionssounds good to me. shchenz: sounds good to me. | |||||
Not Done ReplyInline ActionsThis is a bit of a bizarre set up that makes it hard to read. How about skipping these switch statements and just doing what you're after:
For 2. you can do something like: static bool sameWidthRLWINM(MachineInstr *SrcMI, MachineInstr *UseMI, bool &Is64Bit) { unsigned SrcOpc = SrcMI->getOpcode(); unsigned UseOpc = UseMI->getOpcode(); if ((SrcOpc == PPC::RLWINM8 || SrcOpc == PPC::RLWINM8_rec) && (UseOpc == PPC::RLWINM8 || UseOpc == PPC::RLWINM8_rec)) { Is64Bit = true; return true; } if ((SrcOpc == PPC::RLWINM || SrcOpc == PPC::RLWINM_rec) && (UseOpc == PPC::RLWINM || UseOpc == PPC::RLWINM_rec)) return true; Is64Bit = false; return false; } nemanjai: This is a bit of a bizarre set up that makes it hard to read. How about skipping these switch… | |||||
case PPC::RLWINM: | |||||
A better code style to avoid the duplicate check of the SrcOpCode. switch (SrcOpCode) { case RLWINM8 case RLWINM8_rec: Is64Bit = true; break; case ... } steven.zhang: A better code style to avoid the duplicate check of the SrcOpCode.
```
switch (SrcOpCode) {… | |||||
case PPC::RLWINM_rec: | |||||
if (Is64Bit) | |||||
return false; | |||||
break; | |||||
case PPC::RLWINM8: | |||||
case PPC::RLWINM8_rec: | |||||
if (!Is64Bit) | |||||
return false; | |||||
break; | |||||
default: | |||||
return false; | |||||
} | |||||
if (MRI->isSSA()) { | |||||
CanErase = !SrcMI->hasImplicitDef() && MRI->hasOneNonDBGUse(FoldingReg); | |||||
} else { | |||||
CanErase = !OtherIntermediateUse && MI.getOperand(1).isKill() && | |||||
!SrcMI->hasImplicitDef(); | |||||
// In post-RA, if SrcMI also defines the register to be forwarded, we can | |||||
// only do the folding if SrcMI is going to be erased. | |||||
if (!CanErase && SrcMI->definesRegister(SrcMI->getOperand(1).getReg())) | |||||
lkailUnsubmitted Not Done ReplyInline ActionsSuggest using modifiesRegister or it'll miss case like $x3 = rlwinm $r3, ... lkail: Suggest using `modifiesRegister` or it'll miss case like `$x3 = rlwinm $r3, ...` | |||||
shchenzUnsubmitted Not Done ReplyInline ActionsThat would not happen, for RLWINM, we get input and output are both r3, for RLWINM8 we get input and output are both x3. shchenz: That would not happen, for `RLWINM`, we get input and output are both r3, for `RLWINM8` we get… | |||||
return false; | |||||
} | |||||
assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() && | assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() && | ||||
MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() && | MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() && | ||||
SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) && | SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) && | ||||
"Invalid PPC::RLWINM Instruction!"); | "Invalid PPC::RLWINM Instruction!"); | ||||
uint64_t SHSrc = SrcMI->getOperand(2).getImm(); | uint64_t SHSrc = SrcMI->getOperand(2).getImm(); | ||||
uint64_t SHMI = MI.getOperand(2).getImm(); | uint64_t SHMI = MI.getOperand(2).getImm(); | ||||
uint64_t MBSrc = SrcMI->getOperand(3).getImm(); | uint64_t MBSrc = SrcMI->getOperand(3).getImm(); | ||||
uint64_t MBMI = MI.getOperand(3).getImm(); | uint64_t MBMI = MI.getOperand(3).getImm(); | ||||
uint64_t MESrc = SrcMI->getOperand(4).getImm(); | uint64_t MESrc = SrcMI->getOperand(4).getImm(); | ||||
uint64_t MEMI = MI.getOperand(4).getImm(); | uint64_t MEMI = MI.getOperand(4).getImm(); | ||||
assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) && | assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) && | ||||
"Invalid PPC::RLWINM Instruction!"); | "Invalid PPC::RLWINM Instruction!"); | ||||
// If MBMI is bigger than MEMI, we always can not get run of ones. | // If MBMI is bigger than MEMI, we always can not get run of ones. | ||||
// RotatedSrcMask non-wrap: | // RotatedSrcMask non-wrap: | ||||
// 0........31|32........63 | // 0........31|32........63 | ||||
// RotatedSrcMask: B---E B---E | // RotatedSrcMask: B---E B---E | ||||
// MaskMI: -----------|--E B------ | // MaskMI: -----------|--E B------ | ||||
// Result: ----- --- (Bad candidate) | // Result: ----- --- (Bad candidate) | ||||
// | // | ||||
Not Done ReplyInline ActionsCan these lines be moved after line 3221? So we will bail out early. shchenz: Can these lines be moved after line 3221? So we will bail out early. | |||||
It's safe to call SrcMI->getOperand(1).getReg() after filtering the opcode of SrcMI. Esme: It's safe to call `SrcMI->getOperand(1).getReg()` after filtering the opcode of SrcMI. | |||||
Not Done ReplyInline ActionsIs it safe if we add SrcMI->getOperand(1).isReg()?. We can bail out early if the operand 1 of SrcMI is not a register. shchenz: Is it safe if we add `SrcMI->getOperand(1).isReg()`?. We can bail out early if the operand 1 of… | |||||
// RotatedSrcMask wrap: | // RotatedSrcMask wrap: | ||||
// 0........31|32........63 | // 0........31|32........63 | ||||
// RotatedSrcMask: --E B----|--E B---- | // RotatedSrcMask: --E B----|--E B---- | ||||
// MaskMI: -----------|--E B------ | // MaskMI: -----------|--E B------ | ||||
// Result: --- -----|--- ----- (Bad candidate) | // Result: --- -----|--- ----- (Bad candidate) | ||||
// | // | ||||
// One special case is RotatedSrcMask is a full set mask. | // One special case is RotatedSrcMask is a full set mask. | ||||
// RotatedSrcMask full: | // RotatedSrcMask full: | ||||
// 0........31|32........63 | // 0........31|32........63 | ||||
// RotatedSrcMask: ------EB---|-------EB--- | // RotatedSrcMask: ------EB---|-------EB--- | ||||
// MaskMI: -----------|--E B------ | // MaskMI: -----------|--E B------ | ||||
// Result: -----------|--- ------- (Good candidate) | // Result: -----------|--- ------- (Good candidate) | ||||
// Mark special case. | // Mark special case. | ||||
bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31); | bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31); | ||||
Not Done ReplyInline ActionsPlease describe this "special case" since it appears to be two special cases: nemanjai: Please describe this "special case" since it appears to be two special cases:
The first part… | |||||
// For other MBMI > MEMI cases, just return. | // For other MBMI > MEMI cases, just return. | ||||
if ((MBMI > MEMI) && !SrcMaskFull) | if ((MBMI > MEMI) && !SrcMaskFull) | ||||
return false; | return false; | ||||
// Handle MBMI <= MEMI cases. | // Handle MBMI <= MEMI cases. | ||||
APInt MaskMI = APInt::getBitsSetWithWrap(32, 32 - MEMI - 1, 32 - MBMI); | APInt MaskMI = APInt::getBitsSetWithWrap(32, 32 - MEMI - 1, 32 - MBMI); | ||||
// In MI, we only need low 32 bits of SrcMI, just consider about low 32 | // In MI, we only need low 32 bits of SrcMI, just consider about low 32 | ||||
// bit of SrcMI mask. Note that in APInt, lowerest bit is at index 0, | // bit of SrcMI mask. Note that in APInt, lowerest bit is at index 0, | ||||
Not Done ReplyInline ActionsI am not sure what the intended meaning of lowerest is here, but please use something like least significant bit. nemanjai: I am not sure what the intended meaning of `lowerest` is here, but please use something like… | |||||
// while in PowerPC ISA, lowerest bit is at index 63. | // while in PowerPC ISA, lowerest bit is at index 63. | ||||
APInt MaskSrc = APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc); | APInt MaskSrc = APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc); | ||||
APInt RotatedSrcMask = MaskSrc.rotl(SHMI); | APInt RotatedSrcMask = MaskSrc.rotl(SHMI); | ||||
APInt FinalMask = RotatedSrcMask & MaskMI; | APInt FinalMask = RotatedSrcMask & MaskMI; | ||||
uint32_t NewMB, NewME; | uint32_t NewMB, NewME; | ||||
bool Simplified = false; | bool Simplified = false; | ||||
// If final mask is 0, MI result should be 0 too. | // If final mask is 0, MI result should be 0 too. | ||||
if (FinalMask.isNullValue()) { | if (FinalMask.isNullValue()) { | ||||
bool Is64Bit = | |||||
(MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec); | |||||
Simplified = true; | Simplified = true; | ||||
Not Done ReplyInline ActionsWhy can't this whole block be replaced by a call to replaceInstrWithLI()? nemanjai: Why can't this whole block be replaced by a call to `replaceInstrWithLI()`? | |||||
LLVM_DEBUG(dbgs() << "Replace Instr: "); | LLVM_DEBUG(dbgs() << "Replace Instr: "); | ||||
LLVM_DEBUG(MI.dump()); | LLVM_DEBUG(MI.dump()); | ||||
if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) { | if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) { | ||||
// Replace MI with "LI 0" | // Replace MI with "LI 0" | ||||
MI.RemoveOperand(4); | MI.RemoveOperand(4); | ||||
MI.RemoveOperand(3); | MI.RemoveOperand(3); | ||||
MI.RemoveOperand(2); | MI.RemoveOperand(2); | ||||
Show All 12 Lines | if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) { | ||||
} else | } else | ||||
// About to replace MI.getOperand(1), clear its kill flag. | // About to replace MI.getOperand(1), clear its kill flag. | ||||
MI.getOperand(1).setIsKill(false); | MI.getOperand(1).setIsKill(false); | ||||
} | } | ||||
LLVM_DEBUG(dbgs() << "With: "); | LLVM_DEBUG(dbgs() << "With: "); | ||||
LLVM_DEBUG(MI.dump()); | LLVM_DEBUG(MI.dump()); | ||||
} else if ((isRunOfOnes((unsigned)(FinalMask.getZExtValue()), NewMB, NewME) && | } else if ((isRunOfOnes((unsigned)(FinalMask.getZExtValue()), NewMB, NewME) && | ||||
Not Done ReplyInline ActionsI find it unlikely that clang-format produced this formatting. nemanjai: I find it unlikely that `clang-format` produced this formatting. | |||||
NewMB <= NewME) || | NewMB <= NewME) || | ||||
SrcMaskFull) { | SrcMaskFull) { | ||||
// Here we only handle MBMI <= MEMI case, so NewMB must be no bigger | // Here we only handle MBMI <= MEMI case, so NewMB must be no bigger | ||||
// than NewME. Otherwise we get a 64 bit value after folding, but MI | // than NewME. Otherwise we get a 64 bit value after folding, but MI | ||||
// return a 32 bit value. | // return a 32 bit value. | ||||
Simplified = true; | Simplified = true; | ||||
LLVM_DEBUG(dbgs() << "Converting Instr: "); | LLVM_DEBUG(dbgs() << "Converting Instr: "); | ||||
LLVM_DEBUG(MI.dump()); | LLVM_DEBUG(MI.dump()); | ||||
uint16_t NewSH = (SHSrc + SHMI) % 32; | uint16_t NewSH = (SHSrc + SHMI) % 32; | ||||
MI.getOperand(2).setImm(NewSH); | MI.getOperand(2).setImm(NewSH); | ||||
// If SrcMI mask is full, no need to update MBMI and MEMI. | // If SrcMI mask is full, no need to update MBMI and MEMI. | ||||
Not Done ReplyInline ActionsNo need, but is it incorrect to update them? Namely, won't the NewMB/NewME be the same as MBMI/MEMI respectively? If so, I think it is preferable to avoid the condition and leave it to the reader to figure out. nemanjai: No need, but is it incorrect to update them? Namely, won't the `NewMB/NewME` be the same as… | |||||
It's incorrect to update MBMI/MEMI with NewMB/NewME if the SrcMI mask is full, since isRunOfOnes(FinalMask) may not hold true in such scenario. Well might it be more clear to replace no need with don't? Esme: It's incorrect to update MBMI/MEMI with NewMB/NewME if the SrcMI mask is full, since… | |||||
if (!SrcMaskFull) { | if (!SrcMaskFull) { | ||||
MI.getOperand(3).setImm(NewMB); | MI.getOperand(3).setImm(NewMB); | ||||
MI.getOperand(4).setImm(NewME); | MI.getOperand(4).setImm(NewME); | ||||
} | } | ||||
MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg()); | MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg()); | ||||
if (SrcMI->getOperand(1).isKill()) { | if (SrcMI->getOperand(1).isKill()) { | ||||
Not Done ReplyInline ActionsIn general, I find that manually messing with kill flags when changing the instructions to be an error-prone thing that should be avoided if possible? Is it possible to re-run the pass that computes kill flags after the peephole? For example I think that here, if MI.getOperand(1).isKill() before the change, we will not update the kill flag on the previous use of that register so it will be considered live after MI whereas before it wasn't. This is of course not semantically incorrect, but may hinder some optimizations. nemanjai: In general, I find that manually messing with kill flags when changing the instructions to be… | |||||
Good catch! However I have no idea which pass can solve the problem. It seems that LiveInternals Pass will computes kill flags, but it can't handle the case you mentioned. Do you have any idea about this? Esme: Good catch! However I have no idea which pass can solve the problem. It seems that… | |||||
MI.getOperand(1).setIsKill(true); | MI.getOperand(1).setIsKill(true); | ||||
SrcMI->getOperand(1).setIsKill(false); | SrcMI->getOperand(1).setIsKill(false); | ||||
} else | } else | ||||
// About to replace MI.getOperand(1), clear its kill flag. | // About to replace MI.getOperand(1), clear its kill flag. | ||||
MI.getOperand(1).setIsKill(false); | MI.getOperand(1).setIsKill(false); | ||||
LLVM_DEBUG(dbgs() << "To: "); | LLVM_DEBUG(dbgs() << "To: "); | ||||
LLVM_DEBUG(MI.dump()); | LLVM_DEBUG(MI.dump()); | ||||
} | } | ||||
if (Simplified & MRI->use_nodbg_empty(FoldingReg) && | if (Simplified && CanErase) { | ||||
!SrcMI->hasImplicitDef()) { | // If SrcMI has no implicit def, and FoldingReg has no non-debug use or | ||||
// If FoldingReg has no non-debug use and it has no implicit def (it | // its flag is "killed", it's safe to delete SrcMI. Otherwise keep it. | ||||
// is not RLWINMO or RLWINM8o), it's safe to delete its def SrcMI. | ToErase = SrcMI; | ||||
// Otherwise keep it. | |||||
*ToErase = SrcMI; | |||||
LLVM_DEBUG(dbgs() << "Delete dead instruction: "); | LLVM_DEBUG(dbgs() << "Delete dead instruction: "); | ||||
LLVM_DEBUG(SrcMI->dump()); | LLVM_DEBUG(SrcMI->dump()); | ||||
} | } | ||||
return Simplified; | return Simplified; | ||||
} | } | ||||
Not Done ReplyInline ActionsCan we set the NoUse for pre-ra also,so that just check the NoUse here? steven.zhang: Can we set the NoUse for pre-ra also,so that just check the NoUse here? | |||||
Not Done ReplyInline ActionsFor the scenario of pre-ra, we have to check MRI->use_nodbg_empty(FoldingReg) here instead of setting NoUse before folding as post-ra did, since MRI->use_nodbg_empty(FoldingReg) is false before folding MI and SrcMI. Esme: For the scenario of pre-ra, we have to check `MRI->use_nodbg_empty(FoldingReg)` here instead of… | |||||
Not Done ReplyInline ActionsSame as above, after RA, even SrcMI has multiple uses, we still should do the transform? shchenz: Same as above, after RA, even SrcMI has multiple uses, we still should do the transform? | |||||
Not Done ReplyInline ActionsCan we move CanErase assignment for SSA to the place where we assign it for post SSA? shchenz: Can we move `CanErase` assignment for SSA to the place where we assign it for post SSA? | |||||
The condition MRI->use_nodbg_empty(FoldingReg) has to be checked after the folding of MI and SrcMI. Esme: The condition `MRI->use_nodbg_empty(FoldingReg)` has to be checked after the folding of MI and… | |||||
Not Done ReplyInline ActionsIs it ok if we change use_nodbg_empty to hasOneNonDBGUse()? shchenz: Is it ok if we change `use_nodbg_empty` to `hasOneNonDBGUse()`? | |||||
bool PPCInstrInfo::instrHasImmForm(unsigned Opc, bool IsVFReg, | bool PPCInstrInfo::instrHasImmForm(unsigned Opc, bool IsVFReg, | ||||
null check? steven.zhang: null check? | |||||
ImmInstrInfo &III, bool PostRA) const { | ImmInstrInfo &III, bool PostRA) const { | ||||
// The vast majority of the instructions would need their operand 2 replaced | // The vast majority of the instructions would need their operand 2 replaced | ||||
// with an immediate when switching to the reg+imm form. A marked exception | // with an immediate when switching to the reg+imm form. A marked exception | ||||
// are the update form loads/stores for which a constant operand 2 would need | // are the update form loads/stores for which a constant operand 2 would need | ||||
// to turn into a displacement and move operand 1 to the operand 2 position. | // to turn into a displacement and move operand 1 to the operand 2 position. | ||||
III.ImmOpNo = 2; | III.ImmOpNo = 2; | ||||
III.OpNoForForwarding = 2; | III.OpNoForForwarding = 2; | ||||
III.ImmWidth = 16; | III.ImmWidth = 16; | ||||
▲ Show 20 Lines • Show All 1,662 Lines • Show Last 20 Lines |
How about use the MachineInstr *&ToErase to avoid the null check and default arguments ?