blob: a02302e6ff993703134660c98fd11fce27a21ccf [file] [log] [blame]
Quentin Colombetf8e3a512016-09-23 18:38:15 +00001//===-- ResetMachineFunctionPass.cpp - Reset Machine Function ----*- C++ -*-==//
Quentin Colombetc47e5db2016-08-27 00:18:31 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Quentin Colombetf8e3a512016-09-23 18:38:15 +00009/// \file
10/// This file implements a pass that will conditionally reset a machine
11/// function as if it was just created. This is used to provide a fallback
12/// mechanism when GlobalISel fails, thus the condition for the reset to
13/// happen is that the MachineFunction has the FailedISel property.
Quentin Colombetc47e5db2016-08-27 00:18:31 +000014//===----------------------------------------------------------------------===//
15
Roman Tereshin8e63a832018-02-28 17:55:45 +000016#include "llvm/ADT/ScopeExit.h"
Quentin Colombet76cc1a92016-09-23 18:38:13 +000017#include "llvm/ADT/Statistic.h"
Quentin Colombetc47e5db2016-08-27 00:18:31 +000018#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/MachineFunctionPass.h"
Roman Tereshin8e63a832018-02-28 17:55:45 +000020#include "llvm/CodeGen/MachineRegisterInfo.h"
Matthias Braund79789a2018-07-13 00:08:38 +000021#include "llvm/CodeGen/StackProtector.h"
Chandler Carruthe3e43d92017-06-06 11:49:48 +000022#include "llvm/CodeGen/Passes.h"
Quentin Colombet8e21d402016-08-31 18:43:01 +000023#include "llvm/IR/DiagnosticInfo.h"
Quentin Colombetc47e5db2016-08-27 00:18:31 +000024#include "llvm/Support/Debug.h"
25using namespace llvm;
26
27#define DEBUG_TYPE "reset-machine-function"
28
Quentin Colombet76cc1a92016-09-23 18:38:13 +000029STATISTIC(NumFunctionsReset, "Number of functions reset");
30
Quentin Colombetc47e5db2016-08-27 00:18:31 +000031namespace {
32 class ResetMachineFunction : public MachineFunctionPass {
Quentin Colombet8e21d402016-08-31 18:43:01 +000033 /// Tells whether or not this pass should emit a fallback
34 /// diagnostic when it resets a function.
35 bool EmitFallbackDiag;
Justin Bogner669e2972017-01-13 23:46:11 +000036 /// Whether we should abort immediately instead of resetting the function.
37 bool AbortOnFailedISel;
Quentin Colombet8e21d402016-08-31 18:43:01 +000038
Quentin Colombetc47e5db2016-08-27 00:18:31 +000039 public:
40 static char ID; // Pass identification, replacement for typeid
Justin Bogner669e2972017-01-13 23:46:11 +000041 ResetMachineFunction(bool EmitFallbackDiag = false,
42 bool AbortOnFailedISel = false)
43 : MachineFunctionPass(ID), EmitFallbackDiag(EmitFallbackDiag),
44 AbortOnFailedISel(AbortOnFailedISel) {}
Quentin Colombetc47e5db2016-08-27 00:18:31 +000045
Mehdi Amini67f335d2016-10-01 02:56:57 +000046 StringRef getPassName() const override { return "ResetMachineFunction"; }
Quentin Colombetc47e5db2016-08-27 00:18:31 +000047
Matthias Braund79789a2018-07-13 00:08:38 +000048 void getAnalysisUsage(AnalysisUsage &AU) const override {
49 AU.addPreserved<StackProtector>();
50 MachineFunctionPass::getAnalysisUsage(AU);
51 }
52
Quentin Colombetc47e5db2016-08-27 00:18:31 +000053 bool runOnMachineFunction(MachineFunction &MF) override {
Roman Tereshin8e63a832018-02-28 17:55:45 +000054 // No matter what happened, whether we successfully selected the function
55 // or not, nothing is going to use the vreg types after us. Make sure they
56 // disappear.
57 auto ClearVRegTypesOnReturn =
Roman Tereshincb64cbc2018-05-23 21:12:02 +000058 make_scope_exit([&MF]() { MF.getRegInfo().clearVirtRegTypes(); });
Roman Tereshin8e63a832018-02-28 17:55:45 +000059
Quentin Colombetc47e5db2016-08-27 00:18:31 +000060 if (MF.getProperties().hasProperty(
61 MachineFunctionProperties::Property::FailedISel)) {
Justin Bogner669e2972017-01-13 23:46:11 +000062 if (AbortOnFailedISel)
63 report_fatal_error("Instruction selection failed");
Nicola Zaghen0818e782018-05-14 12:53:11 +000064 LLVM_DEBUG(dbgs() << "Resetting: " << MF.getName() << '\n');
Quentin Colombet76cc1a92016-09-23 18:38:13 +000065 ++NumFunctionsReset;
Quentin Colombetc47e5db2016-08-27 00:18:31 +000066 MF.reset();
Quentin Colombet8e21d402016-08-31 18:43:01 +000067 if (EmitFallbackDiag) {
Matthias Braund3181392017-12-15 22:22:58 +000068 const Function &F = MF.getFunction();
Quentin Colombet8e21d402016-08-31 18:43:01 +000069 DiagnosticInfoISelFallback DiagFallback(F);
70 F.getContext().diagnose(DiagFallback);
71 }
Quentin Colombetc47e5db2016-08-27 00:18:31 +000072 return true;
73 }
74 return false;
75 }
76
77 };
78} // end anonymous namespace
79
80char ResetMachineFunction::ID = 0;
81INITIALIZE_PASS(ResetMachineFunction, DEBUG_TYPE,
Amara Emersonf2316f62018-02-02 01:49:59 +000082 "Reset machine function if ISel failed", false, false)
Quentin Colombetc47e5db2016-08-27 00:18:31 +000083
84MachineFunctionPass *
Justin Bogner669e2972017-01-13 23:46:11 +000085llvm::createResetMachineFunctionPass(bool EmitFallbackDiag = false,
86 bool AbortOnFailedISel = false) {
87 return new ResetMachineFunction(EmitFallbackDiag, AbortOnFailedISel);
Quentin Colombetc47e5db2016-08-27 00:18:31 +000088}