[llvm] r301823 - [Hexagon] Improve shuffle error reporting

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Mon May 1 12:41:44 PDT 2017


Author: kparzysz
Date: Mon May  1 14:41:43 2017
New Revision: 301823

URL: http://llvm.org/viewvc/llvm-project?rev=301823&view=rev
Log:
[Hexagon] Improve shuffle error reporting

Patch by Colin LeMahieu.

Modified:
    llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
    llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.h
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp
    llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h

Modified: llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp Mon May  1 14:41:43 2017
@@ -459,94 +459,16 @@ bool HexagonAsmParser::finishBundle(SMLo
   DEBUG(MCB.dump_pretty(dbgs()));
   DEBUG(dbgs() << "--\n");
 
+  MCB.setLoc(IDLoc);
   // Check the bundle for errors.
   const MCRegisterInfo *RI = getContext().getRegisterInfo();
-  HexagonMCChecker Check(MCII, getSTI(), MCB, MCB, *RI);
+  HexagonMCChecker Check(getContext(), MCII, getSTI(), MCB, *RI);
 
   bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MCII, getSTI(),
                                                         getContext(), MCB,
                                                         &Check);
 
-  while (Check.getNextErrInfo()) {
-    unsigned Reg = Check.getErrRegister();
-    Twine R(RI->getName(Reg));
-
-    uint64_t Err = Check.getError();
-    if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
-      if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
-        return Error(
-            IDLoc,
-            "unconditional branch cannot precede another branch in packet");
-
-      if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
-          HexagonMCErrInfo::CHECK_ERROR_NEWV & Err)
-        return Error(IDLoc, "register `" + R +
-                                "' used with `.new' "
-                                "but not validly modified in the same packet");
-
-      if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
-        return Error(IDLoc, "register `" + R + "' modified more than once");
-
-      if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
-        return Error(IDLoc, "cannot write to read-only register `" + R + "'");
-
-      if (HexagonMCErrInfo::CHECK_ERROR_LOOP & Err)
-        return Error(IDLoc, "loop-setup and some branch instructions "
-                            "cannot be in the same packet");
-
-      if (HexagonMCErrInfo::CHECK_ERROR_ENDLOOP & Err) {
-        Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
-        return Error(IDLoc,
-                     "packet marked with `:endloop" + N + "' " +
-                         "cannot contain instructions that modify register " +
-                         "`" + R + "'");
-      }
-
-      if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
-        return Error(
-            IDLoc,
-            "instruction cannot appear in packet with other instructions");
-
-      if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
-        return Error(IDLoc, "too many slots used in packet");
-
-      if (Err & HexagonMCErrInfo::CHECK_ERROR_SHUFFLE) {
-        uint64_t Erm = Check.getShuffleError();
-
-        if (HexagonShuffler::SHUFFLE_ERROR_INVALID == Erm)
-          return Error(IDLoc, "invalid instruction packet");
-        else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
-          return Error(IDLoc, "invalid instruction packet: too many stores");
-        else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
-          return Error(IDLoc, "invalid instruction packet: too many loads");
-        else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
-          return Error(IDLoc, "too many branches in packet");
-        else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
-          return Error(IDLoc, "invalid instruction packet: out of slots");
-        else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
-          return Error(IDLoc, "invalid instruction packet: slot error");
-        else if (HexagonShuffler::SHUFFLE_ERROR_ERRATA2 == Erm)
-          return Error(IDLoc, "v60 packet violation");
-        else if (HexagonShuffler::SHUFFLE_ERROR_STORE_LOAD_CONFLICT == Erm)
-          return Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
-        else
-          return Error(IDLoc, "unknown error in instruction packet");
-      }
-    }
-
-    unsigned Warn = Check.getWarning();
-    if (Warn != HexagonMCErrInfo::CHECK_SUCCESS) {
-      if (HexagonMCErrInfo::CHECK_WARN_CURRENT & Warn)
-        Warning(IDLoc, "register `" + R + "' used with `.cur' "
-                                          "but not used in the same packet");
-      else if (HexagonMCErrInfo::CHECK_WARN_TEMPORARY & Warn)
-        Warning(IDLoc, "register `" + R + "' used with `.tmp' "
-                                          "but not used in the same packet");
-    }
-  }
-
   if (CheckOk) {
-    MCB.setLoc(IDLoc);
     if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
       assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
       assert(!HexagonMCInstrInfo::isOuterLoop(MCB));

Modified: llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp Mon May  1 14:41:43 2017
@@ -191,7 +191,8 @@ DecodeStatus HexagonDisassembler::getIns
     return Result;
   if (Size > HEXAGON_MAX_PACKET_SIZE)
     return MCDisassembler::Fail;
-  HexagonMCChecker Checker(*MCII, STI, MI, MI, *getContext().getRegisterInfo());
+  HexagonMCChecker Checker(getContext(), *MCII, STI, MI,
+                           *getContext().getRegisterInfo(), false);
   if (!Checker.check())
     return MCDisassembler::Fail;
   return MCDisassembler::Success;

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp Mon May  1 14:41:43 2017
@@ -58,6 +58,7 @@ class HexagonAsmBackend : public MCAsmBa
     RF.getContents() = Code;
     RF.getFixups() = Fixups;
   }
+
 public:
   HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
       StringRef CPU) :
@@ -711,22 +712,24 @@ public:
               break;
             }
             case MCFragment::FT_Relaxable: {
+              MCContext &Context = Asm.getContext();
               auto &RF = cast<MCRelaxableFragment>(*K);
               auto &Inst = const_cast<MCInst &>(RF.getInst());
               while (Size > 0 && HexagonMCInstrInfo::bundleSize(Inst) < 4) {
-                MCInst *Nop = new (Asm.getContext()) MCInst;
+                MCInst *Nop = new (Context) MCInst;
                 Nop->setOpcode(Hexagon::A2_nop);
                 Inst.addOperand(MCOperand::createInst(Nop));
                 Size -= 4;
                 if (!HexagonMCChecker(
-                           *MCII, RF.getSubtargetInfo(), Inst, Inst,
-                           *Asm.getContext().getRegisterInfo()).check()) {
+                         Context, *MCII, RF.getSubtargetInfo(), Inst,
+                         *Context.getRegisterInfo(), false)
+                         .check()) {
                   Inst.erase(Inst.end() - 1);
                   Size = 0;
                 }
               }
-              bool Error = HexagonMCShuffle(true, *MCII, RF.getSubtargetInfo(),
-                                            Inst);
+              bool Error = HexagonMCShuffle(Context, true, *MCII,
+                                            RF.getSubtargetInfo(), Inst);
               //assert(!Error);
               (void)Error;
               ReplaceInstruction(Asm.getEmitter(), RF, Inst);

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp Mon May  1 14:41:43 2017
@@ -16,19 +16,22 @@
 
 #include "HexagonBaseInfo.h"
 
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInstrDesc.h"
 #include "llvm/MC/MCInstrInfo.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
-static cl::opt<bool> RelaxNVChecks("relax-nv-checks", cl::init(false),
-  cl::ZeroOrMore, cl::Hidden, cl::desc("Relax checks of new-value validity"));
+static cl::opt<bool>
+    RelaxNVChecks("relax-nv-checks", cl::init(false), cl::ZeroOrMore,
+                  cl::Hidden, cl::desc("Relax checks of new-value validity"));
 
 const HexagonMCChecker::PredSense
-  HexagonMCChecker::Unconditional(Hexagon::NoRegister, false);
+    HexagonMCChecker::Unconditional(Hexagon::NoRegister, false);
 
 void HexagonMCChecker::init() {
   // Initialize read-only registers set.
@@ -46,13 +49,12 @@ void HexagonMCChecker::init() {
 
   if (HexagonMCInstrInfo::isBundle(MCB))
     // Unfurl a bundle.
-    for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
+    for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
       MCInst const &Inst = *I.getInst();
       if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
         init(*Inst.getOperand(0).getInst());
         init(*Inst.getOperand(1).getInst());
-      }
-      else
+      } else
         init(Inst);
     }
   else
