Line data Source code
1 : //===-- ResetMachineFunctionPass.cpp - Reset Machine Function ----*- C++ -*-==//
2 : //
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 : //===----------------------------------------------------------------------===//
9 : /// \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.
14 : //===----------------------------------------------------------------------===//
15 :
16 : #include "llvm/ADT/ScopeExit.h"
17 : #include "llvm/ADT/Statistic.h"
18 : #include "llvm/CodeGen/MachineFunction.h"
19 : #include "llvm/CodeGen/MachineFunctionPass.h"
20 : #include "llvm/CodeGen/MachineRegisterInfo.h"
21 : #include "llvm/CodeGen/StackProtector.h"
22 : #include "llvm/CodeGen/Passes.h"
23 : #include "llvm/IR/DiagnosticInfo.h"
24 : #include "llvm/Support/Debug.h"
25 : using namespace llvm;
26 :
27 : #define DEBUG_TYPE "reset-machine-function"
28 :
29 : STATISTIC(NumFunctionsReset, "Number of functions reset");
30 :
31 : namespace {
32 : class ResetMachineFunction : public MachineFunctionPass {
33 : /// Tells whether or not this pass should emit a fallback
34 : /// diagnostic when it resets a function.
35 : bool EmitFallbackDiag;
36 : /// Whether we should abort immediately instead of resetting the function.
37 : bool AbortOnFailedISel;
38 :
39 : public:
40 : static char ID; // Pass identification, replacement for typeid
41 : ResetMachineFunction(bool EmitFallbackDiag = false,
42 : bool AbortOnFailedISel = false)
43 199 : : MachineFunctionPass(ID), EmitFallbackDiag(EmitFallbackDiag),
44 199 : AbortOnFailedISel(AbortOnFailedISel) {}
45 :
46 159 : StringRef getPassName() const override { return "ResetMachineFunction"; }
47 :
48 152 : void getAnalysisUsage(AnalysisUsage &AU) const override {
49 : AU.addPreserved<StackProtector>();
50 152 : MachineFunctionPass::getAnalysisUsage(AU);
51 152 : }
52 :
53 823 : bool runOnMachineFunction(MachineFunction &MF) override {
54 : // 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 =
58 823 : make_scope_exit([&MF]() { MF.getRegInfo().clearVirtRegTypes(); });
59 :
60 823 : if (MF.getProperties().hasProperty(
61 : MachineFunctionProperties::Property::FailedISel)) {
62 125 : if (AbortOnFailedISel)
63 0 : report_fatal_error("Instruction selection failed");
64 : LLVM_DEBUG(dbgs() << "Resetting: " << MF.getName() << '\n');
65 : ++NumFunctionsReset;
66 : MF.reset();
67 125 : if (EmitFallbackDiag) {
68 101 : const Function &F = MF.getFunction();
69 : DiagnosticInfoISelFallback DiagFallback(F);
70 101 : F.getContext().diagnose(DiagFallback);
71 : }
72 125 : return true;
73 : }
74 : return false;
75 : }
76 :
77 : };
78 : } // end anonymous namespace
79 :
80 : char ResetMachineFunction::ID = 0;
81 0 : INITIALIZE_PASS(ResetMachineFunction, DEBUG_TYPE,
82 : "Reset machine function if ISel failed", false, false)
83 :
84 : MachineFunctionPass *
85 199 : llvm::createResetMachineFunctionPass(bool EmitFallbackDiag = false,
86 : bool AbortOnFailedISel = false) {
87 199 : return new ResetMachineFunction(EmitFallbackDiag, AbortOnFailedISel);
88 : }
|