misched: DAG builder support for tracking register pressure within the current scheduling region.

The DAG builder is a convenient place to do it. Hopefully this is more
efficient than a separate traversal over the same region.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155456 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick 2012-04-24 17:56:43 +00:00
parent 4dfeef100d
commit 006e1abf76
4 changed files with 65 additions and 7 deletions

View File

@ -27,6 +27,7 @@
#ifndef MACHINESCHEDULER_H
#define MACHINESCHEDULER_H
#include "RegisterClassInfo.h"
#include "llvm/CodeGen/MachinePassRegistry.h"
namespace llvm {
@ -47,7 +48,10 @@ struct MachineSchedContext {
AliasAnalysis *AA;
LiveIntervals *LIS;
MachineSchedContext(): MF(0), MLI(0), MDT(0), PassConfig(0), AA(0), LIS(0) {}
RegisterClassInfo RegClassInfo;
MachineSchedContext():
MF(0), MLI(0), MDT(0), PassConfig(0), AA(0), LIS(0) {}
};
/// MachineSchedRegistry provides a selection of available machine instruction

View File

@ -28,6 +28,7 @@ namespace llvm {
class MachineLoopInfo;
class MachineDominatorTree;
class LiveIntervals;
class RegPressureTracker;
/// LoopDependencies - This class analyzes loop-oriented register
/// dependencies, which are used to guide scheduling decisions.
@ -275,7 +276,7 @@ namespace llvm {
/// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
/// input.
void buildSchedGraph(AliasAnalysis *AA);
void buildSchedGraph(AliasAnalysis *AA, RegPressureTracker *RPTracker = 0);
/// addSchedBarrierDeps - Add dependencies from instructions in the current
/// list of instructions being scheduled to scheduling barrier. We want to

View File

@ -14,6 +14,7 @@
#define DEBUG_TYPE "misched"
#include "RegisterPressure.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/Passes.h"
@ -149,6 +150,8 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
LIS = &getAnalysis<LiveIntervals>();
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
RegClassInfo.runOnMachineFunction(*MF);
// Select the scheduler, or set the default.
MachineSchedRegistry::ScheduleDAGCtor Ctor = MachineSchedOpt;
if (Ctor == useDefaultMachineSched) {
@ -163,6 +166,9 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
OwningPtr<ScheduleDAGInstrs> Scheduler(Ctor(this));
// Visit all machine basic blocks.
//
// TODO: Visit blocks in global postorder or postorder within the bottom-up
// loop tree. Then we can optionally compute global RegPressure.
for (MachineFunction::iterator MBB = MF->begin(), MBBEnd = MF->end();
MBB != MBBEnd; ++MBB) {
@ -181,6 +187,7 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
unsigned RemainingCount = MBB->size();
for(MachineBasicBlock::iterator RegionEnd = MBB->end();
RegionEnd != MBB->begin(); RegionEnd = Scheduler->begin()) {
// Avoid decrementing RegionEnd for blocks with no terminator.
if (RegionEnd != MBB->end()
|| TII->isSchedulingBoundary(llvm::prior(RegionEnd), MBB, *MF)) {
@ -279,8 +286,13 @@ namespace {
/// machine instructions while updating LiveIntervals.
class ScheduleDAGMI : public ScheduleDAGInstrs {
AliasAnalysis *AA;
RegisterClassInfo *RegClassInfo;
MachineSchedStrategy *SchedImpl;
// Register pressure in this region computed by buildSchedGraph.
IntervalPressure RegPressure;
RegPressureTracker RPTracker;
/// The top of the unscheduled zone.
MachineBasicBlock::iterator CurrentTop;
@ -293,7 +305,8 @@ class ScheduleDAGMI : public ScheduleDAGInstrs {
public:
ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
AA(C->AA), SchedImpl(S), CurrentTop(), CurrentBottom(),
AA(C->AA), RegClassInfo(&C->RegClassInfo), SchedImpl(S),
RPTracker(RegPressure), CurrentTop(), CurrentBottom(),
NumInstrsScheduled(0) {}
~ScheduleDAGMI() {
@ -303,7 +316,16 @@ public:
MachineBasicBlock::iterator top() const { return CurrentTop; }
MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
/// Implement ScheduleDAGInstrs interface.
/// Implement the ScheduleDAGInstrs interface for handling the next scheduling
/// region. This covers all instructions in a block, while schedule() may only
/// cover a subset.
void enterRegion(MachineBasicBlock *bb,
MachineBasicBlock::iterator begin,
MachineBasicBlock::iterator end,
unsigned endcount);
/// Implement ScheduleDAGInstrs interface for scheduling a sequence of
/// reorderable instructions.
void schedule();
protected:
@ -392,10 +414,32 @@ bool ScheduleDAGMI::checkSchedLimit() {
return true;
}
/// enterRegion - Called back from MachineScheduler::runOnMachineFunction after
/// crossing a scheduling boundary. [begin, end) includes all instructions in
/// the region, including the boundary itself and single-instruction regions
/// that don't get scheduled.
void ScheduleDAGMI::enterRegion(MachineBasicBlock *bb,
MachineBasicBlock::iterator begin,
MachineBasicBlock::iterator end,
unsigned endcount)
{
ScheduleDAGInstrs::enterRegion(bb, begin, end, endcount);
// Setup the register pressure tracker to begin tracking at the end of this
// region.
RPTracker.init(&MF, RegClassInfo, LIS, BB, end);
}
/// schedule - Called back from MachineScheduler::runOnMachineFunction
/// after setting up the current scheduling region.
/// after setting up the current scheduling region. [RegionBegin, RegionEnd)
/// only includes instructions that have DAG nodes, not scheduling boundaries.
void ScheduleDAGMI::schedule() {
buildSchedGraph(AA);
while(RPTracker.getPos() != RegionEnd) {
bool Moved = RPTracker.recede();
assert(Moved && "Regpressure tracker cannot find RegionEnd"); (void)Moved;
}
// Build the DAG.
buildSchedGraph(AA, &RPTracker);
DEBUG(dbgs() << "********** MI Scheduling **********\n");
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sched-instrs"
#include "RegisterPressure.h"
#include "llvm/Operator.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/ValueTracking.h"
@ -504,7 +505,11 @@ void ScheduleDAGInstrs::initSUnits() {
}
}
void ScheduleDAGInstrs::buildSchedGraph(AliasAnalysis *AA) {
/// If RegPressure is non null, compute register pressure as a side effect. The
/// DAG builder is an efficient place to do it because it already visits
/// operands.
void ScheduleDAGInstrs::buildSchedGraph(AliasAnalysis *AA,
RegPressureTracker *RPTracker) {
// Create an SUnit for each real instruction.
initSUnits();
@ -555,6 +560,10 @@ void ScheduleDAGInstrs::buildSchedGraph(AliasAnalysis *AA) {
PrevMI = MI;
continue;
}
if (RPTracker) {
RPTracker->recede();
assert(RPTracker->getPos() == prior(MII) && "RPTracker can't find MI");
}
assert((!MI->isTerminator() || CanHandleTerminators) && !MI->isLabel() &&
"Cannot schedule terminators or labels!");