|  | //===-- llvm/CodeGen/FinalizeISel.cpp ---------------------------*- C++ -*-===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | /// This pass expands Pseudo-instructions produced by ISel, fixes register | 
|  | /// reservations and may do machine frame information adjustments. | 
|  | /// The pseudo instructions are used to allow the expansion to contain control | 
|  | /// flow, such as a conditional move implemented with a conditional branch and a | 
|  | /// phi, or an atomic operation implemented with a loop. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm/CodeGen/MachineFunction.h" | 
|  | #include "llvm/CodeGen/MachineFunctionPass.h" | 
|  | #include "llvm/CodeGen/Passes.h" | 
|  | #include "llvm/CodeGen/TargetLowering.h" | 
|  | #include "llvm/CodeGen/TargetSubtargetInfo.h" | 
|  | #include "llvm/Support/Debug.h" | 
|  | using namespace llvm; | 
|  |  | 
|  | #define DEBUG_TYPE "finalize-isel" | 
|  |  | 
|  | namespace { | 
|  | class FinalizeISel : public MachineFunctionPass { | 
|  | public: | 
|  | static char ID; // Pass identification, replacement for typeid | 
|  | FinalizeISel() : MachineFunctionPass(ID) {} | 
|  |  | 
|  | private: | 
|  | bool runOnMachineFunction(MachineFunction &MF) override; | 
|  |  | 
|  | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
|  | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | } | 
|  | }; | 
|  | } // end anonymous namespace | 
|  |  | 
|  | char FinalizeISel::ID = 0; | 
|  | char &llvm::FinalizeISelID = FinalizeISel::ID; | 
|  | INITIALIZE_PASS(FinalizeISel, DEBUG_TYPE, | 
|  | "Finalize ISel and expand pseudo-instructions", false, false) | 
|  |  | 
|  | bool FinalizeISel::runOnMachineFunction(MachineFunction &MF) { | 
|  | bool Changed = false; | 
|  | const TargetLowering *TLI = MF.getSubtarget().getTargetLowering(); | 
|  |  | 
|  | // Iterate through each instruction in the function, looking for pseudos. | 
|  | for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { | 
|  | MachineBasicBlock *MBB = &*I; | 
|  | for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end(); | 
|  | MBBI != MBBE; ) { | 
|  | MachineInstr &MI = *MBBI++; | 
|  |  | 
|  | // If MI is a pseudo, expand it. | 
|  | if (MI.usesCustomInsertionHook()) { | 
|  | Changed = true; | 
|  | MachineBasicBlock *NewMBB = TLI->EmitInstrWithCustomInserter(MI, MBB); | 
|  | // The expansion may involve new basic blocks. | 
|  | if (NewMBB != MBB) { | 
|  | MBB = NewMBB; | 
|  | I = NewMBB->getIterator(); | 
|  | MBBI = NewMBB->begin(); | 
|  | MBBE = NewMBB->end(); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | TLI->finalizeLowering(MF); | 
|  |  | 
|  | return Changed; | 
|  | } |