@@ -69,20 +71,18 @@ void HexagonMCChecker::initReg(MCInst co
     // Note use of new predicate register.
     if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
       NewPreds.insert(PredReg);
-  }
-  else
+  } else
     // Note register use.  Super-registers are not tracked directly,
     // but their components.
-    for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
-        SRI.isValid();
-        ++SRI)
+    for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
+         SRI.isValid(); ++SRI)
       if (!MCSubRegIterator(*SRI, &RI).isValid())
         // Skip super-registers used indirectly.
         Uses.insert(*SRI);
 }
 
-void HexagonMCChecker::init(MCInst const& MCI) {
-  const MCInstrDesc& MCID = HexagonMCInstrInfo::getDesc(MCII, MCI);
+void HexagonMCChecker::init(MCInst const &MCI) {
+  const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MCI);
   unsigned PredReg = Hexagon::NoRegister;
   bool isTrue = false;
 
@@ -109,10 +109,10 @@ void HexagonMCChecker::init(MCInst const
 
       if (Hexagon::USR_OVF == R)
         // Many insns change the USR implicitly, but only one or another flag.
-        // The instruction table models the USR.OVF flag, which can be implicitly
-        // modified more than once, but cannot be modified in the same packet
-        // with an instruction that modifies is explicitly. Deal with such situ-
-        // ations individually.
+        // The instruction table models the USR.OVF flag, which can be
+        // implicitly modified more than once, but cannot be modified in the
+        // same packet with an instruction that modifies is explicitly. Deal
+        // with such situ- ations individually.
         SoftDefs.insert(R);
       else if (isPredicateRegister(R) &&
                HexagonMCInstrInfo::isPredicateLate(MCII, MCI))
@@ -124,8 +124,7 @@ void HexagonMCChecker::init(MCInst const
 
   // Figure out explicit register definitions.
   for (unsigned i = 0; i < MCID.getNumDefs(); ++i) {
-    unsigned R = MCI.getOperand(i).getReg(),
-             S = Hexagon::NoRegister;
+    unsigned R = MCI.getOperand(i).getReg(), S = Hexagon::NoRegister;
     // USR has subregisters (while C8 does not for technical reasons), so
     // reset R to USR, since we know how to handle multiple defs of USR,
     // taking into account its subregisters.
@@ -134,9 +133,8 @@ void HexagonMCChecker::init(MCInst const
 
     // Note register definitions, direct ones as well as indirect side-effects.
     // Super-registers are not tracked directly, but their components.
-    for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
-        SRI.isValid();
-        ++SRI) {
+    for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
+         SRI.isValid(); ++SRI) {
       if (MCSubRegIterator(*SRI, &RI).isValid())
         // Skip super-registers defined indirectly.
         continue;
@@ -156,22 +154,25 @@ void HexagonMCChecker::init(MCInst const
         // Only an explicit definition of P3:0 is noted as such; if a
         // side-effect, then note as a soft definition.
         SoftDefs.insert(*SRI);
-      else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) && isPredicateRegister(*SRI))
+      else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) &&
+               isPredicateRegister(*SRI))
         // Some insns produce predicates too late to be used in the same packet.
         LatePreds.insert(*SRI);
-      else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCVI_VM_CUR_LD)
+      else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
+                             HexagonII::TypeCVI_VM_CUR_LD)
         // 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)
+      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
         // results, so it should be disregarded if another insn changes the same
         // register.
         // TODO: relies on the impossibility of a current and a temporary loads
         // in the same packet.
         TmpDefs.insert(*SRI);
-      else if (i <= 1 && llvm::HexagonMCInstrInfo::hasNewValue2(MCII, MCI) )
+      else if (i <= 1 && llvm::HexagonMCInstrInfo::hasNewValue2(MCII, MCI))
         // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
         // destination registers with this instruction. same for vdeal(Vx,Vy,Rx)
         Uses.insert(*SRI);
@@ -187,25 +188,26 @@ void HexagonMCChecker::init(MCInst const
     if (HexagonMCInstrInfo::isCompound(MCII, MCI))
       compoundRegisterMap(R); // Compound insns have a limited register range.
 
-    for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
-        SRI.isValid();
-        ++SRI)
+    for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
+         SRI.isValid(); ++SRI)
       if (!MCSubRegIterator(*SRI, &RI).isValid())
         // No super-registers defined indirectly.
-        NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
-                                              HexagonMCInstrInfo::isFloat(MCII, MCI)));
+        NewDefs[*SRI].push_back(NewSense::Def(
+            PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
+            HexagonMCInstrInfo::isFloat(MCII, MCI)));
 
     // For fairly unique 2-dot-new producers, example:
     // vdeal(V1, V9, R0) V1.new and V9.new can be used by consumers.
     if (HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) {
       unsigned R2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, MCI).getReg();
 
-      for(MCRegAliasIterator SRI(R2, &RI, !MCSubRegIterator(R2, &RI).isValid());
-          SRI.isValid();
-          ++SRI)
+      for (MCRegAliasIterator SRI(R2, &RI,
+                                  !MCSubRegIterator(R2, &RI).isValid());
+           SRI.isValid(); ++SRI)
         if (!MCSubRegIterator(*SRI, &RI).isValid())
-          NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
-                                                HexagonMCInstrInfo::isFloat(MCII, MCI)));
+          NewDefs[*SRI].push_back(NewSense::Def(
+              PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
+              HexagonMCInstrInfo::isFloat(MCII, MCI)));
     }
   }
 
@@ -227,18 +229,19 @@ void HexagonMCChecker::init(MCInst const
       // Super-registers cannot use new values.
       if (MCID.isBranch())
         NewUses[N] = NewSense::Jmp(
-          llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ);
+            llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ);
       else
         NewUses[N] = NewSense::Use(
-          PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI));
+            PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI));
     }
   }
 }
 
-HexagonMCChecker::HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, MCInst &mcbdx,
-                                   MCRegisterInfo const &ri)
-    : MCB(mcb), MCBDX(mcbdx), RI(ri), MCII(MCII), STI(STI),
-      bLoadErrInfo(false) {
+HexagonMCChecker::HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII,
+                                   MCSubtargetInfo const &STI, MCInst &mcb,
+                                   MCRegisterInfo const &ri, bool ReportErrors)
+    : Context(Context), MCB(mcb), RI(ri), MCII(MCII), STI(STI),
+      ReportErrors(ReportErrors) {
   init();
 }
 
@@ -250,21 +253,19 @@ bool HexagonMCChecker::check(bool FullCh
   bool chkS = checkSolo();
   bool chkSh = true;
   if (FullCheck)
-   chkSh = checkShuffle();
+    chkSh = checkShuffle();
   bool chkSl = true;
   if (FullCheck)
-   chkSl = checkSlots();
+    chkSl = checkSlots();
   bool chk = chkB && chkP && chkNV && chkR && chkS && chkSh && chkSl;
 
   return chk;
 }
 
