diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h index e98df234df8e..1b295e1d4ac6 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelect.h @@ -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) diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp index 302c3763d000..f534c43eaa73 100644 --- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp @@ -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" @@ -26,14 +27,23 @@ 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(); + 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(); 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.