mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-23 06:21:11 +00:00
Convert EXTRACT_SUBREG to COPY when emitting machine instrs.
EXTRACT_SUBREG no longer appears as a machine instruction. Use COPY instead. Add isCopy() checks in many places using isMoveInstr() and isExtractSubreg(). The isMoveInstr hook will be removed later. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107879 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5c00e07795
commit
0bc25f4040
@ -215,9 +215,6 @@ public:
|
||||
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
|
||||
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
|
||||
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
|
||||
bool isExtractSubreg() const {
|
||||
return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
|
||||
}
|
||||
bool isInsertSubreg() const {
|
||||
return getOpcode() == TargetOpcode::INSERT_SUBREG;
|
||||
}
|
||||
@ -234,7 +231,13 @@ public:
|
||||
/// isCopyLike - Return true if the instruction behaves like a copy.
|
||||
/// This does not include native copy instructions.
|
||||
bool isCopyLike() const {
|
||||
return isCopy() || isSubregToReg() || isExtractSubreg() || isInsertSubreg();
|
||||
return isCopy() || isSubregToReg();
|
||||
}
|
||||
|
||||
/// isIdentityCopy - Return true is the instruction is an identity copy.
|
||||
bool isIdentityCopy() const {
|
||||
return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() &&
|
||||
getOperand(0).getSubReg() == getOperand(1).getSubReg();
|
||||
}
|
||||
|
||||
/// readsRegister - Return true if the MachineInstr reads the specified
|
||||
|
@ -122,10 +122,6 @@ public:
|
||||
SrcReg == DstReg)
|
||||
return true;
|
||||
|
||||
if (MI.getOpcode() == TargetOpcode::EXTRACT_SUBREG &&
|
||||
MI.getOperand(0).getReg() == MI.getOperand(1).getReg())
|
||||
return true;
|
||||
|
||||
if ((MI.getOpcode() == TargetOpcode::INSERT_SUBREG ||
|
||||
MI.getOpcode() == TargetOpcode::SUBREG_TO_REG) &&
|
||||
MI.getOperand(0).getReg() == MI.getOperand(2).getReg())
|
||||
|
@ -192,6 +192,9 @@ bool LiveIntervals::conflictsWithPhysReg(const LiveInterval &li,
|
||||
if (tii_->isMoveInstr(MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
|
||||
if (SrcReg == li.reg || DstReg == li.reg)
|
||||
continue;
|
||||
if (MI.isCopy() && MI.getOperand(0).getReg() == li.reg &&
|
||||
MI.getOperand(1).getReg() == li.reg)
|
||||
continue;
|
||||
|
||||
// Check for operands using reg
|
||||
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
||||
|
@ -53,7 +53,6 @@ namespace {
|
||||
bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
private:
|
||||
bool LowerExtract(MachineInstr *MI);
|
||||
bool LowerSubregToReg(MachineInstr *MI);
|
||||
bool LowerCopy(MachineInstr *MI);
|
||||
|
||||
@ -121,57 +120,6 @@ LowerSubregsInstructionPass::TransferImplicitDefs(MachineInstr *MI) {
|
||||
}
|
||||
}
|
||||
|
||||
bool LowerSubregsInstructionPass::LowerExtract(MachineInstr *MI) {
|
||||
MachineBasicBlock *MBB = MI->getParent();
|
||||
|
||||
assert(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
|
||||
MI->getOperand(1).isReg() && MI->getOperand(1).isUse() &&
|
||||
MI->getOperand(2).isImm() && "Malformed extract_subreg");
|
||||
|
||||
unsigned DstReg = MI->getOperand(0).getReg();
|
||||
unsigned SuperReg = MI->getOperand(1).getReg();
|
||||
unsigned SubIdx = MI->getOperand(2).getImm();
|
||||
unsigned SrcReg = TRI->getSubReg(SuperReg, SubIdx);
|
||||
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(SuperReg) &&
|
||||
"Extract supperg source must be a physical register");
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
|
||||
"Extract destination must be in a physical register");
|
||||
assert(SrcReg && "invalid subregister index for register");
|
||||
|
||||
DEBUG(dbgs() << "subreg: CONVERTING: " << *MI);
|
||||
|
||||
if (SrcReg == DstReg) {
|
||||
// No need to insert an identity copy instruction.
|
||||
if (MI->getOperand(1).isKill()) {
|
||||
// We must make sure the super-register gets killed. Replace the
|
||||
// instruction with KILL.
|
||||
MI->setDesc(TII->get(TargetOpcode::KILL));
|
||||
MI->RemoveOperand(2); // SubIdx
|
||||
DEBUG(dbgs() << "subreg: replace by: " << *MI);
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << "subreg: eliminated!");
|
||||
} else {
|
||||
TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstReg, SrcReg, false);
|
||||
// Transfer the kill/dead flags, if needed.
|
||||
if (MI->getOperand(0).isDead())
|
||||
TransferDeadFlag(MI, DstReg, TRI);
|
||||
if (MI->getOperand(1).isKill())
|
||||
TransferKillFlag(MI, SuperReg, TRI, true);
|
||||
TransferImplicitDefs(MI);
|
||||
DEBUG({
|
||||
MachineBasicBlock::iterator dMI = MI;
|
||||
dbgs() << "subreg: " << *(--dMI);
|
||||
});
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << '\n');
|
||||
MBB->erase(MI);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) {
|
||||
MachineBasicBlock *MBB = MI->getParent();
|
||||
assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&
|
||||
@ -280,9 +228,9 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) {
|
||||
MachineBasicBlock::iterator nmi = llvm::next(mi);
|
||||
MachineInstr *MI = mi;
|
||||
assert(!MI->isInsertSubreg() && "INSERT_SUBREG should no longer appear");
|
||||
if (MI->isExtractSubreg()) {
|
||||
MadeChange |= LowerExtract(MI);
|
||||
} else if (MI->isSubregToReg()) {
|
||||
assert(MI->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
|
||||
"EXTRACT_SUBREG should no longer appear");
|
||||
if (MI->isSubregToReg()) {
|
||||
MadeChange |= LowerSubregToReg(MI);
|
||||
} else if (MI->isCopy()) {
|
||||
MadeChange |= LowerCopy(MI);
|
||||
|
@ -126,6 +126,28 @@ bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
|
||||
++NumCoalesces;
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
if (!DefMI->isCopy())
|
||||
continue;
|
||||
SrcReg = DefMI->getOperand(1).getReg();
|
||||
if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
|
||||
continue;
|
||||
if (DefMI->getOperand(0).getSubReg() || DefMI->getOperand(1).getSubReg())
|
||||
continue;
|
||||
const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
|
||||
const TargetRegisterClass *RC = MRI->getRegClass(Reg);
|
||||
const TargetRegisterClass *NewRC = getCommonSubClass(RC, SRC);
|
||||
if (!NewRC)
|
||||
continue;
|
||||
DEBUG(dbgs() << "Coalescing: " << *DefMI);
|
||||
DEBUG(dbgs() << "*** to: " << *MI);
|
||||
MO.setReg(SrcReg);
|
||||
MRI->clearKillFlags(SrcReg);
|
||||
if (NewRC != SRC)
|
||||
MRI->setRegClass(SrcReg, NewRC);
|
||||
DefMI->eraseFromParent();
|
||||
++NumCoalesces;
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
return Changed;
|
||||
|
@ -128,12 +128,12 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
|
||||
//
|
||||
// %reg1025 = <sext> %reg1024
|
||||
// ...
|
||||
// %reg1027 = EXTRACT_SUBREG %reg1025, 4
|
||||
// %reg1027 = COPY %reg1025:4
|
||||
// %reg1026 = SUBREG_TO_REG 0, %reg1027, 4
|
||||
//
|
||||
// The problem here is that SUBREG_TO_REG is there to assert that an
|
||||
// implicit zext occurs. It doesn't insert a zext instruction. If we allow
|
||||
// the EXTRACT_SUBREG here, it will give us the value after the <sext>,
|
||||
// the COPY here, it will give us the value after the <sext>,
|
||||
// not the original value of %reg1024 before <sext>.
|
||||
if (UseMI->getOpcode() == TargetOpcode::SUBREG_TO_REG)
|
||||
continue;
|
||||
@ -185,8 +185,8 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
|
||||
continue;
|
||||
unsigned NewVR = MRI->createVirtualRegister(RC);
|
||||
BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
|
||||
TII->get(TargetOpcode::EXTRACT_SUBREG), NewVR)
|
||||
.addReg(DstReg).addImm(SubIdx);
|
||||
TII->get(TargetOpcode::COPY), NewVR)
|
||||
.addReg(DstReg, 0, SubIdx);
|
||||
UseMO->setReg(NewVR);
|
||||
++NumReuse;
|
||||
Changed = true;
|
||||
|
@ -50,8 +50,7 @@ bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI,
|
||||
return true;
|
||||
|
||||
switch(OpIdx) {
|
||||
case 1: return (MI->isExtractSubreg() || MI->isCopy()) &&
|
||||
MI->getOperand(0).getSubReg() == 0;
|
||||
case 1: return MI->isCopy() && MI->getOperand(0).getSubReg() == 0;
|
||||
case 2: return MI->isSubregToReg() && MI->getOperand(0).getSubReg() == 0;
|
||||
default: return false;
|
||||
}
|
||||
|
@ -422,9 +422,10 @@ unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) {
|
||||
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
|
||||
if (vni->def != SlotIndex() && vni->isDefAccurate() &&
|
||||
(CopyMI = li_->getInstructionFromIndex(vni->def)) &&
|
||||
tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
|
||||
(CopyMI->isCopy() ||
|
||||
tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg)))
|
||||
// Defined by a copy, try to extend SrcReg forward
|
||||
CandReg = SrcReg;
|
||||
CandReg = CopyMI->isCopy() ? CopyMI->getOperand(1).getReg() : SrcReg;
|
||||
else if (TrivCoalesceEnds &&
|
||||
(CopyMI =
|
||||
li_->getInstructionFromIndex(range.end.getBaseIndex())) &&
|
||||
@ -993,6 +994,24 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) {
|
||||
if (Reg && allocatableRegs_[Reg] && RC->contains(Reg))
|
||||
mri_->setRegAllocationHint(cur->reg, 0, Reg);
|
||||
}
|
||||
} else if (CopyMI && CopyMI->isCopy()) {
|
||||
DstReg = CopyMI->getOperand(0).getReg();
|
||||
DstSubReg = CopyMI->getOperand(0).getSubReg();
|
||||
SrcReg = CopyMI->getOperand(1).getReg();
|
||||
SrcSubReg = CopyMI->getOperand(1).getSubReg();
|
||||
unsigned Reg = 0;
|
||||
if (TargetRegisterInfo::isPhysicalRegister(SrcReg))
|
||||
Reg = SrcReg;
|
||||
else if (vrm_->isAssignedReg(SrcReg))
|
||||
Reg = vrm_->getPhys(SrcReg);
|
||||
if (Reg) {
|
||||
if (SrcSubReg)
|
||||
Reg = tri_->getSubReg(Reg, SrcSubReg);
|
||||
if (DstSubReg)
|
||||
Reg = tri_->getMatchingSuperReg(Reg, DstSubReg, RC);
|
||||
if (Reg && allocatableRegs_[Reg] && RC->contains(Reg))
|
||||
mri_->setRegAllocationHint(cur->reg, 0, Reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,11 +49,6 @@ bool CoalescerPair::isMoveInstr(const MachineInstr *MI,
|
||||
DstSub = MI->getOperand(0).getSubReg();
|
||||
Src = MI->getOperand(1).getReg();
|
||||
SrcSub = MI->getOperand(1).getSubReg();
|
||||
} else if (MI->isExtractSubreg()) {
|
||||
Dst = MI->getOperand(0).getReg();
|
||||
DstSub = MI->getOperand(0).getSubReg();
|
||||
Src = MI->getOperand(1).getReg();
|
||||
SrcSub = compose(MI->getOperand(1).getSubReg(), MI->getOperand(2).getImm());
|
||||
} else if (MI->isSubregToReg()) {
|
||||
Dst = MI->getOperand(0).getReg();
|
||||
DstSub = compose(MI->getOperand(0).getSubReg(), MI->getOperand(3).getImm());
|
||||
|
@ -1132,24 +1132,11 @@ unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode,
|
||||
unsigned FastISel::FastEmitInst_extractsubreg(MVT RetVT,
|
||||
unsigned Op0, bool Op0IsKill,
|
||||
uint32_t Idx) {
|
||||
const TargetRegisterClass* RC = MRI.getRegClass(Op0);
|
||||
|
||||
unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
|
||||
const TargetInstrDesc &II = TII.get(TargetOpcode::EXTRACT_SUBREG);
|
||||
|
||||
if (II.getNumDefs() >= 1)
|
||||
BuildMI(MBB, DL, II, ResultReg)
|
||||
.addReg(Op0, Op0IsKill * RegState::Kill)
|
||||
.addImm(Idx);
|
||||
else {
|
||||
BuildMI(MBB, DL, II)
|
||||
.addReg(Op0, Op0IsKill * RegState::Kill)
|
||||
.addImm(Idx);
|
||||
bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg,
|
||||
II.ImplicitDefs[0], RC, RC, DL);
|
||||
if (!InsertedCopy)
|
||||
ResultReg = 0;
|
||||
}
|
||||
assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
|
||||
"Cannot yet extract from physregs");
|
||||
BuildMI(MBB, DL, TII.get(TargetOpcode::COPY), ResultReg)
|
||||
.addReg(Op0, getKillRegState(Op0IsKill), Idx);
|
||||
return ResultReg;
|
||||
}
|
||||
|
||||
|
@ -428,12 +428,9 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
|
||||
}
|
||||
|
||||
if (Opc == TargetOpcode::EXTRACT_SUBREG) {
|
||||
// EXTRACT_SUBREG is lowered as %dst = COPY %src:sub
|
||||
unsigned SubIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
|
||||
|
||||
// Create the extract_subreg machine instruction.
|
||||
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
|
||||
TII->get(TargetOpcode::EXTRACT_SUBREG));
|
||||
|
||||
// Figure out the register class to create for the destreg.
|
||||
unsigned VReg = getVR(Node->getOperand(0), VRBaseMap);
|
||||
const TargetRegisterClass *TRC = MRI->getRegClass(VReg);
|
||||
@ -450,11 +447,16 @@ void InstrEmitter::EmitSubregNode(SDNode *Node,
|
||||
VRBase = MRI->createVirtualRegister(SRC);
|
||||
}
|
||||
|
||||
// Add def, source, and subreg index
|
||||
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
|
||||
// Create the extract_subreg machine instruction.
|
||||
MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(),
|
||||
TII->get(TargetOpcode::COPY), VRBase);
|
||||
|
||||
// Add source, and subreg index
|
||||
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap, /*IsDebug=*/false,
|
||||
IsClone, IsCloned);
|
||||
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
||||
assert(TargetRegisterInfo::isVirtualRegister(MI->getOperand(1).getReg()) &&
|
||||
"Cannot yet extract from physregs");
|
||||
MI->getOperand(1).setSubReg(SubIdx);
|
||||
MBB->insert(InsertPos, MI);
|
||||
} else if (Opc == TargetOpcode::INSERT_SUBREG ||
|
||||
Opc == TargetOpcode::SUBREG_TO_REG) {
|
||||
|
@ -1525,7 +1525,7 @@ void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
|
||||
// If this isn't a copy nor a extract_subreg, we can't join intervals.
|
||||
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
|
||||
bool isInsUndef = false;
|
||||
if (Inst->isCopy() || Inst->isExtractSubreg()) {
|
||||
if (Inst->isCopy()) {
|
||||
DstReg = Inst->getOperand(0).getReg();
|
||||
SrcReg = Inst->getOperand(1).getReg();
|
||||
} else if (Inst->isSubregToReg()) {
|
||||
@ -1657,6 +1657,8 @@ SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start,
|
||||
E = mri_->use_nodbg_end(); I != E; ++I) {
|
||||
MachineOperand &Use = I.getOperand();
|
||||
MachineInstr *UseMI = Use.getParent();
|
||||
if (UseMI->isIdentityCopy())
|
||||
continue;
|
||||
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
|
||||
if (tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
|
||||
SrcReg == DstReg && SrcSubIdx == DstSubIdx)
|
||||
@ -1687,7 +1689,8 @@ SimpleRegisterCoalescing::lastRegisterUse(SlotIndex Start,
|
||||
|
||||
// Ignore identity copies.
|
||||
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
|
||||
if (!(tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
|
||||
if (!MI->isIdentityCopy() &&
|
||||
!(tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
|
||||
SrcReg == DstReg && SrcSubIdx == DstSubIdx))
|
||||
for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
|
||||
MachineOperand &Use = MI->getOperand(i);
|
||||
@ -1818,7 +1821,8 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
||||
|
||||
// If the move will be an identity move delete it
|
||||
bool isMove= tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
|
||||
if (isMove && SrcReg == DstReg && SrcSubIdx == DstSubIdx) {
|
||||
if (MI->isIdentityCopy() ||
|
||||
(isMove && SrcReg == DstReg && SrcSubIdx == DstSubIdx)) {
|
||||
if (li_->hasInterval(SrcReg)) {
|
||||
LiveInterval &RegInt = li_->getInterval(SrcReg);
|
||||
// If def of this move instruction is dead, remove its live range
|
||||
|
@ -508,7 +508,7 @@ bool StackSlotColoring::PropagateBackward(MachineBasicBlock::iterator MII,
|
||||
|
||||
// Abort the use is actually a sub-register def. We don't have enough
|
||||
// information to figure out if it is really legal.
|
||||
if (MO.getSubReg() || MII->isExtractSubreg() || MII->isSubregToReg())
|
||||
if (MO.getSubReg() || MII->isSubregToReg())
|
||||
return false;
|
||||
|
||||
const TargetRegisterClass *RC = TID.OpInfo[i].getRegClass(TRI);
|
||||
@ -570,7 +570,7 @@ bool StackSlotColoring::PropagateForward(MachineBasicBlock::iterator MII,
|
||||
|
||||
// Abort the use is actually a sub-register use. We don't have enough
|
||||
// information to figure out if it is really legal.
|
||||
if (MO.getSubReg() || MII->isExtractSubreg())
|
||||
if (MO.getSubReg())
|
||||
return false;
|
||||
|
||||
const TargetRegisterClass *RC = TID.OpInfo[i].getRegClass(TRI);
|
||||
|
@ -382,7 +382,7 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII,
|
||||
DstReg = 0;
|
||||
unsigned SrcSubIdx, DstSubIdx;
|
||||
if (!TII->isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
|
||||
if (MI.isCopy() || MI.isExtractSubreg()) {
|
||||
if (MI.isCopy()) {
|
||||
DstReg = MI.getOperand(0).getReg();
|
||||
SrcReg = MI.getOperand(1).getReg();
|
||||
} else if (MI.isInsertSubreg()) {
|
||||
@ -1291,7 +1291,7 @@ TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs,
|
||||
if (SrcDefMI->getParent() != DstDefMI->getParent())
|
||||
continue;
|
||||
|
||||
// If there are no other uses than extract_subreg which feed into
|
||||
// If there are no other uses than copies which feed into
|
||||
// the reg_sequence, then we might be able to coalesce them.
|
||||
bool CanCoalesce = true;
|
||||
SmallVector<unsigned, 4> SrcSubIndices, DstSubIndices;
|
||||
@ -1299,13 +1299,11 @@ TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs,
|
||||
UI = MRI->use_nodbg_begin(SrcReg),
|
||||
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
|
||||
MachineInstr *UseMI = &*UI;
|
||||
if (!UseMI->isExtractSubreg() ||
|
||||
UseMI->getOperand(0).getReg() != DstReg ||
|
||||
UseMI->getOperand(1).getSubReg() != 0) {
|
||||
if (!UseMI->isCopy() || UseMI->getOperand(0).getReg() != DstReg) {
|
||||
CanCoalesce = false;
|
||||
break;
|
||||
}
|
||||
SrcSubIndices.push_back(UseMI->getOperand(2).getImm());
|
||||
SrcSubIndices.push_back(UseMI->getOperand(1).getSubReg());
|
||||
DstSubIndices.push_back(UseMI->getOperand(0).getSubReg());
|
||||
}
|
||||
|
||||
@ -1340,9 +1338,9 @@ TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs,
|
||||
UI = MRI->use_nodbg_begin(SrcReg),
|
||||
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
|
||||
MachineInstr *UseMI = &*UI;
|
||||
assert(UseMI->isExtractSubreg());
|
||||
assert(UseMI->isCopy());
|
||||
unsigned DstSubIdx = UseMI->getOperand(0).getSubReg();
|
||||
unsigned SrcSubIdx = UseMI->getOperand(2).getImm();
|
||||
unsigned SrcSubIdx = UseMI->getOperand(1).getSubReg();
|
||||
assert(DstSubIdx != 0 && "missing subreg from RegSequence elimination");
|
||||
if ((NewDstSubIdx == 0 &&
|
||||
TRI->composeSubRegIndices(NewSrcSubIdx, DstSubIdx) != SrcSubIdx) ||
|
||||
@ -1357,7 +1355,7 @@ TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs,
|
||||
if (!CanCoalesce)
|
||||
continue;
|
||||
|
||||
// Insert a copy or an extract to replace the original extracts.
|
||||
// Insert a copy to replace the original.
|
||||
MachineBasicBlock::iterator InsertLoc = SomeMI;
|
||||
MachineInstr *CopyMI = BuildMI(*SomeMI->getParent(), SomeMI,
|
||||
SomeMI->getDebugLoc(),
|
||||
@ -1373,11 +1371,10 @@ TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs,
|
||||
++UI;
|
||||
if (UseMI == CopyMI)
|
||||
continue;
|
||||
assert(UseMI->isExtractSubreg());
|
||||
assert(UseMI->isCopy());
|
||||
// Move any kills to the new copy or extract instruction.
|
||||
if (UseMI->getOperand(1).isKill()) {
|
||||
MachineOperand *KillMO = CopyMI->findRegisterUseOperand(SrcReg);
|
||||
KillMO->setIsKill();
|
||||
CopyMI->getOperand(1).setIsKill();
|
||||
if (LV)
|
||||
// Update live variables
|
||||
LV->replaceKillInstruction(SrcReg, UseMI, &*CopyMI);
|
||||
@ -1438,9 +1435,8 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
|
||||
}
|
||||
IsImpDef = false;
|
||||
|
||||
// Remember EXTRACT_SUBREG sources. These might be candidate for
|
||||
// coalescing.
|
||||
if (DefMI->isExtractSubreg())
|
||||
// Remember COPY sources. These might be candidate for coalescing.
|
||||
if (DefMI->isCopy())
|
||||
RealSrcs.push_back(DefMI->getOperand(1).getReg());
|
||||
|
||||
if (!Seen.insert(SrcReg) ||
|
||||
|
@ -2012,7 +2012,7 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs,
|
||||
// = EXTRACT_SUBREG fi#1
|
||||
// fi#1 is available in EDI, but it cannot be reused because it's not in
|
||||
// the right register file.
|
||||
if (PhysReg && !AvoidReload && (SubIdx || MI.isExtractSubreg())) {
|
||||
if (PhysReg && !AvoidReload && SubIdx) {
|
||||
const TargetRegisterClass* RC = MRI->getRegClass(VirtReg);
|
||||
if (!RC->contains(PhysReg))
|
||||
PhysReg = 0;
|
||||
|
@ -407,7 +407,7 @@ NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
|
||||
"expected a virtual register");
|
||||
// Extracting from a Q or QQ register.
|
||||
MachineInstr *DefMI = MRI->getVRegDef(VirtReg);
|
||||
if (!DefMI || !DefMI->isExtractSubreg())
|
||||
if (!DefMI || !DefMI->isCopy() || !DefMI->getOperand(1).getSubReg())
|
||||
return false;
|
||||
VirtReg = DefMI->getOperand(1).getReg();
|
||||
if (LastSrcReg && LastSrcReg != VirtReg)
|
||||
@ -418,7 +418,7 @@ NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
|
||||
RC != ARM::QQPRRegisterClass &&
|
||||
RC != ARM::QQQQPRRegisterClass)
|
||||
return false;
|
||||
unsigned SubIdx = DefMI->getOperand(2).getImm();
|
||||
unsigned SubIdx = DefMI->getOperand(1).getSubReg();
|
||||
if (LastSubIdx) {
|
||||
if (LastSubIdx != SubIdx-Stride)
|
||||
return false;
|
||||
@ -445,7 +445,7 @@ NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
|
||||
MachineOperand &MO = MI->getOperand(FirstOpnd + R);
|
||||
unsigned OldReg = MO.getReg();
|
||||
MachineInstr *DefMI = MRI->getVRegDef(OldReg);
|
||||
assert(DefMI->isExtractSubreg());
|
||||
assert(DefMI->isCopy());
|
||||
MO.setReg(LastSrcReg);
|
||||
MO.setSubReg(SubIds[R]);
|
||||
MO.setIsKill(false);
|
||||
|
@ -1039,11 +1039,10 @@ bool X86FastISel::X86SelectShift(const Instruction *I) {
|
||||
TII.copyRegToReg(*MBB, MBB->end(), CReg, Op1Reg, RC, RC, DL);
|
||||
|
||||
// The shift instruction uses X86::CL. If we defined a super-register
|
||||
// of X86::CL, emit an EXTRACT_SUBREG to precisely describe what
|
||||
// we're doing here.
|
||||
// of X86::CL, emit a subreg KILL to precisely describe what we're doing here.
|
||||
if (CReg != X86::CL)
|
||||
BuildMI(MBB, DL, TII.get(TargetOpcode::EXTRACT_SUBREG), X86::CL)
|
||||
.addReg(CReg).addImm(X86::sub_8bit);
|
||||
BuildMI(MBB, DL, TII.get(TargetOpcode::KILL), X86::CL)
|
||||
.addReg(CReg, RegState::Kill);
|
||||
|
||||
unsigned ResultReg = createResultReg(RC);
|
||||
BuildMI(MBB, DL, TII.get(OpReg), ResultReg).addReg(Op0Reg);
|
||||
|
@ -1201,10 +1201,9 @@ X86InstrInfo::convertToThreeAddressWithLEA(unsigned MIOpc,
|
||||
|
||||
MachineInstr *NewMI = MIB;
|
||||
MachineInstr *ExtMI =
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(X86::EXTRACT_SUBREG))
|
||||
BuildMI(*MFI, MBBI, MI->getDebugLoc(), get(TargetOpcode::COPY))
|
||||
.addReg(Dest, RegState::Define | getDeadRegState(isDead))
|
||||
.addReg(leaOutReg, RegState::Kill)
|
||||
.addImm(X86::sub_16bit);
|
||||
.addReg(leaOutReg, RegState::Kill, X86::sub_16bit);
|
||||
|
||||
if (LV) {
|
||||
// Update live variables
|
||||
|
Loading…
x
Reference in New Issue
Block a user