From 9aa1d44080df6bbe18f88d4bf3d1b5d824126032 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 2 May 2017 17:51:14 +0000 Subject: [PATCH] [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 --- .../Hexagon/MCTargetDesc/HexagonMCChecker.cpp | 57 ++++++++++++++-------- lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h | 9 ++-- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp index 33d73f1819c..f138a7c3e2f 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp @@ -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; diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h index d0238691cdc..c67a217afbe 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h @@ -78,10 +78,6 @@ class HexagonMCChecker { typedef std::set::iterator SoftDefsIterator; std::set SoftDefs; - /// Set of current definitions committed to the register file. - typedef std::set::iterator CurDefsIterator; - std::set CurDefs; - /// Set of temporary definitions not committed to the register file. typedef std::set::iterator TmpDefsIterator; std::set 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(); -- 2.11.0