-bool HexagonMCChecker::checkSlots()
-
-{
+bool HexagonMCChecker::checkSlots() {
   unsigned slotsUsed = 0;
-  for (auto HMI: HexagonMCInstrInfo::bundleInstructions(MCBDX)) {
-    MCInst const& MCI = *HMI.getInst();
+  for (auto HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
+    MCInst const &MCI = *HMI.getInst();
     if (HexagonMCInstrInfo::isImmext(MCI))
       continue;
     if (HexagonMCInstrInfo::isDuplex(MCII, MCI))
@@ -274,9 +275,7 @@ bool HexagonMCChecker::checkSlots()
   }
 
   if (slotsUsed > HEXAGON_PACKET_SIZE) {
-    HexagonMCErrInfo errInfo;
-    errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NOSLOTS);
-    addErrInfo(errInfo);
+    reportError("invalid instruction packet: out of slots");
     return false;
   }
   return true;
@@ -284,11 +283,9 @@ bool HexagonMCChecker::checkSlots()
 
 // Check legal use of branches.
 bool HexagonMCChecker::checkBranches() {
-  HexagonMCErrInfo errInfo;
   if (HexagonMCInstrInfo::isBundle(MCB)) {
     bool hasConditional = false;
-    unsigned Branches = 0,
-             Conditional = HEXAGON_PRESHUFFLE_PACKET_SIZE,
+    unsigned Branches = 0, Conditional = HEXAGON_PRESHUFFLE_PACKET_SIZE,
              Unconditional = HEXAGON_PRESHUFFLE_PACKET_SIZE;
 
     for (unsigned i = HexagonMCInstrInfo::bundleInstructionsOffset;
@@ -314,16 +311,18 @@ bool HexagonMCChecker::checkBranches() {
       if (HexagonMCInstrInfo::isInnerLoop(MCB) ||
           HexagonMCInstrInfo::isOuterLoop(MCB)) {
         // Error out if there's any branch in a loop-end packet.
-        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_ENDLOOP, Hexagon::PC);
-        addErrInfo(errInfo);
+        Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
+        reportError("packet marked with `:endloop" + N + "' " +
+                    "cannot contain instructions that modify register " + "`" +
+                    llvm::Twine(RI.getName(Hexagon::PC)) + "'");
         return false;
       }
     if (Branches > 1)
       if (!hasConditional || Conditional > Unconditional) {
         // Error out if more than one unconditional branch or
         // the conditional branch appears after the unconditional one.
-        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_BRANCHES);
-        addErrInfo(errInfo);
+        reportError(
+            "unconditional branch cannot precede another branch in packet");
         return false;
       }
   }
@@ -333,31 +332,28 @@ bool HexagonMCChecker::checkBranches() {
 
 // Check legal use of predicate registers.
 bool HexagonMCChecker::checkPredicates() {
-  HexagonMCErrInfo errInfo;
   // Check for proper use of new predicate registers.
-  for (const auto& I : NewPreds) {
+  for (const auto &I : NewPreds) {
     unsigned P = I;
 
     if (!Defs.count(P) || LatePreds.count(P)) {
       // Error out if the new predicate register is not defined,
       // or defined "late"
       // (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }").
-      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWP, P);
-      addErrInfo(errInfo);
+      reportErrorNewValue(P);
       return false;
     }
   }
 
   // Check for proper use of auto-anded of predicate registers.
-  for (const auto& I : LatePreds) {
+  for (const auto &I : LatePreds) {
     unsigned P = I;
 
     if (LatePreds.count(P) > 1 || Defs.count(P)) {
       // Error out if predicate register defined "late" multiple times or
       // defined late and regularly defined
       // (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }".
-      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, P);
-      addErrInfo(errInfo);
+      reportErrorRegisters(P);
       return false;
     }
   }
@@ -367,15 +363,12 @@ bool HexagonMCChecker::checkPredicates()
 
 // Check legal use of new values.
 bool HexagonMCChecker::checkNewValues() {
-  HexagonMCErrInfo errInfo;
-  memset(&errInfo, 0, sizeof(errInfo));
-  for (auto& I : NewUses) {
+  for (auto &I : NewUses) {
     unsigned R = I.first;
     NewSense &US = I.second;
 
     if (!hasValidNewValueDef(US, NewDefs[R])) {
-      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWV, R);
-      addErrInfo(errInfo);
+      reportErrorNewValue(R);
       return false;
     }
   }
@@ -385,23 +378,22 @@ bool HexagonMCChecker::checkNewValues()
 
 // Check for legal register uses and definitions.
 bool HexagonMCChecker::checkRegisters() {
-  HexagonMCErrInfo errInfo;
   // Check for proper register definitions.
-  for (const auto& I : Defs) {
+  for (const auto &I : Defs) {
     unsigned R = I.first;
 
     if (ReadOnly.count(R)) {
       // Error out for definitions of read-only registers.
-      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_READONLY, R);
-      addErrInfo(errInfo);
+      reportError("cannot write to read-only register `" +
+                  llvm::Twine(RI.getName(R)) + "'");
       return false;
     }
     if (isLoopRegister(R) && Defs.count(R) > 1 &&
         (HexagonMCInstrInfo::isInnerLoop(MCB) ||
          HexagonMCInstrInfo::isOuterLoop(MCB))) {
       // Error out for definitions of loop registers at the end of a loop.
-      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_LOOP, R);
-      addErrInfo(errInfo);
+      reportError("loop-setup and some branch instructions "
+                  "cannot be in the same packet");
       return false;
     }
     if (SoftDefs.count(R)) {
@@ -409,8 +401,7 @@ bool HexagonMCChecker::checkRegisters()
       // (e.g., "{ usr = r0; r0 = sfadd(...) }").
       unsigned UsrR = Hexagon::USR; // Silence warning about mixed types in ?:.
       unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
-      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR);
-      addErrInfo(errInfo);
+      reportErrorRegisters(BadR);
       return false;
     }
     if (!isPredicateRegister(R) && Defs[R].size() > 1) {
@@ -423,20 +414,18 @@ bool HexagonMCChecker::checkRegisters()
         // changes, conditional or not.
         unsigned UsrR = Hexagon::USR;
         unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
-        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR);
-        addErrInfo(errInfo);
+        reportErrorRegisters(BadR);
         return false;
       }
       // Check for multiple conditional register definitions.
-      for (const auto& J : PM) {
+      for (const auto &J : PM) {
         PredSense P = J;
 
         // Check for multiple uses of the same condition.
         if (PM.count(P) > 1) {
           // Error out on conditional changes based on the same predicate
           // (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }").
-          errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R);
-          addErrInfo(errInfo);
+          reportErrorRegisters(R);
           return false;
         }
         // Check for the use of the complementary condition.
@@ -444,9 +433,9 @@ bool HexagonMCChecker::checkRegisters()
         if (PM.count(P) && PM.size() > 2) {
           // Error out on conditional changes based on the same predicate
           // multiple times
-          // (e.g., "{ if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =... }").
-          errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R);
-          addErrInfo(errInfo);
+          // (e.g., "{ if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =...
+          // }").
+          reportErrorRegisters(R);
           return false;
         }
       }
@@ -454,34 +443,37 @@ bool HexagonMCChecker::checkRegisters()
   }
 
   // Check for use of current definitions.
-  for (const auto& I : CurDefs) {
+  for (const auto &I : CurDefs) {
     unsigned R = I;
 
     if (!Uses.count(R)) {
       // Warn on an unused current definition.
-      errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_CURRENT, R);
-      addErrInfo(errInfo);
+      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) {
+  for (const auto &I : TmpDefs) {
     unsigned R = I;
 
     if (!Uses.count(R)) {
       // special case for vhist
       bool vHistFound = false;
-      for (auto const&HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
-        if(llvm::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) == HexagonII::TypeCVI_HIST) {
-          vHistFound = true;  // vhist() implicitly uses ALL REGxx.tmp
+      for (auto const &HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
+        if (llvm::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) ==
+            HexagonII::TypeCVI_HIST) {
+          vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp
           break;
         }
       }
       // Warn on an unused temporary definition.
       if (vHistFound == false) {
-        errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_TEMPORARY, R);
-        addErrInfo(errInfo);
+        reportWarning("register `" + llvm::Twine(RI.getName(R)) +
+                      "' used with `.tmp' "
+                      "but not used in the same packet");
         return true;
       }
     }
@@ -492,13 +484,12 @@ bool HexagonMCChecker::checkRegisters()
 
 // Check for legal use of solo insns.
 bool HexagonMCChecker::checkSolo() {
-  HexagonMCErrInfo errInfo;
   if (HexagonMCInstrInfo::isBundle(MCB) &&
       HexagonMCInstrInfo::bundleSize(MCB) > 1) {
-    for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
+    for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
       if (llvm::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) {
-        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SOLO);
-        addErrInfo(errInfo);
+        reportError(
+            "instruction cannot appear in packet with other instructions");
         return false;
       }
     }
@@ -508,29 +499,11 @@ bool HexagonMCChecker::checkSolo() {
 }
 
 bool HexagonMCChecker::checkShuffle() {
-  HexagonMCErrInfo errInfo;
-  // Branch info is lost when duplexing. The unduplexed insns must be
-  // checked and only branch errors matter for this case.
-  HexagonMCShuffler MCS(true, MCII, STI, MCB);
-  if (!MCS.check()) {
-    if (MCS.getError() == HexagonShuffler::SHUFFLE_ERROR_BRANCHES) {
-      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE);
-      errInfo.setShuffleError(MCS.getError());
-      addErrInfo(errInfo);
-      return false;
-    }
-  }
-  HexagonMCShuffler MCSDX(true, MCII, STI, MCBDX);
-  if (!MCSDX.check()) {
-    errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE);
-    errInfo.setShuffleError(MCSDX.getError());
-    addErrInfo(errInfo);
-    return false;
-  }
-  return true;
+  HexagonMCShuffler MCSDX(Context, ReportErrors, MCII, STI, MCB);
+  return MCSDX.check();
 }
 
-void HexagonMCChecker::compoundRegisterMap(unsigned& Register) {
+void HexagonMCChecker::compoundRegisterMap(unsigned &Register) {
   switch (Register) {
   default:
     break;
@@ -562,7 +535,7 @@ void HexagonMCChecker::compoundRegisterM
 }
 
 bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use,
-      const NewSenseList &Defs) const {
+                                           const NewSenseList &Defs) const {
   bool Strict = !RelaxNVChecks;
 
   for (unsigned i = 0, n = Defs.size(); i < n; ++i) {
@@ -590,3 +563,26 @@ bool HexagonMCChecker::hasValidNewValueD
   return false;
 }
 
+void HexagonMCChecker::reportErrorRegisters(unsigned Register) {
+  reportError("register `" + llvm::Twine(RI.getName(Register)) +
+              "' modified more than once");
+}
+
+void HexagonMCChecker::reportErrorNewValue(unsigned Register) {
+  reportError("register `" + llvm::Twine(RI.getName(Register)) +
+              "' used with `.new' "
+              "but not validly modified in the same packet");
+}
+
+void HexagonMCChecker::reportError(llvm::Twine const &Msg) {
+  if (ReportErrors)
+    Context.reportError(MCB.getLoc(), Msg);
+}
+
+void HexagonMCChecker::reportWarning(llvm::Twine const &Msg) {
+  if (ReportErrors) {
+    auto SM = Context.getSourceManager();
+    if (SM)
+      SM->PrintMessage(MCB.getLoc(), SourceMgr::DK_Warning, Msg);
+  }
+}

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h Mon May  1 14:41:43 2017
@@ -24,59 +24,14 @@ using namespace llvm;
 namespace llvm {
 class MCOperandInfo;
 
-typedef struct {
-  unsigned Error, Warning, ShuffleError;
-  unsigned Register;
-} ErrInfo_T;
-
-class HexagonMCErrInfo {
-public:
-  enum {
-    CHECK_SUCCESS         = 0,
-    // Errors.
-    CHECK_ERROR_BRANCHES  = 0x00001,
-    CHECK_ERROR_NEWP      = 0x00002,
-    CHECK_ERROR_NEWV      = 0x00004,
-    CHECK_ERROR_REGISTERS = 0x00008,
-    CHECK_ERROR_READONLY  = 0x00010,
-    CHECK_ERROR_LOOP      = 0x00020,
-    CHECK_ERROR_ENDLOOP   = 0x00040,
-    CHECK_ERROR_SOLO      = 0x00080,
-    CHECK_ERROR_SHUFFLE   = 0x00100,
-    CHECK_ERROR_NOSLOTS   = 0x00200,
-    CHECK_ERROR_UNKNOWN   = 0x00400,
-    // Warnings.
-    CHECK_WARN_CURRENT    = 0x10000,
-    CHECK_WARN_TEMPORARY  = 0x20000
-  };
-  ErrInfo_T s;
-
-  void reset() {
-    s.Error = CHECK_SUCCESS;
-    s.Warning = CHECK_SUCCESS;
-    s.ShuffleError = HexagonShuffler::SHUFFLE_SUCCESS;
-    s.Register = Hexagon::NoRegister;
-  };
-  HexagonMCErrInfo() {
-    reset();
-  };
-
-  void setError(unsigned e, unsigned r = Hexagon::NoRegister)
-    { s.Error = e; s.Register = r; };
-  void setWarning(unsigned w, unsigned r = Hexagon::NoRegister)
-    { s.Warning = w; s.Register = r; };
-  void setShuffleError(unsigned e) { s.ShuffleError = e; };
-};
-
 /// Check for a valid bundle.
 class HexagonMCChecker {
-  /// Insn bundle.
-  MCInst& MCB;
-  MCInst& MCBDX;
-  const MCRegisterInfo& RI;
+  MCContext &Context;
+  MCInst &MCB;
+  const MCRegisterInfo &RI;
   MCInstrInfo const &MCII;
   MCSubtargetInfo const &STI;
-  bool bLoadErrInfo;
+  bool ReportErrors;
 
   /// Set of definitions: register #, if predicated, if predicated true.
   typedef std::pair<unsigned, bool> PredSense;
@@ -99,23 +54,23 @@ class HexagonMCChecker {
     bool IsFloat, IsNVJ, Cond;
     // The special-case "constructors":
     static NewSense Jmp(bool isNVJ) {
-      NewSense NS = { /*PredReg=*/ 0, /*IsFloat=*/ false, /*IsNVJ=*/ isNVJ,
-                      /*Cond=*/ false };
+      NewSense NS = {/*PredReg=*/0, /*IsFloat=*/false, /*IsNVJ=*/isNVJ,
+                     /*Cond=*/false};
       return NS;
     }
     static NewSense Use(unsigned PR, bool True) {
-      NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ false, /*IsNVJ=*/ false,
-                      /*Cond=*/ True };
+      NewSense NS = {/*PredReg=*/PR, /*IsFloat=*/false, /*IsNVJ=*/false,
+                     /*Cond=*/True};
       return NS;
     }
     static NewSense Def(unsigned PR, bool True, bool Float) {
-      NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ Float, /*IsNVJ=*/ false,
-                      /*Cond=*/ True };
+      NewSense NS = {/*PredReg=*/PR, /*IsFloat=*/Float, /*IsNVJ=*/false,
+                     /*Cond=*/True};
       return NS;
     }
   };
   /// Set of definitions that produce new register:
-  typedef llvm::SmallVector<NewSense,2> NewSenseList;
+  typedef llvm::SmallVector<NewSense, 2> NewSenseList;
   typedef llvm::DenseMap<unsigned, NewSenseList>::iterator NewDefsIterator;
   llvm::DenseMap<unsigned, NewSenseList> NewDefs;
 
@@ -151,23 +106,8 @@ class HexagonMCChecker {
   typedef std::set<unsigned>::iterator ReadOnlyIterator;
   std::set<unsigned> ReadOnly;
 
-  std::queue<ErrInfo_T> ErrInfoQ;
-  HexagonMCErrInfo CrntErrInfo;
-
-  void getErrInfo() {
-    if (bLoadErrInfo == true) {
-      if (ErrInfoQ.empty()) {
-        CrntErrInfo.reset();
-      } else {
-        CrntErrInfo.s = ErrInfoQ.front();
-        ErrInfoQ.pop();
-      }
-    }
-    bLoadErrInfo = false;
-  }
-
   void init();
-  void init(MCInst const&);
+  void init(MCInst const &);
   void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue);
 
   // Checks performed.
@@ -180,40 +120,31 @@ class HexagonMCChecker {
   bool checkSlots();
   bool checkSize();
 
-  static void compoundRegisterMap(unsigned&);
+  static void compoundRegisterMap(unsigned &);
 
   bool isPredicateRegister(unsigned R) const {
-    return (Hexagon::P0 == R || Hexagon::P1 == R ||
-            Hexagon::P2 == R || Hexagon::P3 == R);
+    return (Hexagon::P0 == R || Hexagon::P1 == R || Hexagon::P2 == R ||
+            Hexagon::P3 == R);
   };
   bool isLoopRegister(unsigned R) const {
-    return (Hexagon::SA0 == R || Hexagon::LC0 == R ||
-            Hexagon::SA1 == R || Hexagon::LC1 == R);
+    return (Hexagon::SA0 == R || Hexagon::LC0 == R || Hexagon::SA1 == R ||
+            Hexagon::LC1 == R);
   };
 
-  bool hasValidNewValueDef(const NewSense &Use,
-                           const NewSenseList &Defs) const;
+  bool hasValidNewValueDef(const NewSense &Use, const NewSenseList &Defs) const;
 
-  public:
-  explicit HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst& mcb, MCInst &mcbdx,
-                            const MCRegisterInfo& ri);
+public:
+  explicit HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII,
+                            MCSubtargetInfo const &STI, MCInst &mcb,
+                            const MCRegisterInfo &ri, bool ReportErrors = true);
 
   bool check(bool FullCheck = true);
-
-  /// add a new error/warning
-  void addErrInfo(HexagonMCErrInfo &err) { ErrInfoQ.push(err.s); };
-
-  /// Return the error code for the last operation in the insn bundle.
-  unsigned getError() { getErrInfo(); return CrntErrInfo.s.Error; };
-  unsigned getWarning() { getErrInfo(); return CrntErrInfo.s.Warning; };
-  unsigned getShuffleError() { getErrInfo(); return CrntErrInfo.s.ShuffleError; };
-  unsigned getErrRegister() { getErrInfo(); return CrntErrInfo.s.Register; };
-  bool getNextErrInfo() {
-    bLoadErrInfo = true;
-    return (ErrInfoQ.empty()) ? false : (getErrInfo(), true);
-  }
+  void reportErrorRegisters(unsigned Register);
+  void reportErrorNewValue(unsigned Register);
+  void reportError(llvm::Twine const &Msg);
+  void reportWarning(llvm::Twine const &Msg);
 };
 
-}
+} // namespace llvm
 
 #endif // HEXAGONMCCHECKER_H

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCCompound.cpp Mon May  1 14:41:43 2017
@@ -406,7 +406,7 @@ void HexagonMCInstrInfo::tryCompound(MCI
   if (MCI.size() < 2)
     return;
 
-  bool StartedValid = llvm::HexagonMCShuffle(false, MCII, STI, MCI);
+  bool StartedValid = llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI);
 
   // Create a vector, needed to keep the order of jump instructions.
   MCInst CheckList(MCI);
@@ -420,8 +420,9 @@ void HexagonMCInstrInfo::tryCompound(MCI
     // Need to update the bundle.
     MCI = CheckList;
 
-    if (StartedValid && !llvm::HexagonMCShuffle(false, MCII, STI, MCI)) {
-      DEBUG(dbgs() << "Found ERROR\n");
+    if (StartedValid &&
+        !llvm::HexagonMCShuffle(Context, false, MCII, STI, MCI)) {
+       DEBUG(dbgs() << "Found ERROR\n");
       MCI = OriginalBundle;
     }
   }

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp Mon May  1 14:41:43 2017
@@ -66,7 +66,7 @@ bool HexagonMCInstrInfo::canonicalizePac
   // instructions when possible.
   if (!HexagonDisableCompound)
     HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);
-  HexagonMCShuffle(false, MCII, STI, MCB);
+  HexagonMCShuffle(Context, false, MCII, STI, MCB);
   // Examine the packet and convert pairs of instructions to duplex
   // instructions when possible.
   MCInst InstBundlePreDuplex = MCInst(MCB);
@@ -74,7 +74,7 @@ bool HexagonMCInstrInfo::canonicalizePac
     SmallVector<DuplexCandidate, 8> possibleDuplexes;
     possibleDuplexes =
         HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB);
