mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Add a new MVT::untyped. This will be used in future work for modelling ISA features like register pairs and lists with "interesting" constraints (such as ARM NEON contiguous register lists or even-odd paired registers). We need to be able to generate these instructions (often from intrinsics), but don't want to have to assign a legal type to them. Instead, we'll use an "untyped" edge to bypass the type-checking and simply ensure that the register classes match.
llvm-svn: 133106
This commit is contained in:
parent
d89900e14c
commit
f98c2ea49d
@ -83,7 +83,11 @@ namespace llvm {
|
|||||||
|
|
||||||
isVoid = 35, // This has no value
|
isVoid = 35, // This has no value
|
||||||
|
|
||||||
LAST_VALUETYPE = 36, // This always remains at the end of the list.
|
untyped = 36, // This value takes a register, but has
|
||||||
|
// unspecified type. The register class
|
||||||
|
// will be determined by the opcode.
|
||||||
|
|
||||||
|
LAST_VALUETYPE = 37, // This always remains at the end of the list.
|
||||||
|
|
||||||
// This is the current maximum for LAST_VALUETYPE.
|
// This is the current maximum for LAST_VALUETYPE.
|
||||||
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
|
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
|
||||||
|
@ -58,6 +58,7 @@ def v4f64 : ValueType<256, 32>; // 4 x f64 vector value
|
|||||||
def x86mmx : ValueType<64 , 33>; // X86 MMX value
|
def x86mmx : ValueType<64 , 33>; // X86 MMX value
|
||||||
def FlagVT : ValueType<0 , 34>; // Pre-RA sched glue
|
def FlagVT : ValueType<0 , 34>; // Pre-RA sched glue
|
||||||
def isVoid : ValueType<0 , 35>; // Produces no value
|
def isVoid : ValueType<0 , 35>; // Produces no value
|
||||||
|
def untyped : ValueType<8,36>; // Produces an untyped value
|
||||||
|
|
||||||
def MetadataVT: ValueType<0, 250>; // Metadata
|
def MetadataVT: ValueType<0, 250>; // Metadata
|
||||||
|
|
||||||
|
@ -276,6 +276,33 @@ private:
|
|||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
/// GetCostForDef - Looks up the register class and cost for a given definition.
|
||||||
|
/// Typically this just means looking up the representative register class,
|
||||||
|
/// but for untyped values (MVT::untyped) it means inspecting the node's
|
||||||
|
/// opcode to determine what register class is being generated.
|
||||||
|
static void GetCostForDef(const ScheduleDAGSDNodes::RegDefIter &RegDefPos,
|
||||||
|
const TargetLowering *TLI,
|
||||||
|
const TargetInstrInfo *TII,
|
||||||
|
const TargetRegisterInfo *TRI,
|
||||||
|
unsigned &RegClass, unsigned &Cost) {
|
||||||
|
EVT VT = RegDefPos.GetValue();
|
||||||
|
|
||||||
|
// Special handling for untyped values. These values can only come from
|
||||||
|
// the expansion of custom DAG-to-DAG patterns.
|
||||||
|
if (VT == MVT::untyped) {
|
||||||
|
unsigned Opcode = RegDefPos.GetNode()->getMachineOpcode();
|
||||||
|
unsigned Idx = RegDefPos.GetIdx();
|
||||||
|
const TargetInstrDesc Desc = TII->get(Opcode);
|
||||||
|
const TargetRegisterClass *RC = Desc.getRegClass(Idx, TRI);
|
||||||
|
RegClass = RC->getID();
|
||||||
|
// FIXME: Cost arbitrarily set to 1 because there doesn't seem to be a
|
||||||
|
// better way to determine it.
|
||||||
|
Cost = 1;
|
||||||
|
} else {
|
||||||
|
RegClass = TLI->getRepRegClassFor(VT)->getID();
|
||||||
|
Cost = TLI->getRepRegClassCostFor(VT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Schedule - Schedule the DAG using list scheduling.
|
/// Schedule - Schedule the DAG using list scheduling.
|
||||||
void ScheduleDAGRRList::Schedule() {
|
void ScheduleDAGRRList::Schedule() {
|
||||||
@ -1807,8 +1834,10 @@ bool RegReductionPQBase::HighRegPressure(const SUnit *SU) const {
|
|||||||
for (ScheduleDAGSDNodes::RegDefIter RegDefPos(PredSU, scheduleDAG);
|
for (ScheduleDAGSDNodes::RegDefIter RegDefPos(PredSU, scheduleDAG);
|
||||||
RegDefPos.IsValid(); RegDefPos.Advance()) {
|
RegDefPos.IsValid(); RegDefPos.Advance()) {
|
||||||
EVT VT = RegDefPos.GetValue();
|
EVT VT = RegDefPos.GetValue();
|
||||||
unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
|
|
||||||
unsigned Cost = TLI->getRepRegClassCostFor(VT);
|
unsigned RCId, Cost;
|
||||||
|
GetCostForDef(RegDefPos, TLI, TII, TRI, RCId, Cost);
|
||||||
|
|
||||||
if ((RegPressure[RCId] + Cost) >= RegLimit[RCId])
|
if ((RegPressure[RCId] + Cost) >= RegLimit[RCId])
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1919,9 +1948,10 @@ void RegReductionPQBase::ScheduledNode(SUnit *SU) {
|
|||||||
RegDefPos.IsValid(); RegDefPos.Advance(), --SkipRegDefs) {
|
RegDefPos.IsValid(); RegDefPos.Advance(), --SkipRegDefs) {
|
||||||
if (SkipRegDefs)
|
if (SkipRegDefs)
|
||||||
continue;
|
continue;
|
||||||
EVT VT = RegDefPos.GetValue();
|
|
||||||
unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
|
unsigned RCId, Cost;
|
||||||
RegPressure[RCId] += TLI->getRepRegClassCostFor(VT);
|
GetCostForDef(RegDefPos, TLI, TII, TRI, RCId, Cost);
|
||||||
|
RegPressure[RCId] += Cost;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1934,16 +1964,16 @@ void RegReductionPQBase::ScheduledNode(SUnit *SU) {
|
|||||||
RegDefPos.IsValid(); RegDefPos.Advance(), --SkipRegDefs) {
|
RegDefPos.IsValid(); RegDefPos.Advance(), --SkipRegDefs) {
|
||||||
if (SkipRegDefs > 0)
|
if (SkipRegDefs > 0)
|
||||||
continue;
|
continue;
|
||||||
EVT VT = RegDefPos.GetValue();
|
unsigned RCId, Cost;
|
||||||
unsigned RCId = TLI->getRepRegClassFor(VT)->getID();
|
GetCostForDef(RegDefPos, TLI, TII, TRI, RCId, Cost);
|
||||||
if (RegPressure[RCId] < TLI->getRepRegClassCostFor(VT)) {
|
if (RegPressure[RCId] < Cost) {
|
||||||
// Register pressure tracking is imprecise. This can happen. But we try
|
// Register pressure tracking is imprecise. This can happen. But we try
|
||||||
// hard not to let it happen because it likely results in poor scheduling.
|
// hard not to let it happen because it likely results in poor scheduling.
|
||||||
DEBUG(dbgs() << " SU(" << SU->NodeNum << ") has too many regdefs\n");
|
DEBUG(dbgs() << " SU(" << SU->NodeNum << ") has too many regdefs\n");
|
||||||
RegPressure[RCId] = 0;
|
RegPressure[RCId] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RegPressure[RCId] -= TLI->getRepRegClassCostFor(VT);
|
RegPressure[RCId] -= Cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dumpRegPressure();
|
dumpRegPressure();
|
||||||
|
@ -135,6 +135,14 @@ namespace llvm {
|
|||||||
return ValueType;
|
return ValueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SDNode *GetNode() const {
|
||||||
|
return Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned GetIdx() const {
|
||||||
|
return DefIdx;
|
||||||
|
}
|
||||||
|
|
||||||
void Advance();
|
void Advance();
|
||||||
private:
|
private:
|
||||||
void InitNodeNumDefs();
|
void InitNodeNumDefs();
|
||||||
|
@ -90,6 +90,7 @@ std::string llvm::getEnumName(MVT::SimpleValueType T) {
|
|||||||
case MVT::Metadata: return "MVT::Metadata";
|
case MVT::Metadata: return "MVT::Metadata";
|
||||||
case MVT::iPTR: return "MVT::iPTR";
|
case MVT::iPTR: return "MVT::iPTR";
|
||||||
case MVT::iPTRAny: return "MVT::iPTRAny";
|
case MVT::iPTRAny: return "MVT::iPTRAny";
|
||||||
|
case MVT::untyped: return "MVT::untyped";
|
||||||
default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
|
default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user