101 lines · cpp
1//===-- llvm/CodeGen/FinalizeISel.cpp ---------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9/// This pass expands Pseudo-instructions produced by ISel, fixes register10/// reservations and may do machine frame information adjustments.11/// The pseudo instructions are used to allow the expansion to contain control12/// flow, such as a conditional move implemented with a conditional branch and a13/// phi, or an atomic operation implemented with a loop.14//15//===----------------------------------------------------------------------===//16 17#include "llvm/CodeGen/FinalizeISel.h"18#include "llvm/CodeGen/MachineFrameInfo.h"19#include "llvm/CodeGen/MachineFunction.h"20#include "llvm/CodeGen/MachineFunctionPass.h"21#include "llvm/CodeGen/TargetInstrInfo.h"22#include "llvm/CodeGen/TargetLowering.h"23#include "llvm/CodeGen/TargetSubtargetInfo.h"24#include "llvm/InitializePasses.h"25using namespace llvm;26 27#define DEBUG_TYPE "finalize-isel"28 29namespace {30 class FinalizeISel : public MachineFunctionPass {31 public:32 static char ID; // Pass identification, replacement for typeid33 FinalizeISel() : MachineFunctionPass(ID) {}34 35 private:36 bool runOnMachineFunction(MachineFunction &MF) override;37 38 void getAnalysisUsage(AnalysisUsage &AU) const override {39 MachineFunctionPass::getAnalysisUsage(AU);40 }41 };42} // end anonymous namespace43 44static std::pair<bool, bool> runImpl(MachineFunction &MF) {45 bool Changed = false;46 bool PreserveCFG = true;47 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();48 const TargetLowering *TLI = MF.getSubtarget().getTargetLowering();49 50 TLI->finalizeLowering(MF);51 52 // Iterate through each instruction in the function, looking for pseudos.53 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {54 MachineBasicBlock *MBB = &*I;55 for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end();56 MBBI != MBBE; ) {57 MachineInstr &MI = *MBBI++;58 59 // Set AdjustsStack to true if the instruction selector emits a stack60 // frame setup instruction or a stack aligning inlineasm.61 if (TII->isFrameInstr(MI) || MI.isStackAligningInlineAsm())62 MF.getFrameInfo().setAdjustsStack(true);63 64 // If MI is a pseudo, expand it.65 if (MI.usesCustomInsertionHook()) {66 Changed = true;67 MachineBasicBlock *NewMBB = TLI->EmitInstrWithCustomInserter(MI, MBB);68 // The expansion may involve new basic blocks.69 if (NewMBB != MBB) {70 PreserveCFG = false;71 MBB = NewMBB;72 I = NewMBB->getIterator();73 MBBI = NewMBB->begin();74 MBBE = NewMBB->end();75 }76 }77 }78 }79 return {Changed, PreserveCFG};80}81 82char FinalizeISel::ID = 0;83char &llvm::FinalizeISelID = FinalizeISel::ID;84INITIALIZE_PASS(FinalizeISel, DEBUG_TYPE,85 "Finalize ISel and expand pseudo-instructions", false, false)86 87bool FinalizeISel::runOnMachineFunction(MachineFunction &MF) {88 return runImpl(MF).first;89}90 91PreservedAnalyses FinalizeISelPass::run(MachineFunction &MF,92 MachineFunctionAnalysisManager &) {93 auto [Changed, PreserveCFG] = runImpl(MF);94 if (!Changed)95 return PreservedAnalyses::all();96 auto PA = getMachineFunctionPassPreservedAnalyses();97 if (PreserveCFG)98 PA.preserveSet<CFGAnalyses>();99 return PA;100}101