[Hexagon] Check for .cur def without use without using a map data structure

Patch by Colin LeMahieu.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301943 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Krzysztof Parzyszek 2017-05-02 17:51:14 +00:00
parent 78070a72ad
commit 9aa1d44080
2 changed files with 42 additions and 24 deletions

View File

@ -159,12 +159,6 @@ void HexagonMCChecker::init(MCInst const &MCI) {
isPredicateRegister(*SRI))
// Some insns produce predicates too late to be used in the same packet.
LatePreds.insert(*SRI);
else if (i == 0 && HexagonMCInstrInfo::isCVINew(MCII, MCI) &&
MCID.mayLoad())
// Current loads should be used in the same packet.
// TODO: relies on the impossibility of a current and a temporary loads
// in the same packet.
CurDefs.insert(*SRI), Defs[*SRI].insert(PredSense(PredReg, isTrue));
else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
HexagonII::TypeCVI_VM_TMP_LD)
// Temporary loads should be used in the same packet, but don't commit
@ -252,6 +246,7 @@ bool HexagonMCChecker::check(bool FullCheck) {
bool chkNV = checkNewValues();
bool chkR = checkRegisters();
bool chkRRO = checkRegistersReadOnly();
checkRegisterCurDefs();
bool chkS = checkSolo();
bool chkSh = true;
if (FullCheck)
@ -396,6 +391,43 @@ bool HexagonMCChecker::checkRegistersReadOnly() {
return true;
}
bool HexagonMCChecker::registerUsed(MCInst const &Inst, unsigned Register) {
if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
if (registerUsed(*Inst.getOperand(0).getInst(), Register) ||
registerUsed(*Inst.getOperand(1).getInst(), Register))
return true;
} else {
unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs();
for (unsigned j = Defs, n = Inst.getNumOperands(); j < n; ++j) {
MCOperand const &Operand = Inst.getOperand(j);
if (Operand.isReg() && Operand.getReg() == Register)
return true;
}
}
return false;
}
bool HexagonMCChecker::registerUsed(unsigned Register) {
auto Range = HexagonMCInstrInfo::bundleInstructions(MCB);
return std::any_of(Range.begin(), Range.end(), [&](MCOperand const &Operand) {
return registerUsed(*Operand.getInst(), Register);
});
}
void HexagonMCChecker::checkRegisterCurDefs() {
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
MCInst const &Inst = *I.getInst();
if (HexagonMCInstrInfo::isCVINew(MCII, Inst) &&
HexagonMCInstrInfo::getDesc(MCII, Inst).mayLoad()) {
unsigned Register = Inst.getOperand(0).getReg();
if (!registerUsed(Register))
reportWarning("Register `" + llvm::Twine(RI.getName(Register)) +
"' used with `.cur' "
"but not used in the same packet");
}
}
}
// Check for legal register uses and definitions.
bool HexagonMCChecker::checkRegisters() {
// Check for proper register definitions.
@ -456,19 +488,6 @@ bool HexagonMCChecker::checkRegisters() {
}
}
// Check for use of current definitions.
for (const auto &I : CurDefs) {
unsigned R = I;
if (!Uses.count(R)) {
// Warn on an unused current definition.
reportWarning("register `" + llvm::Twine(RI.getName(R)) +
"' used with `.cur' "
"but not used in the same packet");
return true;
}
}
// Check for use of temporary definitions.
for (const auto &I : TmpDefs) {
unsigned R = I;

View File

@ -78,10 +78,6 @@ class HexagonMCChecker {
typedef std::set<unsigned>::iterator SoftDefsIterator;
std::set<unsigned> SoftDefs;
/// Set of current definitions committed to the register file.
typedef std::set<unsigned>::iterator CurDefsIterator;
std::set<unsigned> CurDefs;
/// Set of temporary definitions not committed to the register file.
typedef std::set<unsigned>::iterator TmpDefsIterator;
std::set<unsigned> TmpDefs;
@ -109,13 +105,16 @@ class HexagonMCChecker {
void init();
void init(MCInst const &);
void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue);
bool registerUsed(unsigned Register);
bool registerUsed(MCInst const &Inst, unsigned Register);
// Checks performed.
bool checkBranches();
bool checkPredicates();
bool checkNewValues();
bool checkRegisters();
bool checkRegistersReadOnly();
void checkRegisterCurDefs();
bool checkSolo();
bool checkShuffle();
bool checkSlots();