mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
Add TRI::getSubRegIndexLaneMask().
Sub-register lane masks are bitmasks that can be used to determine if two sub-registers of a virtual register will overlap. For example, ARM's ssub0 and ssub1 sub-register indices don't overlap each other, but both overlap dsub0 and qsub0. The lane masks will be accurate on most targets, but on targets that use sub-register indexes in an irregular way, the masks may conservatively report that two sub-register indices overlap when the eventually allocated physregs don't. Irregular register banks also mean that the bits in a lane mask can't be mapped onto register units, but the concept is similar. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163630 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
de0250728b
commit
a6035773d8
@ -221,13 +221,17 @@ public:
|
|||||||
private:
|
private:
|
||||||
const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
|
const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
|
||||||
const char *const *SubRegIndexNames; // Names of subreg indexes.
|
const char *const *SubRegIndexNames; // Names of subreg indexes.
|
||||||
|
// Pointer to array of lane masks, one per sub-reg index.
|
||||||
|
const unsigned *SubRegIndexLaneMasks;
|
||||||
|
|
||||||
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
|
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
||||||
regclass_iterator RegClassBegin,
|
regclass_iterator RegClassBegin,
|
||||||
regclass_iterator RegClassEnd,
|
regclass_iterator RegClassEnd,
|
||||||
const char *const *subregindexnames);
|
const char *const *SRINames,
|
||||||
|
const unsigned *SRILaneMasks);
|
||||||
virtual ~TargetRegisterInfo();
|
virtual ~TargetRegisterInfo();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -332,6 +336,31 @@ public:
|
|||||||
return SubRegIndexNames[SubIdx-1];
|
return SubRegIndexNames[SubIdx-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getSubRegIndexLaneMask - Return a bitmask representing the parts of a
|
||||||
|
/// register that are covered by SubIdx.
|
||||||
|
///
|
||||||
|
/// Lane masks for sub-register indices are similar to register units for
|
||||||
|
/// physical registers. The individual bits in a lane mask can't be assigned
|
||||||
|
/// any specific meaning. They can be used to check if two sub-register
|
||||||
|
/// indices overlap.
|
||||||
|
///
|
||||||
|
/// If the target has a register such that:
|
||||||
|
///
|
||||||
|
/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
|
||||||
|
///
|
||||||
|
/// then:
|
||||||
|
///
|
||||||
|
/// getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0
|
||||||
|
///
|
||||||
|
/// The converse is not necessarily true. If two lane masks have a common
|
||||||
|
/// bit, the corresponding sub-registers may not overlap, but it can be
|
||||||
|
/// assumed that they usually will.
|
||||||
|
unsigned getSubRegIndexLaneMask(unsigned SubIdx) const {
|
||||||
|
// SubIdx == 0 is allowed, it has the lane mask ~0u.
|
||||||
|
assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index");
|
||||||
|
return SubRegIndexLaneMasks[SubIdx];
|
||||||
|
}
|
||||||
|
|
||||||
/// regsOverlap - Returns true if the two registers are equal or alias each
|
/// regsOverlap - Returns true if the two registers are equal or alias each
|
||||||
/// other. The registers may be virtual register.
|
/// other. The registers may be virtual register.
|
||||||
bool regsOverlap(unsigned regA, unsigned regB) const {
|
bool regsOverlap(unsigned regA, unsigned regB) const {
|
||||||
|
@ -20,8 +20,10 @@ using namespace llvm;
|
|||||||
|
|
||||||
TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
||||||
regclass_iterator RCB, regclass_iterator RCE,
|
regclass_iterator RCB, regclass_iterator RCE,
|
||||||
const char *const *subregindexnames)
|
const char *const *SRINames,
|
||||||
: InfoDesc(ID), SubRegIndexNames(subregindexnames),
|
const unsigned *SRILaneMasks)
|
||||||
|
: InfoDesc(ID), SubRegIndexNames(SRINames),
|
||||||
|
SubRegIndexLaneMasks(SRILaneMasks),
|
||||||
RegClassBegin(RCB), RegClassEnd(RCE) {
|
RegClassBegin(RCB), RegClassEnd(RCE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ using namespace llvm;
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
|
CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
|
||||||
: TheDef(R), EnumValue(Enum) {
|
: TheDef(R), EnumValue(Enum), LaneMask(0) {
|
||||||
Name = R->getName();
|
Name = R->getName();
|
||||||
if (R->getValue("Namespace"))
|
if (R->getValue("Namespace"))
|
||||||
Namespace = R->getValueAsString("Namespace");
|
Namespace = R->getValueAsString("Namespace");
|
||||||
@ -36,7 +36,7 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
|
|||||||
|
|
||||||
CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
|
CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
|
||||||
unsigned Enum)
|
unsigned Enum)
|
||||||
: TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum) {
|
: TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum), LaneMask(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CodeGenSubRegIndex::getQualifiedName() const {
|
std::string CodeGenSubRegIndex::getQualifiedName() const {
|
||||||
@ -75,6 +75,23 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned CodeGenSubRegIndex::computeLaneMask() {
|
||||||
|
// Already computed?
|
||||||
|
if (LaneMask)
|
||||||
|
return LaneMask;
|
||||||
|
|
||||||
|
// Recursion guard, shouldn't be required.
|
||||||
|
LaneMask = ~0u;
|
||||||
|
|
||||||
|
// The lane mask is simply the union of all sub-indices.
|
||||||
|
unsigned M = 0;
|
||||||
|
for (CompMap::iterator I = Composed.begin(), E = Composed.end(); I != E; ++I)
|
||||||
|
M |= I->second->computeLaneMask();
|
||||||
|
assert(M && "Missing lane mask, sub-register cycle?");
|
||||||
|
LaneMask = M;
|
||||||
|
return LaneMask;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// CodeGenRegister
|
// CodeGenRegister
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -1156,6 +1173,35 @@ void CodeGenRegBank::computeComposites() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute lane masks. This is similar to register units, but at the
|
||||||
|
// sub-register index level. Each bit in the lane mask is like a register unit
|
||||||
|
// class, and two lane masks will have a bit in common if two sub-register
|
||||||
|
// indices overlap in some register.
|
||||||
|
//
|
||||||
|
// Conservatively share a lane mask bit if two sub-register indices overlap in
|
||||||
|
// some registers, but not in others. That shouldn't happen a lot.
|
||||||
|
void CodeGenRegBank::computeSubRegIndexLaneMasks() {
|
||||||
|
// First assign individual bits to all the leaf indices.
|
||||||
|
unsigned Bit = 0;
|
||||||
|
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
||||||
|
CodeGenSubRegIndex *Idx = SubRegIndices[i];
|
||||||
|
if (Idx->getComposites().empty()) {
|
||||||
|
Idx->LaneMask = 1u << Bit;
|
||||||
|
// Share bit 31 in the unlikely case there are more than 32 leafs.
|
||||||
|
if (Bit < 31) ++Bit;
|
||||||
|
} else {
|
||||||
|
Idx->LaneMask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: What if ad-hoc aliasing introduces overlaps that aren't represented
|
||||||
|
// by the sub-register graph? This doesn't occur in any known targets.
|
||||||
|
|
||||||
|
// Inherit lanes from composites.
|
||||||
|
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
|
||||||
|
SubRegIndices[i]->computeLaneMask();
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// UberRegSet is a helper class for computeRegUnitWeights. Each UberRegSet is
|
// UberRegSet is a helper class for computeRegUnitWeights. Each UberRegSet is
|
||||||
// the transitive closure of the union of overlapping register
|
// the transitive closure of the union of overlapping register
|
||||||
@ -1539,6 +1585,7 @@ void CodeGenRegBank::computeRegUnitSets() {
|
|||||||
|
|
||||||
void CodeGenRegBank::computeDerivedInfo() {
|
void CodeGenRegBank::computeDerivedInfo() {
|
||||||
computeComposites();
|
computeComposites();
|
||||||
|
computeSubRegIndexLaneMasks();
|
||||||
|
|
||||||
// Compute a weight for each register unit created during getSubRegs.
|
// Compute a weight for each register unit created during getSubRegs.
|
||||||
// This may create adopted register units (with unit # >= NumNativeRegUnits).
|
// This may create adopted register units (with unit # >= NumNativeRegUnits).
|
||||||
|
@ -40,6 +40,7 @@ namespace llvm {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
const unsigned EnumValue;
|
const unsigned EnumValue;
|
||||||
|
unsigned LaneMask;
|
||||||
|
|
||||||
CodeGenSubRegIndex(Record *R, unsigned Enum);
|
CodeGenSubRegIndex(Record *R, unsigned Enum);
|
||||||
CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
|
CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
|
||||||
@ -83,6 +84,9 @@ namespace llvm {
|
|||||||
// Return the map of composites.
|
// Return the map of composites.
|
||||||
const CompMap &getComposites() const { return Composed; }
|
const CompMap &getComposites() const { return Composed; }
|
||||||
|
|
||||||
|
// Compute LaneMask from Composed. Return LaneMask.
|
||||||
|
unsigned computeLaneMask();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CompMap Composed;
|
CompMap Composed;
|
||||||
};
|
};
|
||||||
@ -486,6 +490,9 @@ namespace llvm {
|
|||||||
// Populate the Composite map from sub-register relationships.
|
// Populate the Composite map from sub-register relationships.
|
||||||
void computeComposites();
|
void computeComposites();
|
||||||
|
|
||||||
|
// Compute a lane mask for each sub-register index.
|
||||||
|
void computeSubRegIndexLaneMasks();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CodeGenRegBank(RecordKeeper&);
|
CodeGenRegBank(RecordKeeper&);
|
||||||
|
|
||||||
|
@ -876,15 +876,23 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
|
VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
|
||||||
OS << "};\n";
|
OS << "};\n";
|
||||||
|
|
||||||
// Emit SubRegIndex names, skipping 0
|
// Emit SubRegIndex names, skipping 0.
|
||||||
OS << "\nstatic const char *const SubRegIndexTable[] = { \"";
|
OS << "\nstatic const char *const SubRegIndexNameTable[] = { \"";
|
||||||
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
||||||
OS << SubRegIndices[i]->getName();
|
OS << SubRegIndices[i]->getName();
|
||||||
if (i+1 != e)
|
if (i + 1 != e)
|
||||||
OS << "\", \"";
|
OS << "\", \"";
|
||||||
}
|
}
|
||||||
OS << "\" };\n\n";
|
OS << "\" };\n\n";
|
||||||
|
|
||||||
|
// Emit SubRegIndex lane masks, including 0.
|
||||||
|
OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n";
|
||||||
|
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
||||||
|
OS << format(" 0x%08x, // ", SubRegIndices[i]->LaneMask)
|
||||||
|
<< SubRegIndices[i]->getName() << '\n';
|
||||||
|
}
|
||||||
|
OS << " };\n\n";
|
||||||
|
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
|
|
||||||
// Now that all of the structs have been emitted, emit the instances.
|
// Now that all of the structs have been emitted, emit the instances.
|
||||||
@ -1122,7 +1130,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
|
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
|
||||||
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
|
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
|
||||||
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
|
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
|
||||||
<< " SubRegIndexTable) {\n"
|
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
|
||||||
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
||||||
<< Regs.size()+1 << ", RA,\n " << TargetName
|
<< Regs.size()+1 << ", RA,\n " << TargetName
|
||||||
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
|
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user