[llvm-commits] [llvm] r108991 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/PIC16/PIC16ISelLowering.cpp lib/Target/PIC16/PIC16ISelLowering.h
Evan Cheng
evan.cheng at apple.com
Tue Jul 20 23:09:07 PDT 2010
Author: evancheng
Date: Wed Jul 21 01:09:07 2010
New Revision: 108991
URL: http://llvm.org/viewvc/llvm-project?rev=108991&view=rev
Log:
Teach bottom up pre-ra scheduler to track register pressure. Work in progress.
Modified:
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
llvm/trunk/lib/Target/ARM/ARMISelLowering.h
llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp
llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=108991&r1=108990&r2=108991&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Wed Jul 21 01:09:07 2010
@@ -174,12 +174,18 @@
/// For example, on i386 the rep register class for i8, i16, and i32 are GR32;
/// while the rep register class is GR64 on x86_64.
virtual const TargetRegisterClass *getRepRegClassFor(EVT VT) const {
- assert(VT.isSimple() && "getRegClassFor called on illegal type!");
+ assert(VT.isSimple() && "getRepRegClassFor called on illegal type!");
const TargetRegisterClass *RC = RepRegClassForVT[VT.getSimpleVT().SimpleTy];
- assert(RC && "This value type is not natively supported!");
return RC;
}
+ /// getRepRegClassCostFor - Return the cost of the 'representative' register
+ /// class for the specified value type.
+ virtual uint8_t getRepRegClassCostFor(EVT VT) const {
+ assert(VT.isSimple() && "getRepRegClassCostFor called on illegal type!");
+ return RepRegClassCostForVT[VT.getSimpleVT().SimpleTy];
+ }
+
/// isTypeLegal - Return true if the target has native support for the
/// specified value type. This means that it has a register that directly
/// holds it without promotions or expansions.
@@ -994,9 +1000,9 @@
}
/// findRepresentativeClass - Return the largest legal super-reg register class
- /// of the specified register class.
- virtual const TargetRegisterClass *
- findRepresentativeClass(const TargetRegisterClass *RC) const;
+ /// of the register class for the specified type and its associated "cost".
+ virtual std::pair<const TargetRegisterClass*, uint8_t>
+ findRepresentativeClass(EVT VT) const;
/// computeRegisterProperties - Once all of the register classes are added,
/// this allows us to compute derived properties we expose.
@@ -1581,10 +1587,17 @@
/// RepRegClassForVT - This indicates the "representative" register class to
/// use for each ValueType the target supports natively. This information is
- /// used by the scheduler to track register pressure. e.g. On x86, i8, i16,
+ /// used by the scheduler to track register pressure. By default, the
+ /// representative register class is the largest legal super-reg register
+ /// class of the register class of the specified type. e.g. On x86, i8, i16,
/// and i32's representative class would be GR32.
const TargetRegisterClass *RepRegClassForVT[MVT::LAST_VALUETYPE];
+ /// RepRegClassCostForVT - This indicates the "cost" of the "representative"
+ /// register class for each ValueType. The cost is used by the scheduler to
+ /// approximate register pressure.
+ uint8_t RepRegClassCostForVT[MVT::LAST_VALUETYPE];
+
/// Synthesizable indicates whether it is OK for the compiler to create new
/// operations using this type. All Legal types are Synthesizable except
/// MMX types on X86. Non-Legal types are not Synthesizable.
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=108991&r1=108990&r2=108991&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Wed Jul 21 01:09:07 2010
@@ -24,15 +24,20 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetLowering.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <climits>
using namespace llvm;
+static cl::opt<bool> RegPressureAware("reg-pressure-aware-sched",
+ cl::init(false), cl::Hidden);
+
STATISTIC(NumBacktracks, "Number of times scheduler backtracked");
STATISTIC(NumUnfolds, "Number of nodes unfolded");
STATISTIC(NumDups, "Number of duplicated nodes");
@@ -181,7 +186,9 @@
/// Schedule - Schedule the DAG using list scheduling.
void ScheduleDAGRRList::Schedule() {
- DEBUG(dbgs() << "********** List Scheduling **********\n");
+ DEBUG(dbgs()
+ << "********** List Scheduling BB#" << BB->getNumber()
+ << " **********\n");
NumLiveRegs = 0;
LiveRegDefs.resize(TRI->getNumRegs(), NULL);
@@ -989,7 +996,7 @@
: SPQ(spq) {}
hybrid_ls_rr_sort(const hybrid_ls_rr_sort &RHS)
: SPQ(RHS.SPQ) {}
-
+
bool operator()(const SUnit* left, const SUnit* right) const;
};
} // end anonymous namespace
@@ -1029,23 +1036,46 @@
std::vector<SUnit*> Queue;
SF Picker;
unsigned CurQueueId;
+ bool isBottomUp;
protected:
// SUnits - The SUnits for the current graph.
std::vector<SUnit> *SUnits;
-
+
+ MachineFunction &MF;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
+ const TargetLowering *TLI;
ScheduleDAGRRList *scheduleDAG;
// SethiUllmanNumbers - The SethiUllman number for each node.
std::vector<unsigned> SethiUllmanNumbers;
+ /// RegPressure - Tracking current reg pressure per register class.
+ ///
+ std::vector<int> RegPressure;
+
+ /// RegLimit - Tracking the number of allocatable registers per register
+ /// class.
+ std::vector<int> RegLimit;
+
public:
- RegReductionPriorityQueue(const TargetInstrInfo *tii,
- const TargetRegisterInfo *tri)
- : Picker(this), CurQueueId(0),
- TII(tii), TRI(tri), scheduleDAG(NULL) {}
+ RegReductionPriorityQueue(MachineFunction &mf,
+ bool isbottomup,
+ const TargetInstrInfo *tii,
+ const TargetRegisterInfo *tri,
+ const TargetLowering *tli)
+ : Picker(this), CurQueueId(0), isBottomUp(isbottomup),
+ MF(mf), TII(tii), TRI(tri), TLI(tli), scheduleDAG(NULL) {
+ unsigned NumRC = TRI->getNumRegClasses();
+ RegLimit.resize(NumRC);
+ RegPressure.resize(NumRC);
+ std::fill(RegLimit.begin(), RegLimit.end(), 0);
+ std::fill(RegPressure.begin(), RegPressure.end(), 0);
+ for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
+ E = TRI->regclass_end(); I != E; ++I)
+ RegLimit[(*I)->getID()] = tri->getAllocatableSet(MF, *I).count() - 1;
+ }
void initNodes(std::vector<SUnit> &sunits) {
SUnits = &sunits;
@@ -1072,6 +1102,7 @@
void releaseState() {
SUnits = 0;
SethiUllmanNumbers.clear();
+ std::fill(RegPressure.begin(), RegPressure.end(), 0);
}
unsigned getNodePriority(const SUnit *SU) const {
@@ -1139,10 +1170,191 @@
SU->NodeQueueId = 0;
}
+ // EstimateSpills - Given a scheduling unit, estimate the number of spills
+ // it would cause by scheduling it at the current cycle.
+ unsigned EstimateSpills(const SUnit *SU) const {
+ if (!TLI)
+ return 0;
+
+ unsigned Spills = 0;
+ for (SUnit::const_pred_iterator I = SU->Preds.begin(),E = SU->Preds.end();
+ I != E; ++I) {
+ if (I->isCtrl())
+ continue;
+ SUnit *PredSU = I->getSUnit();
+ if (PredSU->NumSuccsLeft != PredSU->NumSuccs - 1)
+ continue;
+ const SDNode *N = PredSU->getNode();
+ if (!N->isMachineOpcode())
+ continue;
+ unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs();
+ for (unsigned i = 0; i != NumDefs; ++i) {
+ EVT VT = N->getValueType(i);
+ if (!N->hasAnyUseOfValue(i))
+ continue;
+ unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
+ unsigned Cost = TLI->getRepRegClassCostFor(VT);
+ // Check if this increases register pressure of the specific register
+ // class to the point where it would cause spills.
+ int Excess = RegPressure[RCId] + Cost - RegLimit[RCId];
+ if (Excess > 0)
+ Spills += Excess;
+ }
+ }
+
+ if (!SU->NumSuccs || !Spills)
+ return Spills;
+ const SDNode *N = SU->getNode();
+ if (!N->isMachineOpcode())
+ return Spills;
+ unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs();
+ for (unsigned i = 0; i != NumDefs; ++i) {
+ EVT VT = N->getValueType(i);
+ if (!N->hasAnyUseOfValue(i))
+ continue;
+ unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
+ unsigned Cost = TLI->getRepRegClassCostFor(VT);
+ if (RegPressure[RCId] > RegLimit[RCId]) {
+ int Less = RegLimit[RCId] - (RegPressure[RCId] - Cost);
+ if (Less > 0) {
+ if (Spills <= (unsigned)Less)
+ return 0;
+ Spills -= Less;
+ }
+ }
+ }
+
+ return Spills;
+ }
+
+ void OpenPredLives(SUnit *SU) {
+ const SDNode *N = SU->getNode();
+ if (!N->isMachineOpcode())
+ return;
+ unsigned Opc = N->getMachineOpcode();
+ if (Opc == TargetOpcode::EXTRACT_SUBREG ||
+ Opc == TargetOpcode::INSERT_SUBREG ||
+ Opc == TargetOpcode::SUBREG_TO_REG ||
+ Opc == TargetOpcode::COPY_TO_REGCLASS ||
+ Opc == TargetOpcode::REG_SEQUENCE ||
+ Opc == TargetOpcode::IMPLICIT_DEF)
+ return;
+
+ for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
+ I != E; ++I) {
+ if (I->isCtrl())
+ continue;
+ SUnit *PredSU = I->getSUnit();
+ if (PredSU->NumSuccsLeft != PredSU->NumSuccs - 1)
+ continue;
+ const SDNode *PN = PredSU->getNode();
+ if (!PN->isMachineOpcode())
+ continue;
+ unsigned NumDefs = TII->get(PN->getMachineOpcode()).getNumDefs();
+ for (unsigned i = 0; i != NumDefs; ++i) {
+ EVT VT = PN->getValueType(i);
+ if (!PN->hasAnyUseOfValue(i))
+ continue;
+ unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
+ RegPressure[RCId] += TLI->getRepRegClassCostFor(VT);
+ }
+ }
+
+ if (!SU->NumSuccs)
+ return;
+ unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs();
+ for (unsigned i = 0; i != NumDefs; ++i) {
+ EVT VT = N->getValueType(i);
+ if (!N->hasAnyUseOfValue(i))
+ continue;
+ unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
+ RegPressure[RCId] -= TLI->getRepRegClassCostFor(VT);
+ if (RegPressure[RCId] < 0)
+ // Register pressure tracking is imprecise. This can happen.
+ RegPressure[RCId] = 0;
+ }
+ }
+
+ void ClosePredLives(SUnit *SU) {
+ const SDNode *N = SU->getNode();
+ if (!N->isMachineOpcode())
+ return;
+ unsigned Opc = N->getMachineOpcode();
+ if (Opc == TargetOpcode::EXTRACT_SUBREG ||
+ Opc == TargetOpcode::INSERT_SUBREG ||
+ Opc == TargetOpcode::SUBREG_TO_REG ||
+ Opc == TargetOpcode::COPY_TO_REGCLASS ||
+ Opc == TargetOpcode::REG_SEQUENCE ||
+ Opc == TargetOpcode::IMPLICIT_DEF)
+ return;
+
+ for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
+ I != E; ++I) {
+ if (I->isCtrl())
+ continue;
+ SUnit *PredSU = I->getSUnit();
+ if (PredSU->NumSuccsLeft != PredSU->NumSuccs - 1)
+ continue;
+ const SDNode *PN = PredSU->getNode();
+ if (!PN->isMachineOpcode())
+ continue;
+ unsigned NumDefs = TII->get(PN->getMachineOpcode()).getNumDefs();
+ for (unsigned i = 0; i != NumDefs; ++i) {
+ EVT VT = PN->getValueType(i);
+ if (!PN->hasAnyUseOfValue(i))
+ continue;
+ unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
+ RegPressure[RCId] -= TLI->getRepRegClassCostFor(VT);
+ if (RegPressure[RCId] < 0)
+ // Register pressure tracking is imprecise. This can happen.
+ RegPressure[RCId] = 0;
+ }
+ }
+
+ if (!SU->NumSuccs)
+ return;
+ unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs();
+ for (unsigned i = NumDefs, e = N->getNumValues(); i != e; ++i) {
+ EVT VT = N->getValueType(i);
+ if (VT == MVT::Flag || VT == MVT::Other)
+ continue;
+ if (!N->hasAnyUseOfValue(i))
+ continue;
+ unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
+ RegPressure[RCId] += TLI->getRepRegClassCostFor(VT);
+ }
+ }
+
+ void ScheduledNode(SUnit *SU) {
+ if (!TLI || !isBottomUp)
+ return;
+ OpenPredLives(SU);
+ dumpRegPressure();
+ }
+
+ void UnscheduledNode(SUnit *SU) {
+ if (!TLI || !isBottomUp)
+ return;
+ ClosePredLives(SU);
+ dumpRegPressure();
+ }
+
void setScheduleDAG(ScheduleDAGRRList *scheduleDag) {
scheduleDAG = scheduleDag;
}
+ void dumpRegPressure() const {
+ for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
+ E = TRI->regclass_end(); I != E; ++I) {
+ const TargetRegisterClass *RC = *I;
+ unsigned Id = RC->getID();
+ unsigned RP = RegPressure[Id];
+ if (!RP) continue;
+ DEBUG(dbgs() << RC->getName() << ": " << RP << " / " << RegLimit[Id]
+ << '\n');
+ }
+ }
+
protected:
bool canClobber(const SUnit *SU, const SUnit *Op);
void AddPseudoTwoAddrDeps();
@@ -1635,8 +1847,8 @@
const TargetInstrInfo *TII = TM.getInstrInfo();
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
- BURegReductionPriorityQueue *PQ = new BURegReductionPriorityQueue(TII, TRI);
-
+ BURegReductionPriorityQueue *PQ =
+ new BURegReductionPriorityQueue(*IS->MF, true, TII, TRI, 0);
ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, false, PQ);
PQ->setScheduleDAG(SD);
return SD;
@@ -1648,8 +1860,8 @@
const TargetInstrInfo *TII = TM.getInstrInfo();
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
- TDRegReductionPriorityQueue *PQ = new TDRegReductionPriorityQueue(TII, TRI);
-
+ TDRegReductionPriorityQueue *PQ =
+ new TDRegReductionPriorityQueue(*IS->MF, false, TII, TRI, 0);
ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, false, false, PQ);
PQ->setScheduleDAG(SD);
return SD;
@@ -1661,8 +1873,8 @@
const TargetInstrInfo *TII = TM.getInstrInfo();
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
- SrcRegReductionPriorityQueue *PQ = new SrcRegReductionPriorityQueue(TII, TRI);
-
+ SrcRegReductionPriorityQueue *PQ =
+ new SrcRegReductionPriorityQueue(*IS->MF, true, TII, TRI, 0);
ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, false, PQ);
PQ->setScheduleDAG(SD);
return SD;
@@ -1673,9 +1885,11 @@
const TargetMachine &TM = IS->TM;
const TargetInstrInfo *TII = TM.getInstrInfo();
const TargetRegisterInfo *TRI = TM.getRegisterInfo();
+ const TargetLowering *TLI = &IS->getTargetLowering();
- HybridBURRPriorityQueue *PQ = new HybridBURRPriorityQueue(TII, TRI);
-
+ HybridBURRPriorityQueue *PQ =
+ new HybridBURRPriorityQueue(*IS->MF, true, TII, TRI,
+ (RegPressureAware ? TLI : 0));
ScheduleDAGRRList *SD = new ScheduleDAGRRList(*IS->MF, true, true, PQ);
PQ->setScheduleDAG(SD);
return SD;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=108991&r1=108990&r2=108991&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Wed Jul 21 01:09:07 2010
@@ -678,9 +678,12 @@
}
/// findRepresentativeClass - Return the largest legal super-reg register class
-/// of the specified register class.
-const TargetRegisterClass *
-TargetLowering::findRepresentativeClass(const TargetRegisterClass *RC) const {
+/// of the register class for the specified type and its associated "cost".
+std::pair<const TargetRegisterClass*, uint8_t>
+TargetLowering::findRepresentativeClass(EVT VT) const {
+ const TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy];
+ if (!RC)
+ return std::make_pair(RC, 0);
const TargetRegisterClass *BestRC = RC;
for (TargetRegisterInfo::regclass_iterator I = RC->superregclasses_begin(),
E = RC->superregclasses_end(); I != E; ++I) {
@@ -688,10 +691,10 @@
if (RRC->isASubClass() || !isLegalRC(RRC))
continue;
if (!hasLegalSuperRegRegClasses(RRC))
- return RRC;
+ return std::make_pair(RRC, 1);
BestRC = RRC;
}
- return BestRC;
+ return std::make_pair(BestRC, 1);
}
/// computeRegisterProperties - Once all of the register classes are added,
@@ -820,8 +823,11 @@
// a group of value types. For example, on i386, i8, i16, and i32
// representative would be GR32; while on x86_64 it's GR64.
for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i) {
- const TargetRegisterClass *RC = RegClassForVT[i];
- RepRegClassForVT[i] = RC ? findRepresentativeClass(RC) : 0;
+ const TargetRegisterClass* RRC;
+ uint8_t Cost;
+ tie(RRC, Cost) = findRepresentativeClass((MVT::SimpleValueType)i);
+ RepRegClassForVT[i] = RRC;
+ RepRegClassCostForVT[i] = Cost;
}
}
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=108991&r1=108990&r2=108991&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Jul 21 01:09:07 2010
@@ -550,20 +550,38 @@
benefitFromCodePlacementOpt = true;
}
-const TargetRegisterClass *
-ARMTargetLowering::findRepresentativeClass(const TargetRegisterClass *RC) const{
- switch (RC->getID()) {
+std::pair<const TargetRegisterClass*, uint8_t>
+ARMTargetLowering::findRepresentativeClass(EVT VT) const{
+ const TargetRegisterClass *RRC = 0;
+ uint8_t Cost = 1;
+ switch (VT.getSimpleVT().SimpleTy) {
default:
- return RC;
- case ARM::tGPRRegClassID:
- case ARM::GPRRegClassID:
- return ARM::GPRRegisterClass;
- case ARM::SPRRegClassID:
- case ARM::DPRRegClassID:
- return ARM::DPRRegisterClass;
- case ARM::QPRRegClassID:
- return ARM::QPRRegisterClass;
+ return TargetLowering::findRepresentativeClass(VT);
+ // Use SPR as representative register class for all floating point
+ // and vector types.
+ case MVT::f32:
+ RRC = ARM::SPRRegisterClass;
+ break;
+ case MVT::f64: case MVT::v8i8: case MVT::v4i16:
+ case MVT::v2i32: case MVT::v1i64: case MVT::v2f32:
+ RRC = ARM::SPRRegisterClass;
+ Cost = 2;
+ break;
+ case MVT::v16i8: case MVT::v8i16: case MVT::v4i32: case MVT::v2i64:
+ case MVT::v4f32: case MVT::v2f64:
+ RRC = ARM::SPRRegisterClass;
+ Cost = 4;
+ break;
+ case MVT::v4i64:
+ RRC = ARM::SPRRegisterClass;
+ Cost = 8;
+ break;
+ case MVT::v8i64:
+ RRC = ARM::SPRRegisterClass;
+ Cost = 16;
+ break;
}
+ return std::make_pair(RRC, Cost);
}
const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=108991&r1=108990&r2=108991&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Wed Jul 21 01:09:07 2010
@@ -272,8 +272,8 @@
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
protected:
- const TargetRegisterClass *
- findRepresentativeClass(const TargetRegisterClass *RC) const;
+ std::pair<const TargetRegisterClass*, uint8_t>
+ findRepresentativeClass(EVT VT) const;
private:
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp?rev=108991&r1=108990&r2=108991&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.cpp Wed Jul 21 01:09:07 2010
@@ -312,6 +312,16 @@
computeRegisterProperties();
}
+std::pair<const TargetRegisterClass*, uint8_t>
+PIC16TargetLowering::findRepresentativeClass(EVT VT) const {
+ switch (VT.getSimpleVT().SimpleTy) {
+ default:
+ return TargetLowering::findRepresentativeClass(VT);
+ case MVT::i16:
+ return std::make_pair(PIC16::FSR16RegisterClass, 1);
+ }
+}
+
// getOutFlag - Extract the flag result if the Op has it.
static SDValue getOutFlag(SDValue &Op) {
// Flag is the last value of the node.
Modified: llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h?rev=108991&r1=108990&r2=108991&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h (original)
+++ llvm/trunk/lib/Target/PIC16/PIC16ISelLowering.h Wed Jul 21 01:09:07 2010
@@ -181,6 +181,9 @@
// FIXME: The function never seems to be aligned.
return 1;
}
+ protected:
+ std::pair<const TargetRegisterClass*, uint8_t>
+ findRepresentativeClass(EVT VT) const;
private:
// If the Node is a BUILD_PAIR representing a direct Address,
// then this function will return true.
More information about the llvm-commits
mailing list