[InstructionSelect] Do not abort when the target wants to fall back.
authorQuentin Colombet <qcolombet@apple.com>
Sat, 27 Aug 2016 02:38:24 +0000 (02:38 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Sat, 27 Aug 2016 02:38:24 +0000 (02:38 +0000)
llvm-svn: 279905

llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h
llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp

index e98df23..1b295e1 100644 (file)
@@ -30,6 +30,8 @@ public:
   static char ID;
   const char *getPassName() const override { return "InstructionSelect"; }
 
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
   MachineFunctionProperties getRequiredProperties() const override {
     return MachineFunctionProperties()
         .set(MachineFunctionProperties::Property::IsSSA)
index 302c376..f534c43 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
 #include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/Function.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 using namespace llvm;
 
 char InstructionSelect::ID = 0;
-INITIALIZE_PASS(InstructionSelect, DEBUG_TYPE,
-                "Select target instructions out of generic instructions",
-                false, false);
+INITIALIZE_PASS_BEGIN(InstructionSelect, DEBUG_TYPE,
+                      "Select target instructions out of generic instructions",
+                      false, false)
+INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE,
+                    "Select target instructions out of generic instructions",
+                    false, false)
 
 InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) {
   initializeInstructionSelectPass(*PassRegistry::getPassRegistry());
 }
 
+void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<TargetPassConfig>();
+  MachineFunctionPass::getAnalysisUsage(AU);
+}
+
 static void reportSelectionError(const MachineInstr &MI, const Twine &Message) {
   const MachineFunction &MF = *MI.getParent()->getParent();
   std::string ErrStorage;
@@ -50,6 +60,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
 
   DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n');
 
+  const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
   const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector();
   assert(ISel && "Cannot work without InstructionSelector");
 
@@ -75,19 +86,29 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
   const size_t NumBlocks = MF.size();
 #endif
 
+  bool Failed = false;
   for (MachineBasicBlock *MBB : post_order(&MF)) {
     for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(),
                                              End = MBB->rend();
          MII != End;) {
       MachineInstr &MI = *MII++;
       DEBUG(dbgs() << "Selecting: " << MI << '\n');
-      if (!ISel->select(MI))
-        reportSelectionError(MI, "Cannot select");
-      // FIXME: It would be nice to dump all inserted instructions.  It's not
-      // obvious how, esp. considering select() can insert after MI.
+      if (!ISel->select(MI)) {
+        if (TPC.isGlobalISelAbortEnabled())
+          // FIXME: It would be nice to dump all inserted instructions.  It's
+          // not
+          // obvious how, esp. considering select() can insert after MI.
+          reportSelectionError(MI, "Cannot select");
+        Failed = true;
+        break;
+      }
     }
   }
 
+  if (!TPC.isGlobalISelAbortEnabled() && (Failed || MF.size() == NumBlocks)) {
+    MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
+    return false;
+  }
   assert(MF.size() == NumBlocks && "Inserting blocks is not supported yet");
 
   // Now that selection is complete, there are no more generic vregs.