mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 00:21:03 +00:00
Re-apply 55467 with fix. If copy is being replaced by remat'ed def, transfer the implicit defs onto the remat'ed instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55564 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -38,6 +38,7 @@ STATISTIC(numJoins , "Number of interval joins performed");
|
|||||||
STATISTIC(numSubJoins , "Number of subclass joins performed");
|
STATISTIC(numSubJoins , "Number of subclass joins performed");
|
||||||
STATISTIC(numCommutes , "Number of instruction commuting performed");
|
STATISTIC(numCommutes , "Number of instruction commuting performed");
|
||||||
STATISTIC(numExtends , "Number of copies extended");
|
STATISTIC(numExtends , "Number of copies extended");
|
||||||
|
STATISTIC(NumReMats , "Number of instructions re-materialized");
|
||||||
STATISTIC(numPeep , "Number of identity moves eliminated after coalescing");
|
STATISTIC(numPeep , "Number of identity moves eliminated after coalescing");
|
||||||
STATISTIC(numAborts , "Number of times interval joining aborted");
|
STATISTIC(numAborts , "Number of times interval joining aborted");
|
||||||
|
|
||||||
@@ -426,6 +427,58 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial
|
||||||
|
/// computation, replace the copy by rematerialize the definition.
|
||||||
|
bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
|
||||||
|
unsigned DstReg,
|
||||||
|
MachineInstr *CopyMI) {
|
||||||
|
unsigned CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI));
|
||||||
|
LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx);
|
||||||
|
if (SrcLR == SrcInt.end()) // Should never happen!
|
||||||
|
return false;
|
||||||
|
VNInfo *ValNo = SrcLR->valno;
|
||||||
|
// If other defs can reach uses of this def, then it's not safe to perform
|
||||||
|
// the optimization.
|
||||||
|
if (ValNo->def == ~0U || ValNo->def == ~1U || ValNo->hasPHIKill)
|
||||||
|
return false;
|
||||||
|
MachineInstr *DefMI = li_->getInstructionFromIndex(ValNo->def);
|
||||||
|
const TargetInstrDesc &TID = DefMI->getDesc();
|
||||||
|
if (!TID.isAsCheapAsAMove())
|
||||||
|
return false;
|
||||||
|
bool SawStore = false;
|
||||||
|
if (!DefMI->isSafeToMove(tii_, SawStore))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned DefIdx = li_->getDefIndex(CopyIdx);
|
||||||
|
const LiveRange *DLR= li_->getInterval(DstReg).getLiveRangeContaining(DefIdx);
|
||||||
|
DLR->valno->copy = NULL;
|
||||||
|
|
||||||
|
MachineBasicBlock::iterator MII = CopyMI;
|
||||||
|
MachineBasicBlock *MBB = CopyMI->getParent();
|
||||||
|
tii_->reMaterialize(*MBB, MII, DstReg, DefMI);
|
||||||
|
MachineInstr *NewMI = prior(MII);
|
||||||
|
// CopyMI may have implicit instructions, transfer them over to the newly
|
||||||
|
// rematerialized instruction. And update implicit def interval valnos.
|
||||||
|
for (unsigned i = CopyMI->getDesc().getNumOperands(),
|
||||||
|
e = CopyMI->getNumOperands(); i != e; ++i) {
|
||||||
|
MachineOperand &MO = CopyMI->getOperand(i);
|
||||||
|
if (MO.isReg() && MO.isImplicit())
|
||||||
|
NewMI->addOperand(MO);
|
||||||
|
if (MO.isDef()) {
|
||||||
|
unsigned Reg = MO.getReg();
|
||||||
|
DLR = li_->getInterval(Reg).getLiveRangeContaining(DefIdx);
|
||||||
|
if (DLR && DLR->valno->copy == CopyMI)
|
||||||
|
DLR->valno->copy = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li_->ReplaceMachineInstrInMaps(CopyMI, NewMI);
|
||||||
|
CopyMI->eraseFromParent();
|
||||||
|
ReMatCopies.insert(CopyMI);
|
||||||
|
++NumReMats;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// isBackEdgeCopy - Returns true if CopyMI is a back edge copy.
|
/// isBackEdgeCopy - Returns true if CopyMI is a back edge copy.
|
||||||
///
|
///
|
||||||
bool SimpleRegisterCoalescing::isBackEdgeCopy(MachineInstr *CopyMI,
|
bool SimpleRegisterCoalescing::isBackEdgeCopy(MachineInstr *CopyMI,
|
||||||
@@ -475,6 +528,17 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
|
|||||||
unsigned UseDstReg = DstReg;
|
unsigned UseDstReg = DstReg;
|
||||||
if (OldSubIdx)
|
if (OldSubIdx)
|
||||||
UseDstReg = tri_->getSubReg(DstReg, OldSubIdx);
|
UseDstReg = tri_->getSubReg(DstReg, OldSubIdx);
|
||||||
|
|
||||||
|
unsigned CopySrcReg, CopyDstReg;
|
||||||
|
if (tii_->isMoveInstr(*UseMI, CopySrcReg, CopyDstReg) &&
|
||||||
|
CopySrcReg != CopyDstReg &&
|
||||||
|
CopySrcReg == SrcReg && CopyDstReg != UseDstReg) {
|
||||||
|
// If the use is a copy and it won't be coalesced away, and its source
|
||||||
|
// is defined by a trivial computation, try to rematerialize it instead.
|
||||||
|
if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,UseMI))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
O.setReg(UseDstReg);
|
O.setReg(UseDstReg);
|
||||||
O.setSubReg(0);
|
O.setSubReg(0);
|
||||||
} else {
|
} else {
|
||||||
@@ -865,7 +929,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
|
|||||||
MachineInstr *CopyMI = TheCopy.MI;
|
MachineInstr *CopyMI = TheCopy.MI;
|
||||||
|
|
||||||
Again = false;
|
Again = false;
|
||||||
if (JoinedCopies.count(CopyMI))
|
if (JoinedCopies.count(CopyMI) || ReMatCopies.count(CopyMI))
|
||||||
return false; // Already done.
|
return false; // Already done.
|
||||||
|
|
||||||
DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI;
|
DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI;
|
||||||
@@ -1108,6 +1172,12 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
|
|||||||
|
|
||||||
if (!isEmpty && !JoinIntervals(DstInt, SrcInt, Swapped)) {
|
if (!isEmpty && !JoinIntervals(DstInt, SrcInt, Swapped)) {
|
||||||
// Coalescing failed.
|
// Coalescing failed.
|
||||||
|
|
||||||
|
// If definition of source is defined by trivial computation, try
|
||||||
|
// rematerializing it.
|
||||||
|
if (!isExtSubReg && !isInsSubReg &&
|
||||||
|
ReMaterializeTrivialDef(SrcInt, DstInt.reg, CopyMI))
|
||||||
|
return true;
|
||||||
|
|
||||||
// If we can eliminate the copy without merging the live ranges, do so now.
|
// If we can eliminate the copy without merging the live ranges, do so now.
|
||||||
if (!isExtSubReg && !isInsSubReg &&
|
if (!isExtSubReg && !isInsSubReg &&
|
||||||
@@ -1211,9 +1281,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
|
|||||||
if (TargetRegisterInfo::isVirtualRegister(DstReg))
|
if (TargetRegisterInfo::isVirtualRegister(DstReg))
|
||||||
RemoveUnnecessaryKills(DstReg, *ResDstInt);
|
RemoveUnnecessaryKills(DstReg, *ResDstInt);
|
||||||
|
|
||||||
// SrcReg is guarateed to be the register whose live interval that is
|
|
||||||
// being merged.
|
|
||||||
li_->removeInterval(SrcReg);
|
|
||||||
if (isInsSubReg)
|
if (isInsSubReg)
|
||||||
// Avoid:
|
// Avoid:
|
||||||
// r1024 = op
|
// r1024 = op
|
||||||
@@ -1223,6 +1290,10 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
|
|||||||
RemoveDeadImpDef(DstReg, *ResDstInt);
|
RemoveDeadImpDef(DstReg, *ResDstInt);
|
||||||
UpdateRegDefsUses(SrcReg, DstReg, SubIdx);
|
UpdateRegDefsUses(SrcReg, DstReg, SubIdx);
|
||||||
|
|
||||||
|
// SrcReg is guarateed to be the register whose live interval that is
|
||||||
|
// being merged.
|
||||||
|
li_->removeInterval(SrcReg);
|
||||||
|
|
||||||
if (isEmpty) {
|
if (isEmpty) {
|
||||||
// Now the copy is being coalesced away, the val# previously defined
|
// Now the copy is being coalesced away, the val# previously defined
|
||||||
// by the copy is being defined by an IMPLICIT_DEF which defines a zero
|
// by the copy is being defined by an IMPLICIT_DEF which defines a zero
|
||||||
@@ -2018,6 +2089,7 @@ void SimpleRegisterCoalescing::printRegName(unsigned reg) const {
|
|||||||
|
|
||||||
void SimpleRegisterCoalescing::releaseMemory() {
|
void SimpleRegisterCoalescing::releaseMemory() {
|
||||||
JoinedCopies.clear();
|
JoinedCopies.clear();
|
||||||
|
ReMatCopies.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isZeroLengthInterval(LiveInterval *li) {
|
static bool isZeroLengthInterval(LiveInterval *li) {
|
||||||
|
@@ -96,6 +96,10 @@ namespace llvm {
|
|||||||
///
|
///
|
||||||
SmallPtrSet<MachineInstr*, 32> JoinedCopies;
|
SmallPtrSet<MachineInstr*, 32> JoinedCopies;
|
||||||
|
|
||||||
|
/// ReMatCopies - Keep track of copies eliminated due to remat.
|
||||||
|
///
|
||||||
|
SmallPtrSet<MachineInstr*, 32> ReMatCopies;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static char ID; // Pass identifcation, replacement for typeid
|
static char ID; // Pass identifcation, replacement for typeid
|
||||||
SimpleRegisterCoalescing() : MachineFunctionPass((intptr_t)&ID) {}
|
SimpleRegisterCoalescing() : MachineFunctionPass((intptr_t)&ID) {}
|
||||||
@@ -194,6 +198,9 @@ namespace llvm {
|
|||||||
bool RemoveCopyByCommutingDef(LiveInterval &IntA, LiveInterval &IntB,
|
bool RemoveCopyByCommutingDef(LiveInterval &IntA, LiveInterval &IntB,
|
||||||
MachineInstr *CopyMI);
|
MachineInstr *CopyMI);
|
||||||
|
|
||||||
|
bool ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg,
|
||||||
|
MachineInstr *CopyMI);
|
||||||
|
|
||||||
/// TurnCopyIntoImpDef - If source of the specified copy is an implicit def,
|
/// TurnCopyIntoImpDef - If source of the specified copy is an implicit def,
|
||||||
/// turn the copy into an implicit def.
|
/// turn the copy into an implicit def.
|
||||||
bool TurnCopyIntoImpDef(MachineBasicBlock::iterator &I,
|
bool TurnCopyIntoImpDef(MachineBasicBlock::iterator &I,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | not grep movd
|
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movd | count 1
|
||||||
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movq
|
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movq
|
||||||
; PR2677
|
; PR2677
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
; RUN: llvm-as < %s | llc -mcpu=yonah
|
; RUN: llvm-as < %s | llc -mcpu=yonah | grep pxor | count 2
|
||||||
|
; RUN: llvm-as < %s | llc -mcpu=yonah | not grep movapd
|
||||||
; PR2715
|
; PR2715
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
%struct.XPTTypeDescriptorPrefix = type { i8 }
|
%struct.XPTTypeDescriptorPrefix = type { i8 }
|
||||||
|
Reference in New Issue
Block a user