1d88c1a5aSDimitry Andric //===-- ResetMachineFunctionPass.cpp - Reset Machine Function ----*- C++ -*-==// 2d88c1a5aSDimitry Andric // 3d88c1a5aSDimitry Andric // The LLVM Compiler Infrastructure 4d88c1a5aSDimitry Andric // 5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source 6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details. 7d88c1a5aSDimitry Andric // 8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===// 9d88c1a5aSDimitry Andric /// \file 10d88c1a5aSDimitry Andric /// This file implements a pass that will conditionally reset a machine 11d88c1a5aSDimitry Andric /// function as if it was just created. This is used to provide a fallback 12d88c1a5aSDimitry Andric /// mechanism when GlobalISel fails, thus the condition for the reset to 13d88c1a5aSDimitry Andric /// happen is that the MachineFunction has the FailedISel property. 14d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===// 15d88c1a5aSDimitry Andric 16d88c1a5aSDimitry Andric #include "llvm/ADT/Statistic.h" 17d88c1a5aSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 18d88c1a5aSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 19db17bf38SDimitry Andric #include "llvm/CodeGen/Passes.h" 20d88c1a5aSDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 21d88c1a5aSDimitry Andric #include "llvm/Support/Debug.h" 22d88c1a5aSDimitry Andric using namespace llvm; 23d88c1a5aSDimitry Andric 24d88c1a5aSDimitry Andric #define DEBUG_TYPE "reset-machine-function" 25d88c1a5aSDimitry Andric 26d88c1a5aSDimitry Andric STATISTIC(NumFunctionsReset, "Number of functions reset"); 27d88c1a5aSDimitry Andric 28d88c1a5aSDimitry Andric namespace { 29d88c1a5aSDimitry Andric class ResetMachineFunction : public MachineFunctionPass { 30d88c1a5aSDimitry Andric /// Tells whether or not this pass should emit a fallback 31d88c1a5aSDimitry Andric /// diagnostic when it resets a function. 32d88c1a5aSDimitry Andric bool EmitFallbackDiag; 337a7e6055SDimitry Andric /// Whether we should abort immediately instead of resetting the function. 347a7e6055SDimitry Andric bool AbortOnFailedISel; 35d88c1a5aSDimitry Andric 36d88c1a5aSDimitry Andric public: 37d88c1a5aSDimitry Andric static char ID; // Pass identification, replacement for typeid 387a7e6055SDimitry Andric ResetMachineFunction(bool EmitFallbackDiag = false, 397a7e6055SDimitry Andric bool AbortOnFailedISel = false) 407a7e6055SDimitry Andric : MachineFunctionPass(ID), EmitFallbackDiag(EmitFallbackDiag), 417a7e6055SDimitry Andric AbortOnFailedISel(AbortOnFailedISel) {} 42d88c1a5aSDimitry Andric 43d88c1a5aSDimitry Andric StringRef getPassName() const override { return "ResetMachineFunction"; } 44d88c1a5aSDimitry Andric 45d88c1a5aSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override { 46d88c1a5aSDimitry Andric if (MF.getProperties().hasProperty( 47d88c1a5aSDimitry Andric MachineFunctionProperties::Property::FailedISel)) { 487a7e6055SDimitry Andric if (AbortOnFailedISel) 497a7e6055SDimitry Andric report_fatal_error("Instruction selection failed"); 50d88c1a5aSDimitry Andric DEBUG(dbgs() << "Reseting: " << MF.getName() << '\n'); 51d88c1a5aSDimitry Andric ++NumFunctionsReset; 52d88c1a5aSDimitry Andric MF.reset(); 53d88c1a5aSDimitry Andric if (EmitFallbackDiag) { 542cab237bSDimitry Andric const Function &F = MF.getFunction(); 55d88c1a5aSDimitry Andric DiagnosticInfoISelFallback DiagFallback(F); 56d88c1a5aSDimitry Andric F.getContext().diagnose(DiagFallback); 57d88c1a5aSDimitry Andric } 58d88c1a5aSDimitry Andric return true; 59d88c1a5aSDimitry Andric } 60d88c1a5aSDimitry Andric return false; 61d88c1a5aSDimitry Andric } 62d88c1a5aSDimitry Andric 63d88c1a5aSDimitry Andric }; 64d88c1a5aSDimitry Andric } // end anonymous namespace 65d88c1a5aSDimitry Andric 66d88c1a5aSDimitry Andric char ResetMachineFunction::ID = 0; 67d88c1a5aSDimitry Andric INITIALIZE_PASS(ResetMachineFunction, DEBUG_TYPE, 68d88c1a5aSDimitry Andric "reset machine function if ISel failed", false, false) 69d88c1a5aSDimitry Andric 70d88c1a5aSDimitry Andric MachineFunctionPass * 717a7e6055SDimitry Andric llvm::createResetMachineFunctionPass(bool EmitFallbackDiag = false, 727a7e6055SDimitry Andric bool AbortOnFailedISel = false) { 737a7e6055SDimitry Andric return new ResetMachineFunction(EmitFallbackDiag, AbortOnFailedISel); 74d88c1a5aSDimitry Andric } 75