summaryrefslogtreecommitdiff
path: root/lib/CodeGen/PostRASchedulerList.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-10-01 08:26:23 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-10-01 08:26:23 +0000
commit714e8bc1fc415050e557272326a75b50ac54d2bb (patch)
tree6ea8306e0a87df921e6a4974c2cd395c4b563c48 /lib/CodeGen/PostRASchedulerList.cpp
parent0d92f5f76884513f8f5e014c61cb7a72ff576fa5 (diff)
downloadllvm-714e8bc1fc415050e557272326a75b50ac54d2bb.tar.gz
llvm-714e8bc1fc415050e557272326a75b50ac54d2bb.tar.bz2
llvm-714e8bc1fc415050e557272326a75b50ac54d2bb.tar.xz
Observe hasExtraSrcRegAllocReq and hasExtraDefRegAllocReq. Do not change
operands of instructions with these properties while breaking anti-dep. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83198 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/PostRASchedulerList.cpp')
-rw-r--r--lib/CodeGen/PostRASchedulerList.cpp73
1 files changed, 55 insertions, 18 deletions
diff --git a/lib/CodeGen/PostRASchedulerList.cpp b/lib/CodeGen/PostRASchedulerList.cpp
index 5fa598d95b..8d746142d1 100644
--- a/lib/CodeGen/PostRASchedulerList.cpp
+++ b/lib/CodeGen/PostRASchedulerList.cpp
@@ -123,14 +123,18 @@ namespace {
/// RegRegs - Map registers to all their references within a live range.
std::multimap<unsigned, MachineOperand *> RegRefs;
- /// The index of the most recent kill (proceding bottom-up), or ~0u if
- /// the register is not live.
+ /// KillIndices - The index of the most recent kill (proceding bottom-up),
+ /// or ~0u if the register is not live.
unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister];
- /// The index of the most recent complete def (proceding bottom up), or ~0u
- /// if the register is live.
+ /// DefIndices - The index of the most recent complete def (proceding bottom
+ /// up), or ~0u if the register is live.
unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister];
+ /// KeepRegs - A set of registers which are live and cannot be changed to
+ /// break anti-dependencies.
+ SmallSet<unsigned, 4> KeepRegs;
+
public:
SchedulePostRATDList(MachineFunction &MF,
const MachineLoopInfo &MLI,
@@ -293,6 +297,9 @@ void SchedulePostRATDList::StartBlock(MachineBasicBlock *BB) {
std::fill(KillIndices, array_endof(KillIndices), ~0u);
std::fill(DefIndices, array_endof(DefIndices), BB->size());
+ // Clear "do not change" set.
+ KeepRegs.clear();
+
// Determine the live-out physregs for this block.
if (!BB->empty() && BB->back().getDesc().isReturn())
// In a return block, examine the function live-out regs.
@@ -495,9 +502,10 @@ void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,
DefIndices[Reg] = Count;
KillIndices[Reg] = ~0u;
- assert(((KillIndices[Reg] == ~0u) !=
- (DefIndices[Reg] == ~0u)) &&
- "Kill and Def maps aren't consistent for Reg!");
+ assert(((KillIndices[Reg] == ~0u) !=
+ (DefIndices[Reg] == ~0u)) &&
+ "Kill and Def maps aren't consistent for Reg!");
+ KeepRegs.erase(Reg);
Classes[Reg] = 0;
RegRefs.erase(Reg);
// Repeat, for all subregs.
@@ -506,6 +514,7 @@ void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,
unsigned SubregReg = *Subreg;
DefIndices[SubregReg] = Count;
KillIndices[SubregReg] = ~0u;
+ KeepRegs.erase(SubregReg);
Classes[SubregReg] = 0;
RegRefs.erase(SubregReg);
}
@@ -690,8 +699,12 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
if (Edge->getKind() == SDep::Anti) {
AntiDepReg = Edge->getReg();
assert(AntiDepReg != 0 && "Anti-dependence on reg0?");
- // Don't break anti-dependencies on non-allocatable registers.
if (!AllocatableSet.test(AntiDepReg))
+ // Don't break anti-dependencies on non-allocatable registers.
+ AntiDepReg = 0;
+ else if (KeepRegs.count(AntiDepReg))
+ // Don't break anti-dependencies if an use down below requires
+ // this exact register.
AntiDepReg = 0;
else {
// If the SUnit has other dependencies on the SUnit that it
@@ -723,16 +736,40 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
PrescanInstruction(MI);
- // If this instruction has a use of AntiDepReg, breaking it
- // is invalid.
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- MachineOperand &MO = MI->getOperand(i);
- if (!MO.isReg()) continue;
- unsigned Reg = MO.getReg();
- if (Reg == 0) continue;
- if (MO.isUse() && AntiDepReg == Reg) {
- AntiDepReg = 0;
- break;
+ if (MI->getDesc().hasExtraSrcRegAllocReq()) {
+ // It's not safe to change register allocation for source operands of
+ // that have special allocation requirements.
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg()) continue;
+ unsigned Reg = MO.getReg();
+ if (Reg == 0) continue;
+ if (MO.isUse()) {
+ if (KeepRegs.insert(Reg)) {
+ for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
+ *Subreg; ++Subreg)
+ KeepRegs.insert(*Subreg);
+ }
+ }
+ }
+ }
+
+ if (MI->getDesc().hasExtraDefRegAllocReq())
+ // If this instruction's defs have special allocation requirement, don't
+ // break this anti-dependency.
+ AntiDepReg = 0;
+ else if (AntiDepReg) {
+ // If this instruction has a use of AntiDepReg, breaking it
+ // is invalid.
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg()) continue;
+ unsigned Reg = MO.getReg();
+ if (Reg == 0) continue;
+ if (MO.isUse() && AntiDepReg == Reg) {
+ AntiDepReg = 0;
+ break;
+ }
}
}