mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
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:
parent
0e7f08bde5
commit
4cb971ce1c
@ -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();
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
17
test/CodeGen/X86/2011-06-14-PreschedRegalias.ll
Normal file
17
test/CodeGen/X86/2011-06-14-PreschedRegalias.ll
Normal 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()
|
Loading…
Reference in New Issue
Block a user