mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Refactor. No intentional functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146187 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
73e08d3507
commit
e265bcf1a6
@ -90,6 +90,8 @@ namespace {
|
|||||||
bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB,
|
bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB,
|
||||||
MachineBasicBlock *DefMBB,
|
MachineBasicBlock *DefMBB,
|
||||||
bool &BreakPHIEdge, bool &LocalUse) const;
|
bool &BreakPHIEdge, bool &LocalUse) const;
|
||||||
|
MachineBasicBlock *FindSuccToSinkTo(MachineInstr *MI, bool &BreakPHIEdge);
|
||||||
|
|
||||||
bool PerformTrivialForwardCoalescing(MachineInstr *MI,
|
bool PerformTrivialForwardCoalescing(MachineInstr *MI,
|
||||||
MachineBasicBlock *MBB);
|
MachineBasicBlock *MBB);
|
||||||
};
|
};
|
||||||
@ -401,25 +403,9 @@ static void collectDebugValues(MachineInstr *MI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SinkInstruction - Determine whether it is safe to sink the specified machine
|
/// FindSuccToSinkTo - Find a successor to sink this instruction to.
|
||||||
/// instruction out of its current block into a successor.
|
MachineBasicBlock *MachineSinking::FindSuccToSinkTo(MachineInstr *MI,
|
||||||
bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
bool &BreakPHIEdge) {
|
||||||
// Don't sink insert_subreg, subreg_to_reg, reg_sequence. These are meant to
|
|
||||||
// be close to the source to make it easier to coalesce.
|
|
||||||
if (AvoidsSinking(MI, MRI))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if it's safe to move the instruction.
|
|
||||||
if (!MI->isSafeToMove(TII, AA, SawStore))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// FIXME: This should include support for sinking instructions within the
|
|
||||||
// block they are currently in to shorten the live ranges. We often get
|
|
||||||
// instructions sunk into the top of a large block, but it would be better to
|
|
||||||
// also sink them down before their first use in the block. This xform has to
|
|
||||||
// be careful not to *increase* register pressure though, e.g. sinking
|
|
||||||
// "x = y + z" down if it kills y and z would increase the live ranges of y
|
|
||||||
// and z and only shrink the live range of x.
|
|
||||||
|
|
||||||
// Loop over all the operands of the specified instruction. If there is
|
// Loop over all the operands of the specified instruction. If there is
|
||||||
// anything we can't handle, bail out.
|
// anything we can't handle, bail out.
|
||||||
@ -429,7 +415,6 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
// decide.
|
// decide.
|
||||||
MachineBasicBlock *SuccToSinkTo = 0;
|
MachineBasicBlock *SuccToSinkTo = 0;
|
||||||
|
|
||||||
bool BreakPHIEdge = false;
|
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI->getOperand(i);
|
||||||
if (!MO.isReg()) continue; // Ignore non-register operands.
|
if (!MO.isReg()) continue; // Ignore non-register operands.
|
||||||
@ -443,23 +428,23 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
// and we can freely move its uses. Alternatively, if it's allocatable,
|
// and we can freely move its uses. Alternatively, if it's allocatable,
|
||||||
// it could get allocated to something with a def during allocation.
|
// it could get allocated to something with a def during allocation.
|
||||||
if (!MRI->def_empty(Reg))
|
if (!MRI->def_empty(Reg))
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
if (AllocatableSet.test(Reg))
|
if (AllocatableSet.test(Reg))
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
// Check for a def among the register's aliases too.
|
// Check for a def among the register's aliases too.
|
||||||
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
|
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
|
||||||
unsigned AliasReg = *Alias;
|
unsigned AliasReg = *Alias;
|
||||||
if (!MRI->def_empty(AliasReg))
|
if (!MRI->def_empty(AliasReg))
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
if (AllocatableSet.test(AliasReg))
|
if (AllocatableSet.test(AliasReg))
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else if (!MO.isDead()) {
|
} else if (!MO.isDead()) {
|
||||||
// A def that isn't dead. We can't move it.
|
// A def that isn't dead. We can't move it.
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Virtual register uses are always safe to sink.
|
// Virtual register uses are always safe to sink.
|
||||||
@ -467,7 +452,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
|
|
||||||
// If it's not safe to move defs of the register class, then abort.
|
// If it's not safe to move defs of the register class, then abort.
|
||||||
if (!TII->isSafeToMoveRegClassDefs(MRI->getRegClass(Reg)))
|
if (!TII->isSafeToMoveRegClassDefs(MRI->getRegClass(Reg)))
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
// FIXME: This picks a successor to sink into based on having one
|
// FIXME: This picks a successor to sink into based on having one
|
||||||
// successor that dominates all the uses. However, there are cases where
|
// successor that dominates all the uses. However, there are cases where
|
||||||
@ -490,7 +475,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
bool LocalUse = false;
|
bool LocalUse = false;
|
||||||
if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, ParentBlock,
|
if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, ParentBlock,
|
||||||
BreakPHIEdge, LocalUse))
|
BreakPHIEdge, LocalUse))
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -518,14 +503,39 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
}
|
}
|
||||||
if (LocalUse)
|
if (LocalUse)
|
||||||
// Def is used locally, it's never safe to move this def.
|
// Def is used locally, it's never safe to move this def.
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we couldn't find a block to sink to, ignore this instruction.
|
// If we couldn't find a block to sink to, ignore this instruction.
|
||||||
if (SuccToSinkTo == 0)
|
if (SuccToSinkTo == 0)
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return SuccToSinkTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SinkInstruction - Determine whether it is safe to sink the specified machine
|
||||||
|
/// instruction out of its current block into a successor.
|
||||||
|
bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
||||||
|
// Don't sink insert_subreg, subreg_to_reg, reg_sequence. These are meant to
|
||||||
|
// be close to the source to make it easier to coalesce.
|
||||||
|
if (AvoidsSinking(MI, MRI))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if it's safe to move the instruction.
|
||||||
|
if (!MI->isSafeToMove(TII, AA, SawStore))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// FIXME: This should include support for sinking instructions within the
|
||||||
|
// block they are currently in to shorten the live ranges. We often get
|
||||||
|
// instructions sunk into the top of a large block, but it would be better to
|
||||||
|
// also sink them down before their first use in the block. This xform has to
|
||||||
|
// be careful not to *increase* register pressure though, e.g. sinking
|
||||||
|
// "x = y + z" down if it kills y and z would increase the live ranges of y
|
||||||
|
// and z and only shrink the live range of x.
|
||||||
|
|
||||||
|
bool BreakPHIEdge = false;
|
||||||
|
MachineBasicBlock *SuccToSinkTo = FindSuccToSinkTo(MI, BreakPHIEdge);
|
||||||
|
|
||||||
// If there are no outputs, it must have side-effects.
|
// If there are no outputs, it must have side-effects.
|
||||||
if (SuccToSinkTo == 0)
|
if (SuccToSinkTo == 0)
|
||||||
@ -546,6 +556,8 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
|
|
||||||
DEBUG(dbgs() << "Sink instr " << *MI << "\tinto block " << *SuccToSinkTo);
|
DEBUG(dbgs() << "Sink instr " << *MI << "\tinto block " << *SuccToSinkTo);
|
||||||
|
|
||||||
|
MachineBasicBlock *ParentBlock = MI->getParent();
|
||||||
|
|
||||||
// If the block has multiple predecessors, this would introduce computation on
|
// If the block has multiple predecessors, this would introduce computation on
|
||||||
// a path that it doesn't already exist. We could split the critical edge,
|
// a path that it doesn't already exist. We could split the critical edge,
|
||||||
// but for now we just punt.
|
// but for now we just punt.
|
||||||
|
Loading…
Reference in New Issue
Block a user