mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-24 08:33:39 +00:00
Teach liveintervalanalysis about virtual registers which are defined by reg_sequence instructions that are formed by registers defined by distinct instructions. e.g.
80 %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0 . . . 120 %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103102 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
91dd419ba4
commit
3749943648
@ -303,6 +303,12 @@ namespace llvm {
|
|||||||
SlotIndex MIIdx,
|
SlotIndex MIIdx,
|
||||||
MachineOperand& MO, unsigned MOIdx);
|
MachineOperand& MO, unsigned MOIdx);
|
||||||
|
|
||||||
|
/// isPartialRedef - Return true if the specified def at the specific index
|
||||||
|
/// is partially re-defining the specified live interval. A common case of
|
||||||
|
/// this is a definition of the sub-register.
|
||||||
|
bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
|
||||||
|
LiveInterval &interval);
|
||||||
|
|
||||||
/// handleVirtualRegisterDef - update intervals for a virtual
|
/// handleVirtualRegisterDef - update intervals for a virtual
|
||||||
/// register def
|
/// register def
|
||||||
void handleVirtualRegisterDef(MachineBasicBlock *MBB,
|
void handleVirtualRegisterDef(MachineBasicBlock *MBB,
|
||||||
|
@ -263,7 +263,7 @@ static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static
|
static
|
||||||
bool MultipleDefsByMI(const MachineInstr &MI, unsigned MOIdx) {
|
bool MultipleDefsBySameMI(const MachineInstr &MI, unsigned MOIdx) {
|
||||||
unsigned Reg = MI.getOperand(MOIdx).getReg();
|
unsigned Reg = MI.getOperand(MOIdx).getReg();
|
||||||
for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) {
|
for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) {
|
||||||
const MachineOperand &MO = MI.getOperand(i);
|
const MachineOperand &MO = MI.getOperand(i);
|
||||||
@ -279,6 +279,24 @@ bool MultipleDefsByMI(const MachineInstr &MI, unsigned MOIdx) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// isPartialRedef - Return true if the specified def at the specific index is
|
||||||
|
/// partially re-defining the specified live interval. A common case of this is
|
||||||
|
/// a definition of the sub-register.
|
||||||
|
bool LiveIntervals::isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
|
||||||
|
LiveInterval &interval) {
|
||||||
|
if (!MO.getSubReg() || MO.isEarlyClobber())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SlotIndex RedefIndex = MIIdx.getDefIndex();
|
||||||
|
const LiveRange *OldLR =
|
||||||
|
interval.getLiveRangeContaining(RedefIndex.getUseIndex());
|
||||||
|
if (OldLR->valno->isDefAccurate()) {
|
||||||
|
MachineInstr *DefMI = getInstructionFromIndex(OldLR->valno->def);
|
||||||
|
return DefMI->findRegisterDefOperandIdx(interval.reg) != -1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||||
MachineBasicBlock::iterator mi,
|
MachineBasicBlock::iterator mi,
|
||||||
SlotIndex MIIdx,
|
SlotIndex MIIdx,
|
||||||
@ -302,15 +320,14 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
// of inputs.
|
// of inputs.
|
||||||
if (MO.isEarlyClobber())
|
if (MO.isEarlyClobber())
|
||||||
defIndex = MIIdx.getUseIndex();
|
defIndex = MIIdx.getUseIndex();
|
||||||
VNInfo *ValNo;
|
|
||||||
MachineInstr *CopyMI = NULL;
|
MachineInstr *CopyMI = NULL;
|
||||||
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
|
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
|
||||||
if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg() ||
|
if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg() ||
|
||||||
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
|
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
|
||||||
CopyMI = mi;
|
CopyMI = mi;
|
||||||
// Earlyclobbers move back one.
|
|
||||||
ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
|
|
||||||
|
|
||||||
|
VNInfo *ValNo = interval.getNextValue(defIndex, CopyMI, true,
|
||||||
|
VNInfoAllocator);
|
||||||
assert(ValNo->id == 0 && "First value in interval is not 0?");
|
assert(ValNo->id == 0 && "First value in interval is not 0?");
|
||||||
|
|
||||||
// Loop over all of the blocks that the vreg is defined in. There are
|
// Loop over all of the blocks that the vreg is defined in. There are
|
||||||
@ -389,7 +406,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (MultipleDefsByMI(*mi, MOIdx))
|
if (MultipleDefsBySameMI(*mi, MOIdx))
|
||||||
// Mutple defs of the same virtual register by the same instruction. e.g.
|
// Mutple defs of the same virtual register by the same instruction. e.g.
|
||||||
// %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
|
// %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
|
||||||
// This is likely due to elimination of REG_SEQUENCE instructions. Return
|
// This is likely due to elimination of REG_SEQUENCE instructions. Return
|
||||||
@ -400,14 +417,23 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
// must be due to phi elimination or two addr elimination. If this is
|
// must be due to phi elimination or two addr elimination. If this is
|
||||||
// the result of two address elimination, then the vreg is one of the
|
// the result of two address elimination, then the vreg is one of the
|
||||||
// def-and-use register operand.
|
// def-and-use register operand.
|
||||||
if (mi->isRegTiedToUseOperand(MOIdx)) {
|
|
||||||
|
// It may also be partial redef like this:
|
||||||
|
// 80 %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0
|
||||||
|
// 120 %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0
|
||||||
|
bool PartReDef = isPartialRedef(MIIdx, MO, interval);
|
||||||
|
if (PartReDef || mi->isRegTiedToUseOperand(MOIdx)) {
|
||||||
// If this is a two-address definition, then we have already processed
|
// If this is a two-address definition, then we have already processed
|
||||||
// the live range. The only problem is that we didn't realize there
|
// the live range. The only problem is that we didn't realize there
|
||||||
// are actually two values in the live interval. Because of this we
|
// are actually two values in the live interval. Because of this we
|
||||||
// need to take the LiveRegion that defines this register and split it
|
// need to take the LiveRegion that defines this register and split it
|
||||||
// into two values.
|
// into two values.
|
||||||
assert(interval.containsOneValue());
|
// Two-address vregs should always only be redefined once. This means
|
||||||
SlotIndex DefIndex = interval.getValNumInfo(0)->def.getDefIndex();
|
// that at this point, there should be exactly one value number in it.
|
||||||
|
assert((PartReDef || interval.containsOneValue()) &&
|
||||||
|
"Unexpected 2-addr liveint!");
|
||||||
|
unsigned NumVals = interval.getNumValNums();
|
||||||
|
SlotIndex DefIndex = interval.getValNumInfo(NumVals-1)->def.getDefIndex();
|
||||||
SlotIndex RedefIndex = MIIdx.getDefIndex();
|
SlotIndex RedefIndex = MIIdx.getDefIndex();
|
||||||
if (MO.isEarlyClobber())
|
if (MO.isEarlyClobber())
|
||||||
RedefIndex = MIIdx.getUseIndex();
|
RedefIndex = MIIdx.getUseIndex();
|
||||||
@ -420,10 +446,6 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
// because the 2-addr copy must be in the same MBB as the redef.
|
// because the 2-addr copy must be in the same MBB as the redef.
|
||||||
interval.removeRange(DefIndex, RedefIndex);
|
interval.removeRange(DefIndex, RedefIndex);
|
||||||
|
|
||||||
// Two-address vregs should always only be redefined once. This means
|
|
||||||
// that at this point, there should be exactly one value number in it.
|
|
||||||
assert(interval.containsOneValue() && "Unexpected 2-addr liveint!");
|
|
||||||
|
|
||||||
// The new value number (#1) is defined by the instruction we claimed
|
// The new value number (#1) is defined by the instruction we claimed
|
||||||
// defined value #0.
|
// defined value #0.
|
||||||
VNInfo *ValNo = interval.getNextValue(OldValNo->def, OldValNo->getCopy(),
|
VNInfo *ValNo = interval.getNextValue(OldValNo->def, OldValNo->getCopy(),
|
||||||
@ -451,8 +473,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
dbgs() << " RESULT: ";
|
dbgs() << " RESULT: ";
|
||||||
interval.print(dbgs(), tri_);
|
interval.print(dbgs(), tri_);
|
||||||
});
|
});
|
||||||
} else {
|
} else if (lv_->isPHIJoin(interval.reg)) {
|
||||||
assert(lv_->isPHIJoin(interval.reg) && "Multiply defined register");
|
|
||||||
// In the case of PHI elimination, each variable definition is only
|
// In the case of PHI elimination, each variable definition is only
|
||||||
// live until the end of the block. We've already taken care of the
|
// live until the end of the block. We've already taken care of the
|
||||||
// rest of the live range.
|
// rest of the live range.
|
||||||
@ -475,6 +496,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
|||||||
ValNo->addKill(indexes_->getTerminatorGap(mbb));
|
ValNo->addKill(indexes_->getTerminatorGap(mbb));
|
||||||
ValNo->setHasPHIKill(true);
|
ValNo->setHasPHIKill(true);
|
||||||
DEBUG(dbgs() << " phi-join +" << LR);
|
DEBUG(dbgs() << " phi-join +" << LR);
|
||||||
|
} else {
|
||||||
|
llvm_unreachable("Multiply defined register");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user