summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/MIRYamlMapping.h2
-rw-r--r--llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp14
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIRParser.cpp2
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp14
-rw-r--r--llvm/lib/CodeGen/ResetMachineFunctionPass.cpp8
-rw-r--r--llvm/test/CodeGen/MIR/AArch64/print-parse-verify-failedISel-property.mir65
7 files changed, 94 insertions, 13 deletions
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index ba40e522e26..b75f9c8a693 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -472,6 +472,7 @@ struct MachineFunction {
bool Legalized = false;
bool RegBankSelected = false;
bool Selected = false;
+ bool FailedISel = false;
// Register information
bool TracksRegLiveness = false;
std::vector<VirtualRegisterDefinition> VirtualRegisters;
@@ -495,6 +496,7 @@ template <> struct MappingTraits<MachineFunction> {
YamlIO.mapOptional("legalized", MF.Legalized, false);
YamlIO.mapOptional("regBankSelected", MF.RegBankSelected, false);
YamlIO.mapOptional("selected", MF.Selected, false);
+ YamlIO.mapOptional("failedISel", MF.FailedISel, false);
YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
YamlIO.mapOptional("registers", MF.VirtualRegisters,
std::vector<VirtualRegisterDefinition>());
diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index 301233073b1..51344567591 100644
--- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -12,7 +12,6 @@
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
@@ -61,13 +60,6 @@ void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
}
bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
- const MachineRegisterInfo &MRI = MF.getRegInfo();
-
- // No matter what happens, whether we successfully select the function or not,
- // nothing is going to use the vreg types after us. Make sure they disappear.
- auto ClearVRegTypesOnReturn =
- make_scope_exit([&]() { MRI.getVRegToType().clear(); });
-
// If the ISel pipeline failed, do not bother running that pass.
if (MF.getProperties().hasProperty(
MachineFunctionProperties::Property::FailedISel))
@@ -85,6 +77,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
// FIXME: There are many other MF/MFI fields we need to initialize.
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
#ifndef NDEBUG
// Check that our input is fully legal: we require the function to have the
// Legalized property, so it should be.
@@ -238,6 +231,11 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
.getTarget()
.getBackendName());
+ // If we successfully selected the function nothing is going to use the vreg
+ // types after us (otherwise MIRPrinter would need them). Make sure the types
+ // disappear.
+ MRI.getVRegToType().clear();
+
// FIXME: Should we accurately track changes?
return true;
}
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 52ac08cd2d3..9eb94c004f5 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -362,6 +362,8 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
MachineFunctionProperties::Property::RegBankSelected);
if (YamlMF.Selected)
MF.getProperties().set(MachineFunctionProperties::Property::Selected);
+ if (YamlMF.FailedISel)
+ MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses,
Names2RegBanks);
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 658b596262d..683ad6e479a 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -207,6 +207,8 @@ void MIRPrinter::print(const MachineFunction &MF) {
MachineFunctionProperties::Property::RegBankSelected);
YamlMF.Selected = MF.getProperties().hasProperty(
MachineFunctionProperties::Property::Selected);
+ YamlMF.FailedISel = MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::FailedISel);
convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
ModuleSlotTracker MST(MF.getFunction().getParent());
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 3b38bbff215..a9fe04d7576 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -359,11 +359,15 @@ unsigned MachineVerifier::verify(MachineFunction &MF) {
TRI = MF.getSubtarget().getRegisterInfo();
MRI = &MF.getRegInfo();
- isFunctionRegBankSelected = MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::RegBankSelected);
- isFunctionSelected = MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::Selected);
-
+ const bool isFunctionFailedISel = MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::FailedISel);
+ isFunctionRegBankSelected =
+ !isFunctionFailedISel &&
+ MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::RegBankSelected);
+ isFunctionSelected = !isFunctionFailedISel &&
+ MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::Selected);
LiveVars = nullptr;
LiveInts = nullptr;
LiveStks = nullptr;
diff --git a/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp b/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp
index 2be3a557387..72b631baf94 100644
--- a/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp
+++ b/llvm/lib/CodeGen/ResetMachineFunctionPass.cpp
@@ -13,9 +13,11 @@
/// happen is that the MachineFunction has the FailedISel property.
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/Support/Debug.h"
@@ -43,6 +45,12 @@ namespace {
StringRef getPassName() const override { return "ResetMachineFunction"; }
bool runOnMachineFunction(MachineFunction &MF) override {
+ // No matter what happened, whether we successfully selected the function
+ // or not, nothing is going to use the vreg types after us. Make sure they
+ // disappear.
+ auto ClearVRegTypesOnReturn =
+ make_scope_exit([&MF]() { MF.getRegInfo().getVRegToType().clear(); });
+
if (MF.getProperties().hasProperty(
MachineFunctionProperties::Property::FailedISel)) {
if (AbortOnFailedISel)
diff --git a/llvm/test/CodeGen/MIR/AArch64/print-parse-verify-failedISel-property.mir b/llvm/test/CodeGen/MIR/AArch64/print-parse-verify-failedISel-property.mir
new file mode 100644
index 00000000000..4d4b93eb41a
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/AArch64/print-parse-verify-failedISel-property.mir
@@ -0,0 +1,65 @@
+# RUN: llc -mtriple aarch64-- -run-pass instruction-select -simplify-mir \
+# RUN: -verify-machineinstrs %s -o - | FileCheck %s
+#
+# RUN: llc -mtriple aarch64-- -global-isel=true -global-isel-abort=2 \
+# RUN: -start-after=regbankselect -stop-before=expand-isel-pseudos \
+# RUN: -simplify-mir -verify-machineinstrs %s -o - 2>&1 \
+# RUN: | FileCheck %s --check-prefix=FALLBACK
+
+# Test that:
+# 1) MIRParser can deserialize FailedISel property.
+# 2) Machine Verifier respects FailedISel and doesn't complain needlessly.
+# 3) MIRPrinter is able to print FailedISel MIR after InstructionSelect pass.
+# 4) MIRPrinter can serialize FailedISel property.
+# 5) It's possible to start llc mid-GlobalISel pipeline from a MIR file with
+# the FailedISel property set to true and watch it properly fallback to
+# FastISel / SelectionDAG ISel.
+--- |
+ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64--"
+
+ define i32 @test(i32 %a, i32 %b) #0 {
+ entry:
+ %add = add i32 %b, %a
+ ret i32 %add
+ }
+
+ attributes #0 = { nounwind readnone ssp }
+...
+---
+# CHECK-LABEL: name: test
+# CHECK: failedISel: true
+#
+# FALLBACK: warning: Instruction selection used fallback path for test
+# FALLBACK-LABEL: name: test
+# FALLBACK-NOT: failedISel
+name: test
+alignment: 2
+legalized: true
+regBankSelected: true
+failedISel: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $w0, $w1
+
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[COPY1]], [[COPY]]
+ ; CHECK: $w0 = COPY [[ADD]](s32)
+ ; CHECK: RET_ReallyLR implicit $w0
+ ;
+ ; FALLBACK: liveins: $w0, $w1
+ ; FALLBACK: [[COPY:%[0-9]+]]:gpr32 = COPY $w1
+ ; FALLBACK: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
+ ; FALLBACK: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY1]]
+ ; FALLBACK: $w0 = COPY [[ADDWrr]]
+ ; FALLBACK: RET_ReallyLR implicit $w0
+
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:gpr(s32) = G_ADD %1, %0
+ $w0 = COPY %2(s32)
+ RET_ReallyLR implicit $w0
+...
OpenPOWER on IntegriCloud