/// Run - perform scheduling.
///
- MachineBasicBlock *Run();
+ void Run();
/// isPassiveNode - Return true if the node is a non-scheduled leaf.
///
///
void EmitNoop();
- void EmitSchedule();
+ MachineBasicBlock *EmitSchedule();
void dumpSchedule() const;
class FunctionLoweringInfo;
class HazardRecognizer;
class CollectorMetadata;
+ class ScheduleDAG;
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
/// pattern-matching instruction selectors.
void ComputeLiveOutVRegInfo(SelectionDAG &DAG);
- /// Pick a safe ordering and emit instructions for each target node in the
+ /// Pick a safe ordering for instructions for each target node in the
/// graph.
- void ScheduleAndEmitDAG(SelectionDAG &DAG);
+ ScheduleDAG *Schedule(SelectionDAG &DAG);
/// SwitchCases - Vector of CaseBlock structures used to communicate
/// SwitchInst code generation information.
///
struct NamedRegionTimer : public TimeRegion {
explicit NamedRegionTimer(const std::string &Name);
+ explicit NamedRegionTimer(const std::string &Name,
+ const std::string &GroupName);
};
}
/// EmitSchedule - Emit the machine code in scheduled order.
-void ScheduleDAG::EmitSchedule() {
+MachineBasicBlock *ScheduleDAG::EmitSchedule() {
bool isEntryBB = &MF->front() == BB;
if (isEntryBB && !SchedLiveInCopies) {
if (isEntryBB && SchedLiveInCopies)
EmitLiveInCopies(MF->begin());
+
+ return BB;
}
/// dump - dump the schedule.
/// Run - perform scheduling.
///
-MachineBasicBlock *ScheduleDAG::Run() {
+void ScheduleDAG::Run() {
Schedule();
- return BB;
+
+ DOUT << "*** Final schedule ***\n";
+ DEBUG(dumpSchedule());
+ DOUT << "\n";
}
/// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
ListScheduleTopDown();
AvailableQueue->releaseState();
-
- DOUT << "*** Final schedule ***\n";
- DEBUG(dumpSchedule());
- DOUT << "\n";
-
- // Emit in scheduled order
- EmitSchedule();
}
//===----------------------------------------------------------------------===//
if (!Fast)
CommuteNodesToReducePressure();
-
- DOUT << "*** Final schedule ***\n";
- DEBUG(dumpSchedule());
- DOUT << "\n";
-
- // Emit in scheduled order
- EmitSchedule();
}
/// CommuteNodesToReducePressure - If a node is two-address and commutable, and
void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) {
DOUT << "Lowered selection DAG:\n";
DEBUG(DAG.dump());
+ std::string GroupName = "Instruction Selection and Scheduling";
// Run the DAG combiner in pre-legalize mode.
if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Combining 1");
+ NamedRegionTimer T("DAG Combining 1", GroupName);
DAG.Combine(false, *AA);
} else {
DAG.Combine(false, *AA);
}
if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Legalization");
+ NamedRegionTimer T("DAG Legalization", GroupName);
DAG.Legalize();
} else {
DAG.Legalize();
// Run the DAG combiner in post-legalize mode.
if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Combining 2");
+ NamedRegionTimer T("DAG Combining 2", GroupName);
DAG.Combine(true, *AA);
} else {
DAG.Combine(true, *AA);
// Third, instruction select all of the operations to machine code, adding the
// code to the MachineBasicBlock.
if (TimePassesIsEnabled) {
- NamedRegionTimer T("Instruction Selection");
+ NamedRegionTimer T("Instruction Selection", GroupName);
InstructionSelect(DAG);
} else {
InstructionSelect(DAG);
}
+ // Schedule machine code.
+ ScheduleDAG *Scheduler;
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Scheduling", GroupName);
+ Scheduler = Schedule(DAG);
+ } else {
+ Scheduler = Schedule(DAG);
+ }
+
// Emit machine code to BB. This can change 'BB' to the last block being
// inserted into.
if (TimePassesIsEnabled) {
- NamedRegionTimer T("Instruction Scheduling");
- ScheduleAndEmitDAG(DAG);
+ NamedRegionTimer T("Instruction Creation", GroupName);
+ BB = Scheduler->EmitSchedule();
} else {
- ScheduleAndEmitDAG(DAG);
+ BB = Scheduler->EmitSchedule();
+ }
+
+ // Free the scheduler state.
+ if (TimePassesIsEnabled) {
+ NamedRegionTimer T("Instruction Scheduling Cleanup", GroupName);
+ delete Scheduler;
+ } else {
+ delete Scheduler;
}
// Perform target specific isel post processing.
if (TimePassesIsEnabled) {
- NamedRegionTimer T("Instruction Selection Post Processing");
+ NamedRegionTimer T("Instruction Selection Post Processing", GroupName);
InstructionSelectPostProcessing(DAG);
} else {
InstructionSelectPostProcessing(DAG);
}
-//===----------------------------------------------------------------------===//
-/// ScheduleAndEmitDAG - Pick a safe ordering and emit instructions for each
+/// Schedule - Pick a safe ordering for instructions for each
/// target node in the graph.
-void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) {
+///
+ScheduleDAG *SelectionDAGISel::Schedule(SelectionDAG &DAG) {
if (ViewSchedDAGs) DAG.viewGraph();
RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
RegisterScheduler::setDefault(Ctor);
}
- ScheduleDAG *SL = Ctor(this, &DAG, BB, FastISel);
- BB = SL->Run();
-
- if (ViewSUnitDAGs) SL->viewGraph();
+ ScheduleDAG *Scheduler = Ctor(this, &DAG, BB, FastISel);
+ Scheduler->Run();
- delete SL;
+ if (ViewSUnitDAGs) Scheduler->viewGraph();
+ return Scheduler;
}
// NamedRegionTimer Implementation
//===----------------------------------------------------------------------===//
-static ManagedStatic<std::map<std::string, Timer> > NamedTimers;
+namespace {
+
+typedef std::map<std::string, Timer> Name2Timer;
+typedef std::map<std::string, std::pair<TimerGroup, Name2Timer> > Name2Pair;
+
+}
+
+static ManagedStatic<Name2Timer> NamedTimers;
+
+static ManagedStatic<Name2Pair> NamedGroupedTimers;
static Timer &getNamedRegionTimer(const std::string &Name) {
- std::map<std::string, Timer>::iterator I = NamedTimers->find(Name);
+ Name2Timer::iterator I = NamedTimers->find(Name);
if (I != NamedTimers->end())
return I->second;
return NamedTimers->insert(I, std::make_pair(Name, Timer(Name)))->second;
}
+static Timer &getNamedRegionTimer(const std::string &Name,
+ const std::string &GroupName) {
+
+ Name2Pair::iterator I = NamedGroupedTimers->find(GroupName);
+ if (I == NamedGroupedTimers->end()) {
+ TimerGroup TG(GroupName);
+ std::pair<TimerGroup, Name2Timer> Pair(TG, Name2Timer());
+ I = NamedGroupedTimers->insert(I, std::make_pair(GroupName, Pair));
+ }
+
+ Name2Timer::iterator J = I->second.second.find(Name);
+ if (J == I->second.second.end())
+ J = I->second.second.insert(J,
+ std::make_pair(Name,
+ Timer(Name,
+ I->second.first)));
+
+ return J->second;
+}
+
NamedRegionTimer::NamedRegionTimer(const std::string &Name)
: TimeRegion(getNamedRegionTimer(Name)) {}
+NamedRegionTimer::NamedRegionTimer(const std::string &Name,
+ const std::string &GroupName)
+ : TimeRegion(getNamedRegionTimer(Name, GroupName)) {}
//===----------------------------------------------------------------------===//
// TimerGroup Implementation