mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-29 13:29:28 +00:00
This is a skeleton for a pre-RA MachineInstr scheduler strategy. Currently it only tries to expose more parallelism for ALU instructions (this also makes the distribution of GPR channels more uniform and increases the chances of ALU instructions to be packed together in a single VLIW group). Also it tries to reduce clause switching by grouping instruction of the same kind (ALU/FETCH/CF) together. Vincent Lejeune: - Support for VLIW4 Slot assignement - Recomputation of ScheduleDAG to get more parallelism opportunities Tom Stellard: - Fix assertion failure when trying to determine an instruction's slot based on its destination register's class - Fix some compiler warnings Vincent Lejeune: [v2] - Remove recomputation of ScheduleDAG (will be provided in a later patch) - Improve estimation of an ALU clause size so that heuristic does not emit cf instructions at the wrong position. - Make schedule heuristic smarter using SUnit Depth - Take constant read limitations into account Vincent Lejeune: [v3] - Fix some uninitialized values in ConstPair - Add asserts to ensure an ALU slot is always populated git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176498 91177308-0d34-0410-b5e6-96231b3b80d8
122 lines
3.0 KiB
C++
122 lines
3.0 KiB
C++
//===-- R600MachineScheduler.h - R600 Scheduler Interface -*- C++ -*-------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \file
|
|
/// \brief R600 Machine Scheduler interface
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef R600MACHINESCHEDULER_H_
|
|
#define R600MACHINESCHEDULER_H_
|
|
|
|
#include "R600InstrInfo.h"
|
|
#include "llvm/CodeGen/MachineScheduler.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/ADT/PriorityQueue.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace llvm {
|
|
|
|
class CompareSUnit {
|
|
public:
|
|
bool operator()(const SUnit *S1, const SUnit *S2) {
|
|
return S1->getDepth() > S2->getDepth();
|
|
}
|
|
};
|
|
|
|
class R600SchedStrategy : public MachineSchedStrategy {
|
|
|
|
const ScheduleDAGMI *DAG;
|
|
const R600InstrInfo *TII;
|
|
const R600RegisterInfo *TRI;
|
|
MachineRegisterInfo *MRI;
|
|
|
|
enum InstQueue {
|
|
QAlu = 1,
|
|
QFetch = 2,
|
|
QOther = 4
|
|
};
|
|
|
|
enum InstKind {
|
|
IDAlu,
|
|
IDFetch,
|
|
IDOther,
|
|
IDLast
|
|
};
|
|
|
|
enum AluKind {
|
|
AluAny,
|
|
AluT_X,
|
|
AluT_Y,
|
|
AluT_Z,
|
|
AluT_W,
|
|
AluT_XYZW,
|
|
AluDiscarded, // LLVM Instructions that are going to be eliminated
|
|
AluLast
|
|
};
|
|
|
|
ReadyQueue *Available[IDLast], *Pending[IDLast];
|
|
std::multiset<SUnit *, CompareSUnit> AvailableAlus[AluLast];
|
|
|
|
InstKind CurInstKind;
|
|
int CurEmitted;
|
|
InstKind NextInstKind;
|
|
|
|
int InstKindLimit[IDLast];
|
|
|
|
int OccupedSlotsMask;
|
|
|
|
public:
|
|
R600SchedStrategy() :
|
|
DAG(0), TII(0), TRI(0), MRI(0) {
|
|
Available[IDAlu] = new ReadyQueue(QAlu, "AAlu");
|
|
Available[IDFetch] = new ReadyQueue(QFetch, "AFetch");
|
|
Available[IDOther] = new ReadyQueue(QOther, "AOther");
|
|
Pending[IDAlu] = new ReadyQueue(QAlu<<4, "PAlu");
|
|
Pending[IDFetch] = new ReadyQueue(QFetch<<4, "PFetch");
|
|
Pending[IDOther] = new ReadyQueue(QOther<<4, "POther");
|
|
}
|
|
|
|
virtual ~R600SchedStrategy() {
|
|
for (unsigned I = 0; I < IDLast; ++I) {
|
|
delete Available[I];
|
|
delete Pending[I];
|
|
}
|
|
}
|
|
|
|
virtual void initialize(ScheduleDAGMI *dag);
|
|
virtual SUnit *pickNode(bool &IsTopNode);
|
|
virtual void schedNode(SUnit *SU, bool IsTopNode);
|
|
virtual void releaseTopNode(SUnit *SU);
|
|
virtual void releaseBottomNode(SUnit *SU);
|
|
|
|
private:
|
|
SUnit *InstructionsGroupCandidate[4];
|
|
|
|
int getInstKind(SUnit *SU);
|
|
bool regBelongsToClass(unsigned Reg, const TargetRegisterClass *RC) const;
|
|
AluKind getAluKind(SUnit *SU) const;
|
|
void LoadAlu();
|
|
bool isAvailablesAluEmpty() const;
|
|
SUnit *AttemptFillSlot (unsigned Slot);
|
|
void PrepareNextSlot();
|
|
SUnit *PopInst(std::multiset<SUnit *, CompareSUnit> &Q);
|
|
|
|
void AssignSlot(MachineInstr *MI, unsigned Slot);
|
|
SUnit* pickAlu();
|
|
SUnit* pickOther(int QID);
|
|
bool isBundleable(const MachineInstr& MI);
|
|
void MoveUnits(ReadyQueue *QSrc, ReadyQueue *QDst);
|
|
};
|
|
|
|
} // namespace llvm
|
|
|
|
#endif /* R600MACHINESCHEDULER_H_ */
|