blob: 0f73973c8a51cecc93815ed537ce7653f8467eae [file] [log] [blame]
Quentin Colombet380cd882016-09-23 18:38:15 +00001//===-- ResetMachineFunctionPass.cpp - Reset Machine Function ----*- C++ -*-==//
Quentin Colombet374796d2016-08-27 00:18:31 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Quentin Colombet374796d2016-08-27 00:18:31 +00006//
7//===----------------------------------------------------------------------===//
Quentin Colombet380cd882016-09-23 18:38:15 +00008/// \file
9/// This file implements a pass that will conditionally reset a machine
10/// function as if it was just created. This is used to provide a fallback
11/// mechanism when GlobalISel fails, thus the condition for the reset to
12/// happen is that the MachineFunction has the FailedISel property.
Quentin Colombet374796d2016-08-27 00:18:31 +000013//===----------------------------------------------------------------------===//
14
Roman Tereshin3054ece2018-02-28 17:55:45 +000015#include "llvm/ADT/ScopeExit.h"
Quentin Colombet0f4c20a2016-09-23 18:38:13 +000016#include "llvm/ADT/Statistic.h"
Quentin Colombet374796d2016-08-27 00:18:31 +000017#include "llvm/CodeGen/MachineFunction.h"
18#include "llvm/CodeGen/MachineFunctionPass.h"
Roman Tereshin3054ece2018-02-28 17:55:45 +000019#include "llvm/CodeGen/MachineRegisterInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000020#include "llvm/CodeGen/Passes.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080021#include "llvm/CodeGen/StackProtector.h"
Quentin Colombet612cd1f2016-08-31 18:43:01 +000022#include "llvm/IR/DiagnosticInfo.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080023#include "llvm/InitializePasses.h"
Quentin Colombet374796d2016-08-27 00:18:31 +000024#include "llvm/Support/Debug.h"
25using namespace llvm;
26
27#define DEBUG_TYPE "reset-machine-function"
28
Quentin Colombet0f4c20a2016-09-23 18:38:13 +000029STATISTIC(NumFunctionsReset, "Number of functions reset");
Craig Topper66df7362019-03-14 01:13:15 +000030STATISTIC(NumFunctionsVisited, "Number of functions visited");
Quentin Colombet0f4c20a2016-09-23 18:38:13 +000031
Quentin Colombet374796d2016-08-27 00:18:31 +000032namespace {
33 class ResetMachineFunction : public MachineFunctionPass {
Quentin Colombet612cd1f2016-08-31 18:43:01 +000034 /// Tells whether or not this pass should emit a fallback
35 /// diagnostic when it resets a function.
36 bool EmitFallbackDiag;
Justin Bogner1a314da2017-01-13 23:46:11 +000037 /// Whether we should abort immediately instead of resetting the function.
38 bool AbortOnFailedISel;
Quentin Colombet612cd1f2016-08-31 18:43:01 +000039
Quentin Colombet374796d2016-08-27 00:18:31 +000040 public:
41 static char ID; // Pass identification, replacement for typeid
Justin Bogner1a314da2017-01-13 23:46:11 +000042 ResetMachineFunction(bool EmitFallbackDiag = false,
43 bool AbortOnFailedISel = false)
44 : MachineFunctionPass(ID), EmitFallbackDiag(EmitFallbackDiag),
45 AbortOnFailedISel(AbortOnFailedISel) {}
Quentin Colombet374796d2016-08-27 00:18:31 +000046
Mehdi Amini117296c2016-10-01 02:56:57 +000047 StringRef getPassName() const override { return "ResetMachineFunction"; }
Quentin Colombet374796d2016-08-27 00:18:31 +000048
Matthias Braun90ad6832018-07-13 00:08:38 +000049 void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.addPreserved<StackProtector>();
51 MachineFunctionPass::getAnalysisUsage(AU);
52 }
53
Quentin Colombet374796d2016-08-27 00:18:31 +000054 bool runOnMachineFunction(MachineFunction &MF) override {
Craig Topper66df7362019-03-14 01:13:15 +000055 ++NumFunctionsVisited;
Roman Tereshin3054ece2018-02-28 17:55:45 +000056 // No matter what happened, whether we successfully selected the function
57 // or not, nothing is going to use the vreg types after us. Make sure they
58 // disappear.
59 auto ClearVRegTypesOnReturn =
Roman Tereshin13229af2018-05-23 21:12:02 +000060 make_scope_exit([&MF]() { MF.getRegInfo().clearVirtRegTypes(); });
Roman Tereshin3054ece2018-02-28 17:55:45 +000061
Quentin Colombet374796d2016-08-27 00:18:31 +000062 if (MF.getProperties().hasProperty(
63 MachineFunctionProperties::Property::FailedISel)) {
Justin Bogner1a314da2017-01-13 23:46:11 +000064 if (AbortOnFailedISel)
65 report_fatal_error("Instruction selection failed");
Nicola Zaghend34e60c2018-05-14 12:53:11 +000066 LLVM_DEBUG(dbgs() << "Resetting: " << MF.getName() << '\n');
Quentin Colombet0f4c20a2016-09-23 18:38:13 +000067 ++NumFunctionsReset;
Quentin Colombet374796d2016-08-27 00:18:31 +000068 MF.reset();
Quentin Colombet612cd1f2016-08-31 18:43:01 +000069 if (EmitFallbackDiag) {
Matthias Braunf1caa282017-12-15 22:22:58 +000070 const Function &F = MF.getFunction();
Quentin Colombet612cd1f2016-08-31 18:43:01 +000071 DiagnosticInfoISelFallback DiagFallback(F);
72 F.getContext().diagnose(DiagFallback);
73 }
Quentin Colombet374796d2016-08-27 00:18:31 +000074 return true;
75 }
76 return false;
77 }
78
79 };
80} // end anonymous namespace
81
82char ResetMachineFunction::ID = 0;
83INITIALIZE_PASS(ResetMachineFunction, DEBUG_TYPE,
Amara Emerson98af4662018-02-02 01:49:59 +000084 "Reset machine function if ISel failed", false, false)
Quentin Colombet374796d2016-08-27 00:18:31 +000085
86MachineFunctionPass *
Justin Bogner1a314da2017-01-13 23:46:11 +000087llvm::createResetMachineFunctionPass(bool EmitFallbackDiag = false,
88 bool AbortOnFailedISel = false) {
89 return new ResetMachineFunction(EmitFallbackDiag, AbortOnFailedISel);
Quentin Colombet374796d2016-08-27 00:18:31 +000090}