diff options
Diffstat (limited to 'lib/CodeGen/FinalizeISel.cpp')
-rw-r--r-- | lib/CodeGen/FinalizeISel.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/CodeGen/FinalizeISel.cpp b/lib/CodeGen/FinalizeISel.cpp new file mode 100644 index 000000000000..772d7f71bb37 --- /dev/null +++ b/lib/CodeGen/FinalizeISel.cpp @@ -0,0 +1,76 @@ +//===-- 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; +} |