-    HexagonMCShuffle(MCII, STI, Context, MCB, possibleDuplexes);
+    HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);
   }
   // Examines packet and pad the packet, if needed, when an
   // end-loop is in the bundle.
@@ -87,7 +87,7 @@ bool HexagonMCInstrInfo::canonicalizePac
   CheckOk = Check ? Check->check(true) : true;
   if (!CheckOk)
     return false;
-  HexagonMCShuffle(true, MCII, STI, MCB);
+  HexagonMCShuffle(Context, true, MCII, STI, MCB);
   return true;
 }
 

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp Mon May  1 14:41:43 2017
@@ -45,6 +45,7 @@ void HexagonMCShuffler::init(MCInst &MCB
     }
   }
 
+  Loc = MCB.getLoc();
   BundleFlags = MCB.getOperand(0).getImm();
 }
 
@@ -68,12 +69,14 @@ void HexagonMCShuffler::init(MCInst &MCB
       append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
   }
 
+  Loc = MCB.getLoc();
   BundleFlags = MCB.getOperand(0).getImm();
 }
 
 void HexagonMCShuffler::copyTo(MCInst &MCB) {
   MCB.clear();
   MCB.addOperand(MCOperand::createImm(BundleFlags));
+  MCB.setLoc(Loc);
   // Copy the results into the bundle.
   for (HexagonShuffler::iterator I = begin(); I != end(); ++I) {
 
@@ -89,15 +92,16 @@ bool HexagonMCShuffler::reshuffleTo(MCIn
   if (shuffle()) {
     // Copy the results into the bundle.
     copyTo(MCB);
-  } else
-    DEBUG(MCB.dump());
-
-  return (!getError());
+    return true;
+  }
+  DEBUG(MCB.dump());
+  return false;
 }
 
-bool llvm::HexagonMCShuffle(bool Fatal, MCInstrInfo const &MCII,
-                            MCSubtargetInfo const &STI, MCInst &MCB) {
-  HexagonMCShuffler MCS(true, MCII, STI, MCB);
+bool llvm::HexagonMCShuffle(MCContext &Context, bool Fatal,
+                            MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
+                            MCInst &MCB) {
+  HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB);
 
   if (DisableShuffle)
     // Ignore if user chose so.
@@ -117,52 +121,16 @@ bool llvm::HexagonMCShuffle(bool Fatal,
     return false;
   }
 
-  // Reorder the bundle and copy the result.
-  if (!MCS.reshuffleTo(MCB)) {
-    // Unless there is any error, which should not happen at this point.
-    unsigned shuffleError = MCS.getError();
-
-    if (!Fatal && (shuffleError !=  HexagonShuffler::SHUFFLE_SUCCESS))
-      return false;
-    if (shuffleError !=  HexagonShuffler::SHUFFLE_SUCCESS) {
-      errs() << "\nFailing packet:\n";
-      for (const auto& I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
-        MCInst *MI = const_cast<MCInst *>(I.getInst());
-        errs() << HexagonMCInstrInfo::getName(MCII, *MI) << ' ' << HexagonMCInstrInfo::getDesc(MCII, *MI).getOpcode() << '\n';
-      }
-      errs() << '\n';
-    }
-
-    switch (shuffleError) {
-    default:
-      llvm_unreachable("unknown error");
-    case HexagonShuffler::SHUFFLE_ERROR_INVALID:
-      llvm_unreachable("invalid packet");
-    case HexagonShuffler::SHUFFLE_ERROR_STORES:
-      llvm_unreachable("too many stores");
-    case HexagonShuffler::SHUFFLE_ERROR_LOADS:
-      llvm_unreachable("too many loads");
-    case HexagonShuffler::SHUFFLE_ERROR_BRANCHES:
-      llvm_unreachable("too many branches");
-    case HexagonShuffler::SHUFFLE_ERROR_NOSLOTS:
-      llvm_unreachable("no suitable slot");
-    case HexagonShuffler::SHUFFLE_ERROR_SLOTS:
-      llvm_unreachable("over-subscribed slots");
-    case HexagonShuffler::SHUFFLE_SUCCESS: // Single instruction case.
-      return true;
-    }
-  }
-
-  return true;
+  return MCS.reshuffleTo(MCB);
 }
 
-unsigned
-llvm::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
-                       MCContext &Context, MCInst &MCB,
+bool
+llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
+                       MCSubtargetInfo const &STI, MCInst &MCB,
                        SmallVector<DuplexCandidate, 8> possibleDuplexes) {
 
   if (DisableShuffle)
-    return HexagonShuffler::SHUFFLE_SUCCESS;
+    return false;
 
   if (!HexagonMCInstrInfo::bundleSize(MCB)) {
     // There once was a bundle:
@@ -172,46 +140,44 @@ llvm::HexagonMCShuffle(MCInstrInfo const
     // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
     // became empty.
     DEBUG(dbgs() << "Skipping empty bundle");
-    return HexagonShuffler::SHUFFLE_SUCCESS;
+    return false;
   } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
     DEBUG(dbgs() << "Skipping stand-alone insn");
-    return HexagonShuffler::SHUFFLE_SUCCESS;
+    return false;
   }
 
   bool doneShuffling = false;
-  unsigned shuffleError;
   while (possibleDuplexes.size() > 0 && (!doneShuffling)) {
     // case of Duplex Found
     DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
     MCInst Attempt(MCB);
     HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
-    HexagonMCShuffler MCS(true, MCII, STI, Attempt); // copy packet to the shuffler
+    HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler
     if (MCS.size() == 1) {                     // case of one duplex
       // copy the created duplex in the shuffler to the bundle
       MCS.copyTo(MCB);
-      return HexagonShuffler::SHUFFLE_SUCCESS;
+      return false;
     }
     // try shuffle with this duplex
     doneShuffling = MCS.reshuffleTo(MCB);
-    shuffleError = MCS.getError();
 
     if (doneShuffling)
       break;
   }
 
   if (doneShuffling == false) {
-    HexagonMCShuffler MCS(true, MCII, STI, MCB);
+    HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
     doneShuffling = MCS.reshuffleTo(MCB); // shuffle
-    shuffleError = MCS.getError();
   }
   if (!doneShuffling)
-    return shuffleError;
+    return true;
 
-  return HexagonShuffler::SHUFFLE_SUCCESS;
+  return false;
 }
 
