Added -stress-sched flag in the Asserts build.

Added a test case for handling physreg aliases during pre-RA-sched.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133063 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick 2011-06-15 17:16:12 +00:00
parent 0e7f08bde5
commit 4cb971ce1c
5 changed files with 79 additions and 16 deletions

View File

@ -497,6 +497,12 @@ namespace llvm {
SUnit EntrySU; // Special node for the region entry.
SUnit ExitSU; // Special node for the region exit.
#ifdef NDEBUG
static const bool StressSched = false;
#else
bool StressSched;
#endif
explicit ScheduleDAG(MachineFunction &mf);
virtual ~ScheduleDAG();

View File

@ -19,17 +19,27 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <climits>
using namespace llvm;
#ifndef NDEBUG
cl::opt<bool> StressSchedOpt(
"stress-sched", cl::Hidden, cl::init(false),
cl::desc("Stress test instruction scheduling"));
#endif
ScheduleDAG::ScheduleDAG(MachineFunction &mf)
: TM(mf.getTarget()),
TII(TM.getInstrInfo()),
TRI(TM.getRegisterInfo()),
MF(mf), MRI(mf.getRegInfo()),
EntrySU(), ExitSU() {
#ifndef NDEBUG
StressSched = StressSchedOpt;
#endif
}
ScheduleDAG::~ScheduleDAG() {}
@ -307,6 +317,8 @@ void SUnit::dumpAll(const ScheduleDAG *G) const {
if (I->isArtificial())
dbgs() << " *";
dbgs() << ": Latency=" << I->getLatency();
if (I->isAssignedRegDep())
dbgs() << " Reg=" << G->TRI->getName(I->getReg());
dbgs() << "\n";
}
}

View File

@ -1369,6 +1369,21 @@ struct queue_sort : public std::binary_function<SUnit*, SUnit*, bool> {
bool isReady(SUnit* SU, unsigned CurCycle) const { return true; }
};
#ifndef NDEBUG
template<class SF>
struct reverse_sort : public queue_sort {
SF &SortFunc;
reverse_sort(SF &sf) : SortFunc(sf) {}
reverse_sort(const reverse_sort &RHS) : SortFunc(RHS.SortFunc) {}
bool operator()(SUnit* left, SUnit* right) const {
// reverse left/right rather than simply !SortFunc(left, right)
// to expose different paths in the comparison logic.
return SortFunc(right, left);
}
};
#endif // NDEBUG
/// bu_ls_rr_sort - Priority function for bottom up register pressure
// reduction scheduler.
struct bu_ls_rr_sort : public queue_sort {
@ -1569,20 +1584,33 @@ protected:
};
template<class SF>
class RegReductionPriorityQueue : public RegReductionPQBase {
static SUnit *popFromQueue(std::vector<SUnit*> &Q, SF &Picker) {
std::vector<SUnit *>::iterator Best = Q.begin();
for (std::vector<SUnit *>::iterator I = llvm::next(Q.begin()),
E = Q.end(); I != E; ++I)
if (Picker(*Best, *I))
Best = I;
SUnit *V = *Best;
if (Best != prior(Q.end()))
std::swap(*Best, Q.back());
Q.pop_back();
return V;
}
static SUnit *popFromQueueImpl(std::vector<SUnit*> &Q, SF &Picker) {
std::vector<SUnit *>::iterator Best = Q.begin();
for (std::vector<SUnit *>::iterator I = llvm::next(Q.begin()),
E = Q.end(); I != E; ++I)
if (Picker(*Best, *I))
Best = I;
SUnit *V = *Best;
if (Best != prior(Q.end()))
std::swap(*Best, Q.back());
Q.pop_back();
return V;
}
template<class SF>
SUnit *popFromQueue(std::vector<SUnit*> &Q, SF &Picker, ScheduleDAG *DAG) {
#ifndef NDEBUG
if (DAG->StressSched) {
reverse_sort<SF> RPicker(Picker);
return popFromQueueImpl(Q, RPicker);
}
#endif
(void)DAG;
return popFromQueueImpl(Q, Picker);
}
template<class SF>
class RegReductionPriorityQueue : public RegReductionPQBase {
SF Picker;
public:
@ -1603,7 +1631,7 @@ public:
SUnit *pop() {
if (Queue.empty()) return NULL;
SUnit *V = popFromQueue(Queue, Picker);
SUnit *V = popFromQueue(Queue, Picker, scheduleDAG);
V->NodeQueueId = 0;
return V;
}
@ -1613,7 +1641,7 @@ public:
std::vector<SUnit*> DumpQueue = Queue;
SF DumpPicker = Picker;
while (!DumpQueue.empty()) {
SUnit *SU = popFromQueue(DumpQueue, DumpPicker);
SUnit *SU = popFromQueue(DumpQueue, DumpPicker, scheduleDAG);
if (isBottomUp())
dbgs() << "Height " << SU->getHeight() << ": ";
else

View File

@ -435,7 +435,7 @@ void ScheduleDAGSDNodes::AddSchedEdges() {
// it requires a cross class copy (cost < 0). That means we are only
// treating "expensive to copy" register dependency as physical register
// dependency. This may change in the future though.
if (Cost >= 0)
if (Cost >= 0 && !StressSched)
PhysReg = 0;
// If this is a ctrl dep, latency is 1.

View File

@ -0,0 +1,17 @@
; RUN: llc < %s -march=x86-64 -stress-sched | FileCheck %s
; Test interference between physreg aliases during preRAsched.
; mul wants an operand in AL, but call clobbers it.
define i8 @f(i8 %v1, i8 %v2) nounwind {
entry:
; CHECK: callq
; CHECK: movb %{{.*}}, %al
; CHECK: mulb
; CHECK: mulb
%rval = tail call i8 @bar() nounwind
%m1 = mul i8 %v1, %v2
%m2 = mul i8 %m1, %rval
ret i8 %m2
}
declare i8 @bar()