| //===-- 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/TargetLowering.h" | |
| #include "llvm/CodeGen/TargetSubtargetInfo.h" | |
| #include "llvm/InitializePasses.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; | |
| } |