-bool llvm::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
-                            MCInst &MCB, MCInst const &AddMI, int fixupCount) {
+bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
+                            MCSubtargetInfo const &STI, MCInst &MCB,
+                            MCInst const &AddMI, int fixupCount) {
   if (!HexagonMCInstrInfo::isBundle(MCB))
     return false;
 
@@ -246,16 +212,6 @@ bool llvm::HexagonMCShuffle(MCInstrInfo
   if (bhasDuplex && bundleSize >= maxBundleSize)
     return false;
 
-  HexagonMCShuffler MCS(MCII, STI, MCB, AddMI, false);
-  if (!MCS.reshuffleTo(MCB)) {
-    unsigned shuffleError = MCS.getError();
-    switch (shuffleError) {
-    default:
-      return false;
-    case HexagonShuffler::SHUFFLE_SUCCESS: // single instruction case
-      return true;
-    }
-  }
-
-  return true;
+  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);
+  return MCS.reshuffleTo(MCB);
 }

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.h?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.h Mon May  1 14:41:43 2017
@@ -18,24 +18,19 @@
 #include "MCTargetDesc/HexagonShuffler.h"
 
 namespace llvm {
-
 class MCInst;
-
 // Insn bundle shuffler.
 class HexagonMCShuffler : public HexagonShuffler {
-  bool immext_present;
-  bool duplex_present;
-
 public:
-  HexagonMCShuffler(bool Fatal, MCInstrInfo const &MCII,
+  HexagonMCShuffler(MCContext &Context, bool Fatal, MCInstrInfo const &MCII,
                     MCSubtargetInfo const &STI, MCInst &MCB)
-      : HexagonShuffler(MCII, STI) {
+      : HexagonShuffler(Context, Fatal, MCII, STI) {
     init(MCB);
   };
-  HexagonMCShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
-                    MCInst &MCB, MCInst const &AddMI,
-                    bool InsertAtFront)
-      : HexagonShuffler(MCII, STI) {
+  HexagonMCShuffler(MCContext &Context, bool Fatal, MCInstrInfo const &MCII,
+                    MCSubtargetInfo const &STI, MCInst &MCB,
+                    MCInst const &AddMI, bool InsertAtFront)
+      : HexagonShuffler(Context, Fatal, MCII, STI) {
     init(MCB, AddMI, InsertAtFront);
   };
 
@@ -44,22 +39,20 @@ public:
   // Reorder and copy result to another.
   bool reshuffleTo(MCInst &MCB);
 
-  bool immextPresent() const { return immext_present; };
-  bool duplexPresent() const { return duplex_present; };
-
 private:
   void init(MCInst &MCB);
   void init(MCInst &MCB, MCInst const &AddMI, bool InsertAtFront);
 };
 
 // Invocation of the shuffler.
-bool HexagonMCShuffle(bool Fatal, MCInstrInfo const &MCII,
+bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII,
                       MCSubtargetInfo const &STI, MCInst &);
-bool HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
-                      MCInst &, MCInst const &, int);
-unsigned HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
-                          MCContext &Context, MCInst &,
-                          SmallVector<DuplexCandidate, 8>);
-}
+bool HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
+                      MCSubtargetInfo const &STI, MCInst &, MCInst const &,
+                      int);
+bool HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
+                      MCSubtargetInfo const &STI, MCInst &,
+                      SmallVector<DuplexCandidate, 8>);
+} // namespace llvm
 
 #endif // HEXAGONMCSHUFFLER_H

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.cpp Mon May  1 14:41:43 2017
@@ -14,17 +14,18 @@
 
 #define DEBUG_TYPE "hexagon-shuffle"
 
