mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
When scheduling a block in parts, keep track of the overall
instruction index across each part. Instruction indices are used to make live range queries, and live ranges can extend beyond scheduling region boundaries. Refactor the ScheduleDAGSDNodes class some more so that it doesn't have to worry about this additional information. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64288 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ca70533d3d
commit
47ac0f0c7c
@ -31,7 +31,6 @@ namespace llvm {
|
|||||||
class MachineInstr;
|
class MachineInstr;
|
||||||
class TargetRegisterInfo;
|
class TargetRegisterInfo;
|
||||||
class ScheduleDAG;
|
class ScheduleDAG;
|
||||||
class SelectionDAG;
|
|
||||||
class SDNode;
|
class SDNode;
|
||||||
class TargetInstrInfo;
|
class TargetInstrInfo;
|
||||||
class TargetInstrDesc;
|
class TargetInstrDesc;
|
||||||
@ -426,10 +425,8 @@ namespace llvm {
|
|||||||
|
|
||||||
class ScheduleDAG {
|
class ScheduleDAG {
|
||||||
public:
|
public:
|
||||||
SelectionDAG *DAG; // DAG of the current basic block
|
MachineBasicBlock *BB; // The block in which to insert instructions.
|
||||||
MachineBasicBlock *BB; // Current basic block
|
MachineBasicBlock::iterator InsertPos;// The position to insert instructions.
|
||||||
MachineBasicBlock::iterator Begin; // The beginning of the range to be scheduled.
|
|
||||||
MachineBasicBlock::iterator End; // The end of the range to be scheduled.
|
|
||||||
const TargetMachine &TM; // Target processor
|
const TargetMachine &TM; // Target processor
|
||||||
const TargetInstrInfo *TII; // Target instruction information
|
const TargetInstrInfo *TII; // Target instruction information
|
||||||
const TargetRegisterInfo *TRI; // Target processor register info
|
const TargetRegisterInfo *TRI; // Target processor register info
|
||||||
@ -452,12 +449,6 @@ namespace llvm {
|
|||||||
///
|
///
|
||||||
void viewGraph();
|
void viewGraph();
|
||||||
|
|
||||||
/// Run - perform scheduling.
|
|
||||||
///
|
|
||||||
void Run(SelectionDAG *DAG, MachineBasicBlock *MBB,
|
|
||||||
MachineBasicBlock::iterator Begin,
|
|
||||||
MachineBasicBlock::iterator End);
|
|
||||||
|
|
||||||
/// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
|
/// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
|
||||||
/// according to the order specified in Sequence.
|
/// according to the order specified in Sequence.
|
||||||
///
|
///
|
||||||
@ -482,6 +473,10 @@ namespace llvm {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/// Run - perform scheduling.
|
||||||
|
///
|
||||||
|
void Run(MachineBasicBlock *bb, MachineBasicBlock::iterator insertPos);
|
||||||
|
|
||||||
/// BuildSchedGraph - Build SUnits and set up their Preds and Succs
|
/// BuildSchedGraph - Build SUnits and set up their Preds and Succs
|
||||||
/// to form the scheduling dependency graph.
|
/// to form the scheduling dependency graph.
|
||||||
///
|
///
|
||||||
|
@ -26,13 +26,13 @@ namespace llvm {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
class SelectionDAGISel;
|
class SelectionDAGISel;
|
||||||
class ScheduleDAG;
|
class ScheduleDAGSDNodes;
|
||||||
class SelectionDAG;
|
class SelectionDAG;
|
||||||
class MachineBasicBlock;
|
class MachineBasicBlock;
|
||||||
|
|
||||||
class RegisterScheduler : public MachinePassRegistryNode {
|
class RegisterScheduler : public MachinePassRegistryNode {
|
||||||
public:
|
public:
|
||||||
typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, bool);
|
typedef ScheduleDAGSDNodes *(*FunctionPassCtor)(SelectionDAGISel*, bool);
|
||||||
|
|
||||||
static MachinePassRegistry Registry;
|
static MachinePassRegistry Registry;
|
||||||
|
|
||||||
@ -63,28 +63,28 @@ public:
|
|||||||
|
|
||||||
/// createBURRListDAGScheduler - This creates a bottom up register usage
|
/// createBURRListDAGScheduler - This creates a bottom up register usage
|
||||||
/// reduction list scheduler.
|
/// reduction list scheduler.
|
||||||
ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
|
ScheduleDAGSDNodes *createBURRListDAGScheduler(SelectionDAGISel *IS,
|
||||||
bool Fast);
|
bool Fast);
|
||||||
|
|
||||||
/// createTDRRListDAGScheduler - This creates a top down register usage
|
/// createTDRRListDAGScheduler - This creates a top down register usage
|
||||||
/// reduction list scheduler.
|
/// reduction list scheduler.
|
||||||
ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
|
ScheduleDAGSDNodes *createTDRRListDAGScheduler(SelectionDAGISel *IS,
|
||||||
bool Fast);
|
bool Fast);
|
||||||
|
|
||||||
/// createTDListDAGScheduler - This creates a top-down list scheduler with
|
/// createTDListDAGScheduler - This creates a top-down list scheduler with
|
||||||
/// a hazard recognizer.
|
/// a hazard recognizer.
|
||||||
ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
|
ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS,
|
||||||
bool Fast);
|
bool Fast);
|
||||||
|
|
||||||
/// createFastDAGScheduler - This creates a "fast" scheduler.
|
/// createFastDAGScheduler - This creates a "fast" scheduler.
|
||||||
///
|
///
|
||||||
ScheduleDAG *createFastDAGScheduler(SelectionDAGISel *IS,
|
ScheduleDAGSDNodes *createFastDAGScheduler(SelectionDAGISel *IS,
|
||||||
bool Fast);
|
bool Fast);
|
||||||
|
|
||||||
/// createDefaultScheduler - This creates an instruction scheduler appropriate
|
/// createDefaultScheduler - This creates an instruction scheduler appropriate
|
||||||
/// for the target.
|
/// for the target.
|
||||||
ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
|
ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
|
||||||
bool Fast);
|
bool Fast);
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace llvm {
|
|||||||
class FunctionLoweringInfo;
|
class FunctionLoweringInfo;
|
||||||
class ScheduleHazardRecognizer;
|
class ScheduleHazardRecognizer;
|
||||||
class GCFunctionInfo;
|
class GCFunctionInfo;
|
||||||
class ScheduleDAG;
|
class ScheduleDAGSDNodes;
|
||||||
|
|
||||||
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
|
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
|
||||||
/// pattern-matching instruction selectors.
|
/// pattern-matching instruction selectors.
|
||||||
@ -133,7 +133,7 @@ private:
|
|||||||
/// via the SchedulerRegistry, use it, otherwise select the
|
/// via the SchedulerRegistry, use it, otherwise select the
|
||||||
/// one preferred by the target.
|
/// one preferred by the target.
|
||||||
///
|
///
|
||||||
ScheduleDAG *CreateScheduler();
|
ScheduleDAGSDNodes *CreateScheduler();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ namespace {
|
|||||||
/// Observe - Update liveness information to account for the current
|
/// Observe - Update liveness information to account for the current
|
||||||
/// instruction, which will not be scheduled.
|
/// instruction, which will not be scheduled.
|
||||||
///
|
///
|
||||||
void Observe(MachineInstr *MI);
|
void Observe(MachineInstr *MI, unsigned Count);
|
||||||
|
|
||||||
/// FinishBlock - Clean up register live-range state.
|
/// FinishBlock - Clean up register live-range state.
|
||||||
///
|
///
|
||||||
@ -254,19 +254,26 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
|
|||||||
// Schedule each sequence of instructions not interrupted by a label
|
// Schedule each sequence of instructions not interrupted by a label
|
||||||
// or anything else that effectively needs to shut down scheduling.
|
// or anything else that effectively needs to shut down scheduling.
|
||||||
MachineBasicBlock::iterator Current = MBB->end();
|
MachineBasicBlock::iterator Current = MBB->end();
|
||||||
|
unsigned Count = MBB->size(), CurrentCount = Count;
|
||||||
for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) {
|
for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) {
|
||||||
MachineInstr *MI = prior(I);
|
MachineInstr *MI = prior(I);
|
||||||
if (isSchedulingBoundary(MI, Fn)) {
|
if (isSchedulingBoundary(MI, Fn)) {
|
||||||
if (I != Current) {
|
if (I != Current) {
|
||||||
Scheduler.Run(0, MBB, I, Current);
|
Scheduler.Run(MBB, I, Current, CurrentCount);
|
||||||
Scheduler.EmitSchedule();
|
Scheduler.EmitSchedule();
|
||||||
}
|
}
|
||||||
Scheduler.Observe(MI);
|
Scheduler.Observe(MI, Count);
|
||||||
Current = MI;
|
Current = MI;
|
||||||
|
CurrentCount = Count - 1;
|
||||||
}
|
}
|
||||||
I = MI;
|
I = MI;
|
||||||
|
--Count;
|
||||||
|
}
|
||||||
|
assert(Count == 0 && "Instruction count mismatch!");
|
||||||
|
if (MBB->begin() != Current) {
|
||||||
|
assert(CurrentCount != 0 && "Instruction count mismatch!");
|
||||||
|
Scheduler.Run(MBB, MBB->begin(), Current, CurrentCount);
|
||||||
}
|
}
|
||||||
Scheduler.Run(0, MBB, MBB->begin(), Current);
|
|
||||||
Scheduler.EmitSchedule();
|
Scheduler.EmitSchedule();
|
||||||
|
|
||||||
// Clean up register live-range state.
|
// Clean up register live-range state.
|
||||||
@ -384,9 +391,9 @@ void SchedulePostRATDList::Schedule() {
|
|||||||
/// Observe - Update liveness information to account for the current
|
/// Observe - Update liveness information to account for the current
|
||||||
/// instruction, which will not be scheduled.
|
/// instruction, which will not be scheduled.
|
||||||
///
|
///
|
||||||
void SchedulePostRATDList::Observe(MachineInstr *MI) {
|
void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) {
|
||||||
PrescanInstruction(MI);
|
PrescanInstruction(MI);
|
||||||
ScanInstruction(MI, 0);
|
ScanInstruction(MI, Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FinishBlock - Clean up register live-range state.
|
/// FinishBlock - Clean up register live-range state.
|
||||||
@ -484,6 +491,9 @@ void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,
|
|||||||
|
|
||||||
DefIndices[Reg] = Count;
|
DefIndices[Reg] = Count;
|
||||||
KillIndices[Reg] = ~0u;
|
KillIndices[Reg] = ~0u;
|
||||||
|
assert(((KillIndices[Reg] == ~0u) !=
|
||||||
|
(DefIndices[Reg] == ~0u)) &&
|
||||||
|
"Kill and Def maps aren't consistent for Reg!");
|
||||||
Classes[Reg] = 0;
|
Classes[Reg] = 0;
|
||||||
RegRefs.erase(Reg);
|
RegRefs.erase(Reg);
|
||||||
// Repeat, for all subregs.
|
// Repeat, for all subregs.
|
||||||
@ -525,6 +535,9 @@ void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,
|
|||||||
if (KillIndices[Reg] == ~0u) {
|
if (KillIndices[Reg] == ~0u) {
|
||||||
KillIndices[Reg] = Count;
|
KillIndices[Reg] = Count;
|
||||||
DefIndices[Reg] = ~0u;
|
DefIndices[Reg] = ~0u;
|
||||||
|
assert(((KillIndices[Reg] == ~0u) !=
|
||||||
|
(DefIndices[Reg] == ~0u)) &&
|
||||||
|
"Kill and Def maps aren't consistent for Reg!");
|
||||||
}
|
}
|
||||||
// Repeat, for all aliases.
|
// Repeat, for all aliases.
|
||||||
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
|
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
|
||||||
@ -608,8 +621,8 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
|
|||||||
// instructions from the bottom up, tracking information about liveness
|
// instructions from the bottom up, tracking information about liveness
|
||||||
// as we go to help determine which registers are available.
|
// as we go to help determine which registers are available.
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
unsigned Count = SUnits.size() - 1;
|
unsigned Count = InsertPosIndex - 1;
|
||||||
for (MachineBasicBlock::iterator I = End, E = Begin;
|
for (MachineBasicBlock::iterator I = InsertPos, E = Begin;
|
||||||
I != E; --Count) {
|
I != E; --Count) {
|
||||||
MachineInstr *MI = --I;
|
MachineInstr *MI = --I;
|
||||||
|
|
||||||
@ -739,10 +752,16 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
|
|||||||
Classes[NewReg] = Classes[AntiDepReg];
|
Classes[NewReg] = Classes[AntiDepReg];
|
||||||
DefIndices[NewReg] = DefIndices[AntiDepReg];
|
DefIndices[NewReg] = DefIndices[AntiDepReg];
|
||||||
KillIndices[NewReg] = KillIndices[AntiDepReg];
|
KillIndices[NewReg] = KillIndices[AntiDepReg];
|
||||||
|
assert(((KillIndices[NewReg] == ~0u) !=
|
||||||
|
(DefIndices[NewReg] == ~0u)) &&
|
||||||
|
"Kill and Def maps aren't consistent for NewReg!");
|
||||||
|
|
||||||
Classes[AntiDepReg] = 0;
|
Classes[AntiDepReg] = 0;
|
||||||
DefIndices[AntiDepReg] = KillIndices[AntiDepReg];
|
DefIndices[AntiDepReg] = KillIndices[AntiDepReg];
|
||||||
KillIndices[AntiDepReg] = ~0u;
|
KillIndices[AntiDepReg] = ~0u;
|
||||||
|
assert(((KillIndices[AntiDepReg] == ~0u) !=
|
||||||
|
(DefIndices[AntiDepReg] == ~0u)) &&
|
||||||
|
"Kill and Def maps aren't consistent for AntiDepReg!");
|
||||||
|
|
||||||
RegRefs.erase(AntiDepReg);
|
RegRefs.erase(AntiDepReg);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
@ -754,7 +773,6 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
|
|||||||
|
|
||||||
ScanInstruction(MI, Count);
|
ScanInstruction(MI, Count);
|
||||||
}
|
}
|
||||||
assert(Count == ~0u && "Count mismatch!");
|
|
||||||
|
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
ScheduleDAG::ScheduleDAG(MachineFunction &mf)
|
ScheduleDAG::ScheduleDAG(MachineFunction &mf)
|
||||||
: DAG(0), BB(0), TM(mf.getTarget()),
|
: TM(mf.getTarget()),
|
||||||
TII(TM.getInstrInfo()),
|
TII(TM.getInstrInfo()),
|
||||||
TRI(TM.getRegisterInfo()),
|
TRI(TM.getRegisterInfo()),
|
||||||
TLI(TM.getTargetLowering()),
|
TLI(TM.getTargetLowering()),
|
||||||
@ -47,18 +47,13 @@ void ScheduleDAG::dumpSchedule() const {
|
|||||||
|
|
||||||
/// Run - perform scheduling.
|
/// Run - perform scheduling.
|
||||||
///
|
///
|
||||||
void ScheduleDAG::Run(SelectionDAG *dag, MachineBasicBlock *bb,
|
void ScheduleDAG::Run(MachineBasicBlock *bb,
|
||||||
MachineBasicBlock::iterator begin,
|
MachineBasicBlock::iterator insertPos) {
|
||||||
MachineBasicBlock::iterator end) {
|
BB = bb;
|
||||||
assert((!dag || begin == end) &&
|
InsertPos = insertPos;
|
||||||
"An instruction range was given for SelectionDAG scheduling!");
|
|
||||||
|
|
||||||
SUnits.clear();
|
SUnits.clear();
|
||||||
Sequence.clear();
|
Sequence.clear();
|
||||||
DAG = dag;
|
|
||||||
BB = bb;
|
|
||||||
Begin = begin;
|
|
||||||
End = end;
|
|
||||||
EntrySU = SUnit();
|
EntrySU = SUnit();
|
||||||
ExitSU = SUnit();
|
ExitSU = SUnit();
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ void ScheduleDAG::AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ScheduleDAG::EmitNoop() {
|
void ScheduleDAG::EmitNoop() {
|
||||||
TII->insertNoop(*BB, End);
|
TII->insertNoop(*BB, InsertPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScheduleDAG::EmitPhysRegCopy(SUnit *SU,
|
void ScheduleDAG::EmitPhysRegCopy(SUnit *SU,
|
||||||
@ -54,7 +54,7 @@ void ScheduleDAG::EmitPhysRegCopy(SUnit *SU,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TII->copyRegToReg(*BB, End, Reg, VRI->second,
|
TII->copyRegToReg(*BB, InsertPos, Reg, VRI->second,
|
||||||
SU->CopyDstRC, SU->CopySrcRC);
|
SU->CopyDstRC, SU->CopySrcRC);
|
||||||
} else {
|
} else {
|
||||||
// Copy from physical register.
|
// Copy from physical register.
|
||||||
@ -63,7 +63,7 @@ void ScheduleDAG::EmitPhysRegCopy(SUnit *SU,
|
|||||||
bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second;
|
bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second;
|
||||||
isNew = isNew; // Silence compiler warning.
|
isNew = isNew; // Silence compiler warning.
|
||||||
assert(isNew && "Node emitted out of order - early");
|
assert(isNew && "Node emitted out of order - early");
|
||||||
TII->copyRegToReg(*BB, End, VRBase, I->getReg(),
|
TII->copyRegToReg(*BB, InsertPos, VRBase, I->getReg(),
|
||||||
SU->CopyDstRC, SU->CopySrcRC);
|
SU->CopyDstRC, SU->CopySrcRC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -32,6 +32,19 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
|
|||||||
const MachineDominatorTree &mdt)
|
const MachineDominatorTree &mdt)
|
||||||
: ScheduleDAG(mf), MLI(mli), MDT(mdt), LoopRegs(MLI, MDT) {}
|
: ScheduleDAG(mf), MLI(mli), MDT(mdt), LoopRegs(MLI, MDT) {}
|
||||||
|
|
||||||
|
/// Run - perform scheduling.
|
||||||
|
///
|
||||||
|
void ScheduleDAGInstrs::Run(MachineBasicBlock *bb,
|
||||||
|
MachineBasicBlock::iterator begin,
|
||||||
|
MachineBasicBlock::iterator end,
|
||||||
|
unsigned endcount) {
|
||||||
|
BB = bb;
|
||||||
|
Begin = begin;
|
||||||
|
InsertPosIndex = endcount;
|
||||||
|
|
||||||
|
ScheduleDAG::Run(bb, end);
|
||||||
|
}
|
||||||
|
|
||||||
/// getOpcode - If this is an Instruction or a ConstantExpr, return the
|
/// getOpcode - If this is an Instruction or a ConstantExpr, return the
|
||||||
/// opcode value. Otherwise return UserOp1.
|
/// opcode value. Otherwise return UserOp1.
|
||||||
static unsigned getOpcode(const Value *V) {
|
static unsigned getOpcode(const Value *V) {
|
||||||
@ -146,7 +159,7 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
|
|||||||
TM.getSubtarget<TargetSubtarget>().getSpecialAddressLatency();
|
TM.getSubtarget<TargetSubtarget>().getSpecialAddressLatency();
|
||||||
|
|
||||||
// Walk the list of instructions, from bottom moving up.
|
// Walk the list of instructions, from bottom moving up.
|
||||||
for (MachineBasicBlock::iterator MII = End, MIE = Begin;
|
for (MachineBasicBlock::iterator MII = InsertPos, MIE = Begin;
|
||||||
MII != MIE; --MII) {
|
MII != MIE; --MII) {
|
||||||
MachineInstr *MI = prior(MII);
|
MachineInstr *MI = prior(MII);
|
||||||
const TargetInstrDesc &TID = MI->getDesc();
|
const TargetInstrDesc &TID = MI->getDesc();
|
||||||
@ -428,7 +441,7 @@ std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const {
|
|||||||
MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() {
|
MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() {
|
||||||
// For MachineInstr-based scheduling, we're rescheduling the instructions in
|
// For MachineInstr-based scheduling, we're rescheduling the instructions in
|
||||||
// the block, so start by removing them from the block.
|
// the block, so start by removing them from the block.
|
||||||
while (Begin != End) {
|
while (Begin != InsertPos) {
|
||||||
MachineBasicBlock::iterator I = Begin;
|
MachineBasicBlock::iterator I = Begin;
|
||||||
++Begin;
|
++Begin;
|
||||||
BB->remove(I);
|
BB->remove(I);
|
||||||
@ -443,7 +456,7 @@ MachineBasicBlock *ScheduleDAGInstrs::EmitSchedule() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BB->insert(End, SU->getInstr());
|
BB->insert(InsertPos, SU->getInstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the Begin iterator, as the first instruction in the block
|
// Update the Begin iterator, as the first instruction in the block
|
||||||
|
@ -120,6 +120,12 @@ namespace llvm {
|
|||||||
SmallSet<unsigned, 8> LoopLiveInRegs;
|
SmallSet<unsigned, 8> LoopLiveInRegs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
MachineBasicBlock *BB; // Current basic block
|
||||||
|
MachineBasicBlock::iterator Begin; // The beginning of the range to
|
||||||
|
// be scheduled. The range extends
|
||||||
|
// to InsertPos.
|
||||||
|
unsigned InsertPosIndex; // The index in BB of InsertPos.
|
||||||
|
|
||||||
explicit ScheduleDAGInstrs(MachineFunction &mf,
|
explicit ScheduleDAGInstrs(MachineFunction &mf,
|
||||||
const MachineLoopInfo &mli,
|
const MachineLoopInfo &mli,
|
||||||
const MachineDominatorTree &mdt);
|
const MachineDominatorTree &mdt);
|
||||||
@ -139,6 +145,13 @@ namespace llvm {
|
|||||||
return &SUnits.back();
|
return &SUnits.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run - perform scheduling.
|
||||||
|
///
|
||||||
|
void Run(MachineBasicBlock *bb,
|
||||||
|
MachineBasicBlock::iterator begin,
|
||||||
|
MachineBasicBlock::iterator end,
|
||||||
|
unsigned endindex);
|
||||||
|
|
||||||
/// BuildSchedGraph - Build SUnits from the MachineBasicBlock that we are
|
/// BuildSchedGraph - Build SUnits from the MachineBasicBlock that we are
|
||||||
/// input.
|
/// input.
|
||||||
virtual void BuildSchedGraph();
|
virtual void BuildSchedGraph();
|
||||||
|
@ -629,6 +629,7 @@ void ScheduleDAGFast::ListScheduleBottomUp() {
|
|||||||
// Public Constructor Functions
|
// Public Constructor Functions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
llvm::ScheduleDAG* llvm::createFastDAGScheduler(SelectionDAGISel *IS, bool) {
|
llvm::ScheduleDAGSDNodes *
|
||||||
|
llvm::createFastDAGScheduler(SelectionDAGISel *IS, bool) {
|
||||||
return new ScheduleDAGFast(*IS->MF);
|
return new ScheduleDAGFast(*IS->MF);
|
||||||
}
|
}
|
||||||
|
@ -260,8 +260,8 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
|||||||
/// createTDListDAGScheduler - This creates a top-down list scheduler with a
|
/// createTDListDAGScheduler - This creates a top-down list scheduler with a
|
||||||
/// new hazard recognizer. This scheduler takes ownership of the hazard
|
/// new hazard recognizer. This scheduler takes ownership of the hazard
|
||||||
/// recognizer and deletes it when done.
|
/// recognizer and deletes it when done.
|
||||||
ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAGISel *IS,
|
ScheduleDAGSDNodes *
|
||||||
bool Fast) {
|
llvm::createTDListDAGScheduler(SelectionDAGISel *IS, bool Fast) {
|
||||||
return new ScheduleDAGList(*IS->MF,
|
return new ScheduleDAGList(*IS->MF,
|
||||||
new LatencyPriorityQueue(),
|
new LatencyPriorityQueue(),
|
||||||
IS->CreateTargetHazardRecognizer());
|
IS->CreateTargetHazardRecognizer());
|
||||||
|
@ -1358,8 +1358,8 @@ bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
|
|||||||
// Public Constructor Functions
|
// Public Constructor Functions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS,
|
llvm::ScheduleDAGSDNodes *
|
||||||
bool) {
|
llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, bool) {
|
||||||
const TargetMachine &TM = IS->TM;
|
const TargetMachine &TM = IS->TM;
|
||||||
const TargetInstrInfo *TII = TM.getInstrInfo();
|
const TargetInstrInfo *TII = TM.getInstrInfo();
|
||||||
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
|
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
|
||||||
@ -1372,8 +1372,8 @@ llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS,
|
|||||||
return SD;
|
return SD;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS,
|
llvm::ScheduleDAGSDNodes *
|
||||||
bool) {
|
llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, bool) {
|
||||||
const TargetMachine &TM = IS->TM;
|
const TargetMachine &TM = IS->TM;
|
||||||
const TargetInstrInfo *TII = TM.getInstrInfo();
|
const TargetInstrInfo *TII = TM.getInstrInfo();
|
||||||
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
|
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
|
||||||
|
@ -26,6 +26,14 @@ ScheduleDAGSDNodes::ScheduleDAGSDNodes(MachineFunction &mf)
|
|||||||
: ScheduleDAG(mf) {
|
: ScheduleDAG(mf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run - perform scheduling.
|
||||||
|
///
|
||||||
|
void ScheduleDAGSDNodes::Run(SelectionDAG *dag, MachineBasicBlock *bb,
|
||||||
|
MachineBasicBlock::iterator insertPos) {
|
||||||
|
DAG = dag;
|
||||||
|
ScheduleDAG::Run(bb, insertPos);
|
||||||
|
}
|
||||||
|
|
||||||
SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
|
SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
|
||||||
SUnit *SU = NewSUnit(Old->getNode());
|
SUnit *SU = NewSUnit(Old->getNode());
|
||||||
SU->OrigNode = Old->OrigNode;
|
SU->OrigNode = Old->OrigNode;
|
||||||
|
@ -35,10 +35,17 @@ namespace llvm {
|
|||||||
///
|
///
|
||||||
class ScheduleDAGSDNodes : public ScheduleDAG {
|
class ScheduleDAGSDNodes : public ScheduleDAG {
|
||||||
public:
|
public:
|
||||||
|
SelectionDAG *DAG; // DAG of the current basic block
|
||||||
|
|
||||||
explicit ScheduleDAGSDNodes(MachineFunction &mf);
|
explicit ScheduleDAGSDNodes(MachineFunction &mf);
|
||||||
|
|
||||||
virtual ~ScheduleDAGSDNodes() {}
|
virtual ~ScheduleDAGSDNodes() {}
|
||||||
|
|
||||||
|
/// Run - perform scheduling.
|
||||||
|
///
|
||||||
|
void Run(SelectionDAG *dag, MachineBasicBlock *bb,
|
||||||
|
MachineBasicBlock::iterator insertPos);
|
||||||
|
|
||||||
/// isPassiveNode - Return true if the node is a non-scheduled leaf.
|
/// isPassiveNode - Return true if the node is a non-scheduled leaf.
|
||||||
///
|
///
|
||||||
static bool isPassiveNode(SDNode *Node) {
|
static bool isPassiveNode(SDNode *Node) {
|
||||||
|
@ -125,7 +125,8 @@ void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
|
|||||||
} else {
|
} else {
|
||||||
// Create the reg, emit the copy.
|
// Create the reg, emit the copy.
|
||||||
VRBase = MRI.createVirtualRegister(DstRC);
|
VRBase = MRI.createVirtualRegister(DstRC);
|
||||||
bool Emitted = TII->copyRegToReg(*BB, End, VRBase, SrcReg, DstRC, SrcRC);
|
bool Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg,
|
||||||
|
DstRC, SrcRC);
|
||||||
if (!Emitted) {
|
if (!Emitted) {
|
||||||
cerr << "Unable to issue a copy instruction!\n";
|
cerr << "Unable to issue a copy instruction!\n";
|
||||||
abort();
|
abort();
|
||||||
@ -381,7 +382,7 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,
|
|||||||
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
|
MI->addOperand(MachineOperand::CreateReg(VRBase, true));
|
||||||
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
|
AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap);
|
||||||
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
||||||
BB->insert(End, MI);
|
BB->insert(InsertPos, MI);
|
||||||
} else if (Opc == TargetInstrInfo::INSERT_SUBREG ||
|
} else if (Opc == TargetInstrInfo::INSERT_SUBREG ||
|
||||||
Opc == TargetInstrInfo::SUBREG_TO_REG) {
|
Opc == TargetInstrInfo::SUBREG_TO_REG) {
|
||||||
SDValue N0 = Node->getOperand(0);
|
SDValue N0 = Node->getOperand(0);
|
||||||
@ -414,7 +415,7 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,
|
|||||||
// Add the subregster being inserted
|
// Add the subregster being inserted
|
||||||
AddOperand(MI, N1, 0, 0, VRBaseMap);
|
AddOperand(MI, N1, 0, 0, VRBaseMap);
|
||||||
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
MI->addOperand(MachineOperand::CreateImm(SubIdx));
|
||||||
BB->insert(End, MI);
|
BB->insert(InsertPos, MI);
|
||||||
} else
|
} else
|
||||||
assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg");
|
assert(0 && "Node is not insert_subreg, extract_subreg, or subreg_to_reg");
|
||||||
|
|
||||||
@ -478,9 +479,9 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
|
|||||||
// Insert this instruction into the basic block using a target
|
// Insert this instruction into the basic block using a target
|
||||||
// specific inserter which may returns a new basic block.
|
// specific inserter which may returns a new basic block.
|
||||||
BB = TLI->EmitInstrWithCustomInserter(MI, BB);
|
BB = TLI->EmitInstrWithCustomInserter(MI, BB);
|
||||||
Begin = End = BB->end();
|
InsertPos = BB->end();
|
||||||
} else {
|
} else {
|
||||||
BB->insert(End, MI);
|
BB->insert(InsertPos, MI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional results must be an physical register def.
|
// Additional results must be an physical register def.
|
||||||
@ -530,7 +531,8 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
|
|||||||
else
|
else
|
||||||
DstTRC = TRI->getPhysicalRegisterRegClass(DestReg,
|
DstTRC = TRI->getPhysicalRegisterRegClass(DestReg,
|
||||||
Node->getOperand(1).getValueType());
|
Node->getOperand(1).getValueType());
|
||||||
bool Emitted = TII->copyRegToReg(*BB, End, DestReg, SrcReg, DstTRC, SrcTRC);
|
bool Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg,
|
||||||
|
DstTRC, SrcTRC);
|
||||||
if (!Emitted) {
|
if (!Emitted) {
|
||||||
cerr << "Unable to issue a copy instruction!\n";
|
cerr << "Unable to issue a copy instruction!\n";
|
||||||
abort();
|
abort();
|
||||||
@ -590,7 +592,7 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BB->insert(End, MI);
|
BB->insert(InsertPos, MI);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,8 @@ namespace llvm {
|
|||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
/// createDefaultScheduler - This creates an instruction scheduler appropriate
|
/// createDefaultScheduler - This creates an instruction scheduler appropriate
|
||||||
/// for the target.
|
/// for the target.
|
||||||
ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
|
ScheduleDAGSDNodes* createDefaultScheduler(SelectionDAGISel *IS,
|
||||||
bool Fast) {
|
bool Fast) {
|
||||||
const TargetLowering &TLI = IS->getTargetLowering();
|
const TargetLowering &TLI = IS->getTargetLowering();
|
||||||
|
|
||||||
if (Fast)
|
if (Fast)
|
||||||
@ -662,12 +662,12 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
|
|||||||
if (ViewSchedDAGs) CurDAG->viewGraph("scheduler input for " + BlockName);
|
if (ViewSchedDAGs) CurDAG->viewGraph("scheduler input for " + BlockName);
|
||||||
|
|
||||||
// Schedule machine code.
|
// Schedule machine code.
|
||||||
ScheduleDAG *Scheduler = CreateScheduler();
|
ScheduleDAGSDNodes *Scheduler = CreateScheduler();
|
||||||
if (TimePassesIsEnabled) {
|
if (TimePassesIsEnabled) {
|
||||||
NamedRegionTimer T("Instruction Scheduling", GroupName);
|
NamedRegionTimer T("Instruction Scheduling", GroupName);
|
||||||
Scheduler->Run(CurDAG, BB, BB->end(), BB->end());
|
Scheduler->Run(CurDAG, BB, BB->end());
|
||||||
} else {
|
} else {
|
||||||
Scheduler->Run(CurDAG, BB, BB->end(), BB->end());
|
Scheduler->Run(CurDAG, BB, BB->end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ViewSUnitDAGs) Scheduler->viewGraph();
|
if (ViewSUnitDAGs) Scheduler->viewGraph();
|
||||||
@ -1068,7 +1068,7 @@ SelectionDAGISel::FinishBasicBlock() {
|
|||||||
/// via the SchedulerRegistry, use it, otherwise select the
|
/// via the SchedulerRegistry, use it, otherwise select the
|
||||||
/// one preferred by the target.
|
/// one preferred by the target.
|
||||||
///
|
///
|
||||||
ScheduleDAG *SelectionDAGISel::CreateScheduler() {
|
ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
|
||||||
RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
|
RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
|
||||||
|
|
||||||
if (!Ctor) {
|
if (!Ctor) {
|
||||||
|
Loading…
Reference in New Issue
Block a user