-#include <algorithm>
-#include <utility>
+#include "HexagonShuffler.h"
 #include "Hexagon.h"
 #include "MCTargetDesc/HexagonBaseInfo.h"
-#include "MCTargetDesc/HexagonMCTargetDesc.h"
 #include "MCTargetDesc/HexagonMCInstrInfo.h"
-#include "HexagonShuffler.h"
+#include "MCTargetDesc/HexagonMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <utility>
 
 using namespace llvm;
 
@@ -38,7 +39,7 @@ class HexagonBid {
   unsigned Bid;
 
 public:
-  HexagonBid() : Bid(0){}
+  HexagonBid() : Bid(0) {}
   HexagonBid(unsigned B) { Bid = B ? MAX / countPopulation(B) : 0; }
 
   // Check if the insn priority is overflowed.
@@ -87,7 +88,7 @@ unsigned HexagonResource::setWeight(unsi
   // Calculate relative weight of the insn for the given slot, weighing it the
   // heavier the more restrictive the insn is and the lowest the slots that the
   // insn may be executed in.
-  if (Key == 0 || Units == 0 || (SlotWeight*s >= 32))
+  if (Key == 0 || Units == 0 || (SlotWeight * s >= 32))
     return Weight = 0;
 
   unsigned Ctpop = countPopulation(Units);
@@ -106,9 +107,9 @@ void HexagonCVIResource::SetupTUL(TypeUn
   (*TUL)[HexagonII::TypeCVI_VP_VS] = UnitsAndLanes(CVI_XLANE, 2);
   (*TUL)[HexagonII::TypeCVI_VS] = UnitsAndLanes(CVI_SHIFT, 1);
   (*TUL)[HexagonII::TypeCVI_VINLANESAT] =
-      (CPU == "hexagonv60" || CPU == "hexagonv61" || CPU == "hexagonv61v1") ?
-      UnitsAndLanes(CVI_SHIFT, 1) :
-      UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
+      (CPU == "hexagonv60" || CPU == "hexagonv61" || CPU == "hexagonv61v1")
+          ? UnitsAndLanes(CVI_SHIFT, 1)
+          : UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
   (*TUL)[HexagonII::TypeCVI_VM_LD] =
       UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
   (*TUL)[HexagonII::TypeCVI_VM_TMP_LD] = UnitsAndLanes(CVI_NONE, 0);
@@ -154,18 +155,19 @@ typedef SmallVector<struct CVIUnits, 8>
 static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
 
 {
-  for (unsigned i = 1 ; i < Lanes ; ++i)
+  for (unsigned i = 1; i < Lanes; ++i)
     startBit = (startBit << 1) | startBit;
   return startBit;
 }
 
-static bool checkHVXPipes(const HVXInstsT& hvxInsts, unsigned startIdx, unsigned usedUnits)
+static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
+                          unsigned usedUnits)
 
 {
   if (startIdx < hvxInsts.size()) {
     if (!hvxInsts[startIdx].Units)
       return checkHVXPipes(hvxInsts, startIdx + 1, usedUnits);
-    for (unsigned b = 0x1 ; b <= 0x8 ; b <<= 1) {
+    for (unsigned b = 0x1; b <= 0x8; b <<= 1) {
       if ((hvxInsts[startIdx].Units & b) == 0)
         continue;
       unsigned allBits = makeAllBits(b, hvxInsts[startIdx].Lanes);
@@ -179,9 +181,10 @@ static bool checkHVXPipes(const HVXInsts
   return true;
 }
 
-HexagonShuffler::HexagonShuffler(MCInstrInfo const &MCII,
+HexagonShuffler::HexagonShuffler(MCContext &Context, bool ReportErrors,
+                                 MCInstrInfo const &MCII,
                                  MCSubtargetInfo const &STI)
-    : MCII(MCII), STI(STI) {
+    : Context(Context), MCII(MCII), STI(STI), ReportErrors(ReportErrors) {
   reset();
   HexagonCVIResource::SetupTUL(&TUL, STI.getCPU());
 }
@@ -189,7 +192,6 @@ HexagonShuffler::HexagonShuffler(MCInstr
 void HexagonShuffler::reset() {
   Packet.clear();
   BundleFlags = 0;
-  Error = SHUFFLE_SUCCESS;
 }
 
 void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
@@ -202,8 +204,8 @@ void HexagonShuffler::append(MCInst cons
 static struct {
   unsigned first;
   unsigned second;
-} jumpSlots[] = { {8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1} };
-#define MAX_JUMP_SLOTS (sizeof(jumpSlots)/sizeof(jumpSlots[0]))
+} jumpSlots[] = {{8, 4}, {8, 2}, {8, 1}, {4, 2}, {4, 1}, {2, 1}};
+#define MAX_JUMP_SLOTS (sizeof(jumpSlots) / sizeof(jumpSlots[0]))
 
 namespace {
 bool isDuplexAGroup(unsigned Opcode) {
@@ -248,26 +250,23 @@ unsigned countNeitherAnorX(MCInstrInfo c
     Result += !isDuplexAGroup(subInst0Opcode);
     Result += !isDuplexAGroup(subInst1Opcode);
   } else
-    Result += Type != HexagonII::TypeALU32_2op &&
-              Type != HexagonII::TypeALU32_3op &&
-              Type != HexagonII::TypeALU32_ADDI &&
-              Type != HexagonII::TypeS_2op &&
-              Type != HexagonII::TypeS_3op &&
-              Type != HexagonII::TypeALU64 &&
-              (Type != HexagonII::TypeM ||
-               HexagonMCInstrInfo::isFloat(MCII, ID));
+    Result +=
+        Type != HexagonII::TypeALU32_2op && Type != HexagonII::TypeALU32_3op &&
+        Type != HexagonII::TypeALU32_ADDI && Type != HexagonII::TypeS_2op &&
+        Type != HexagonII::TypeS_3op && Type != HexagonII::TypeALU64 &&
+        (Type != HexagonII::TypeM || HexagonMCInstrInfo::isFloat(MCII, ID));
   return Result;
 }
-}
+} // namespace
 
 /// Check that the packet is legal and enforce relative insn order.
 bool HexagonShuffler::check() {
   // Descriptive slot masks.
   const unsigned slotSingleLoad = 0x1, slotSingleStore = 0x1, slotOne = 0x2,
-                 slotThree = 0x8, //slotFirstJump = 0x8,
-                 slotFirstLoadStore = 0x2, slotLastLoadStore = 0x1;
+                 slotThree = 0x8, // slotFirstJump = 0x8,
+      slotFirstLoadStore = 0x2, slotLastLoadStore = 0x1;
   // Highest slots for branches and stores used to keep their original order.
-  //unsigned slotJump = slotFirstJump;
+  // unsigned slotJump = slotFirstJump;
   unsigned slotLoadStore = slotFirstLoadStore;
   // Number of branches, solo branches, indirect branches.
   unsigned jumps = 0, jump1 = 0;
@@ -287,6 +286,7 @@ bool HexagonShuffler::check() {
   unsigned onlyNo1 = 0;
   unsigned xtypeFloat = 0;
   unsigned pSlot3Cnt = 0;
+  unsigned nvstores = 0;
   unsigned memops = 0;
   unsigned deallocs = 0;
   iterator slot3ISJ = end();
@@ -333,8 +333,7 @@ bool HexagonShuffler::check() {
       ++loads;
       ++memory;
       if (ISJ->Core.getUnits() == slotSingleLoad ||
-          HexagonMCInstrInfo::getType(MCII, ID) ==
-              HexagonII::TypeCVI_VM_VP_LDU)
+          HexagonMCInstrInfo::getType(MCII, ID) == HexagonII::TypeCVI_VM_VP_LDU)
         ++load0;
       if (HexagonMCInstrInfo::getDesc(MCII, ID).isReturn()) {
         ++deallocs, ++jumps, ++jump1; // DEALLOC_RETURN is of type LD.
@@ -368,18 +367,19 @@ bool HexagonShuffler::check() {
       }
       break;
     case HexagonII::TypeV2LDST:
-      if(HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
+      if (HexagonMCInstrInfo::getDesc(MCII, ID).mayLoad()) {
         ++loads;
         ++memory;
         if (ISJ->Core.getUnits() == slotSingleLoad ||
-            HexagonMCInstrInfo::getType(MCII,ID) ==
+            HexagonMCInstrInfo::getType(MCII, ID) ==
                 HexagonII::TypeCVI_VM_VP_LDU)
           ++load0;
-      }
-      else {
+      } else {
         assert(HexagonMCInstrInfo::getDesc(MCII, ID).mayStore());
         ++memory;
         ++stores;
+        if (HexagonMCInstrInfo::isNewValue(MCII, ID))
+          ++nvstores;
       }
       break;
     case HexagonII::TypeCR:
@@ -415,21 +415,21 @@ bool HexagonShuffler::check() {
   if ((load0 > 1 || store0 > 1 || CVIloads > 1 || CVIstores > 1) ||
       (duplex > 1 || (duplex && memory)) || (solo && size() > 1) ||
       (onlyAX && neitherAnorX > 1) || (onlyAX && xtypeFloat)) {
-    Error = SHUFFLE_ERROR_INVALID;
+    reportError(llvm::Twine("invalid instruction packet"));
     return false;
   }
 
   if (jump1 && jumps > 1) {
     // Error if single branch with another branch.
-    Error = SHUFFLE_ERROR_BRANCHES;
+    reportError(llvm::Twine("too many branches in packet"));
     return false;
   }
-  if (memops && stores > 1) {
-    Error = SHUFFLE_ERROR_STORE_LOAD_CONFLICT;
+  if ((nvstores || memops) && stores > 1) {
+    reportError(llvm::Twine("slot 0 instruction does not allow slot 1 store"));
     return false;
   }
   if (deallocs && stores) {
-    Error = SHUFFLE_ERROR_STORE_LOAD_CONFLICT;
+    reportError(llvm::Twine("slot 0 instruction does not allow slot 1 store"));
     return false;
   }
 
@@ -441,7 +441,6 @@ bool HexagonShuffler::check() {
 
     if (!ISJ->Core.getUnits()) {
       // Error if insn may not be executed in any slot.
-      Error = SHUFFLE_ERROR_UNKNOWN;
       return false;
     }
 
@@ -472,7 +471,8 @@ bool HexagonShuffler::check() {
         else if (stores > 1) {
           if (slotLoadStore < slotLastLoadStore) {
             // Error if no more slots available for stores.
-            Error = SHUFFLE_ERROR_STORES;
+            reportError(
+                llvm::Twine("invalid instruction packet: too many stores"));
             return false;
           }
           // Pin the store to the highest slot available to it.
@@ -483,7 +483,7 @@ bool HexagonShuffler::check() {
       }
       if (store1 && stores > 1) {
         // Error if a single store with another store.
-        Error = SHUFFLE_ERROR_STORES;
+        reportError(llvm::Twine("invalid instruction packet: too many stores"));
         return false;
       }
     }
@@ -494,7 +494,7 @@ bool HexagonShuffler::check() {
 
     if (!ISJ->Core.getUnits()) {
       // Error if insn may not be executed in any slot.
-      Error = SHUFFLE_ERROR_NOSLOTS;
+      reportError(llvm::Twine("invalid instruction packet: out of slots"));
       return false;
     }
   }
@@ -503,12 +503,12 @@ bool HexagonShuffler::check() {
   bool validateSlots = true;
   if (jumps > 1) {
     if (foundBranches.size() > 2) {
-      Error = SHUFFLE_ERROR_BRANCHES;
+      reportError(llvm::Twine("too many branches in packet"));
       return false;
     }
 
     // try all possible choices
-    for (unsigned int i = 0 ; i < MAX_JUMP_SLOTS ; ++i) {
+    for (unsigned int i = 0; i < MAX_JUMP_SLOTS; ++i) {
       // validate first jump with this slot rule
       if (!(jumpSlots[i].first & foundBranches[0]->Core.getUnits()))
         continue;
@@ -535,18 +535,18 @@ bool HexagonShuffler::check() {
       if (!bFail) {
         validateSlots = false; // all good, no need to re-do auction
         break;
-      }
-      else
+      } else
         // restore original values
         Packet = PacketSave;
     }
     if (validateSlots == true) {
-      Error = SHUFFLE_ERROR_NOSLOTS;
+      reportError(llvm::Twine("invalid instruction packet: out of slots"));
       return false;
     }
   }
 
-  if (jumps <= 1 && bOnlySlot3 == false && pSlot3Cnt == 1 && slot3ISJ != end()) {
+  if (jumps <= 1 && bOnlySlot3 == false && pSlot3Cnt == 1 &&
+      slot3ISJ != end()) {
     validateSlots = true;
     // save off slot mask of instruction marked with A_PREFER_SLOT3
     // and then pin it to slot #3
@@ -582,7 +582,7 @@ bool HexagonShuffler::check() {
 
     for (iterator I = begin(); I != end(); ++I)
       if (!AuctionCore.bid(I->Core.getUnits())) {
-        Error = SHUFFLE_ERROR_SLOTS;
+        reportError(llvm::Twine("invalid instruction packet: slot error"));
         return false;
       }
   }
@@ -605,12 +605,11 @@ bool HexagonShuffler::check() {
     startIdx = usedUnits = 0x0;
     if (checkHVXPipes(hvxInsts, startIdx, usedUnits) == false) {
       // too many pipes used to be valid
-      Error = SHUFFLE_ERROR_SLOTS;
+      reportError(llvm::Twine("invalid instruction packet: slot error"));
       return false;
     }
   }
 
-  Error = SHUFFLE_SUCCESS;
   return true;
 }
 
@@ -618,12 +617,13 @@ bool HexagonShuffler::shuffle() {
   if (size() > HEXAGON_PACKET_SIZE) {
     // Ignore a packet with with more than what a packet can hold
     // or with compound or duplex insns for now.
-    Error = SHUFFLE_ERROR_INVALID;
+    reportError(llvm::Twine("invalid instruction packet"));
     return false;
   }
 
   // Check and prepare packet.
-  if (size() > 1 && check())
+  bool Ok = true;
+  if (size() > 1 && (Ok = check()))
     // Reorder the handles for each slot.
     for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
          ++nSlot) {
@@ -659,5 +659,10 @@ bool HexagonShuffler::shuffle() {
           dbgs() << '\n');
   DEBUG(dbgs() << '\n');
 
-  return (!getError());
+  return Ok;
+}
+
+void HexagonShuffler::reportError(llvm::Twine const &Msg) {
+  if (ReportErrors)
+    Context.reportError(Loc, Msg);
 }

Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h?rev=301823&r1=301822&r2=301823&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h Mon May  1 14:41:43 2017
@@ -45,8 +45,7 @@ public:
 
   // Check if the resources are in ascending slot order.
   static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
-    return (countPopulation(A.getUnits()) <
-            countPopulation(B.getUnits()));
+    return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
   };
   // Check if the resources are in ascending weight order.
   static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
@@ -106,7 +105,7 @@ class HexagonInstr {
 public:
   HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes *T,
                MCInstrInfo const &MCII, MCInst const *id,
-               MCInst const *Extender, unsigned s)
+               MCInst const *Extender, unsigned s, bool x = false)
       : ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id) {}
 
   MCInst const &getDesc() const { return *ID; };
@@ -136,33 +135,21 @@ class HexagonShuffler {
   HexagonPacket Packet;
   HexagonPacket PacketSave;
 
-  // Shuffling error code.
-  unsigned Error;
-
   HexagonCVIResource::TypeUnitsAndLanes TUL;
 
 protected:
+  MCContext &Context;
   int64_t BundleFlags;
   MCInstrInfo const &MCII;
   MCSubtargetInfo const &STI;
+  SMLoc Loc;
+  bool ReportErrors;
 
 public:
   typedef HexagonPacket::iterator iterator;
 
-  enum {
-    SHUFFLE_SUCCESS = 0,    ///< Successful operation.
-    SHUFFLE_ERROR_INVALID,  ///< Invalid bundle.
-    SHUFFLE_ERROR_STORES,   ///< No free slots for store insns.
-    SHUFFLE_ERROR_LOADS,    ///< No free slots for load insns.
-    SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
-    SHUFFLE_ERROR_NOSLOTS,  ///< No free slots for other insns.
-    SHUFFLE_ERROR_SLOTS,    ///< Over-subscribed slots.
-    SHUFFLE_ERROR_ERRATA2, ///< Errata violation (v60).
-    SHUFFLE_ERROR_STORE_LOAD_CONFLICT, ///< store/load conflict
-    SHUFFLE_ERROR_UNKNOWN   ///< Unknown error.
-  };
-
-  explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
+  HexagonShuffler(MCContext &Context, bool ReportErrors,
+                  MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
 
   // Reset to initial state.
   void reset();
@@ -180,9 +167,8 @@ public:
   void append(MCInst const &ID, MCInst const *Extender, unsigned S);
 
   // Return the error code for the last check or shuffling of the bundle.
-  void setError(unsigned Err) { Error = Err; };
-  unsigned getError() const { return (Error); };
+  void reportError(llvm::Twine const &Msg);
 };
-}
+} // namespace llvm
 
 #endif // HEXAGONSHUFFLER_H




More information about the llvm-commits mailing list