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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// This pass expands Pseudo-instructions produced by ISel, fixes register 10 /// reservations and may do machine frame information adjustments. 11 /// The pseudo instructions are used to allow the expansion to contain control 12 /// flow, such as a conditional move implemented with a conditional branch and a 13 /// 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" 25 using namespace llvm; 26 27 #define DEBUG_TYPE "finalize-isel" 28 29 namespace { 30 class FinalizeISel : public MachineFunctionPass { 31 public: 32 static char ID; // Pass identification, replacement for typeid 33 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 namespace 43 44 static 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 // Iterate through each instruction in the function, looking for pseudos. 51 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { 52 MachineBasicBlock *MBB = &*I; 53 for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end(); 54 MBBI != MBBE; ) { 55 MachineInstr &MI = *MBBI++; 56 57 // Set AdjustsStack to true if the instruction selector emits a stack 58 // frame setup instruction or a stack aligning inlineasm. 59 if (TII->isFrameInstr(MI) || MI.isStackAligningInlineAsm()) 60 MF.getFrameInfo().setAdjustsStack(true); 61 62 // If MI is a pseudo, expand it. 63 if (MI.usesCustomInsertionHook()) { 64 Changed = true; 65 MachineBasicBlock *NewMBB = TLI->EmitInstrWithCustomInserter(MI, MBB); 66 // The expansion may involve new basic blocks. 67 if (NewMBB != MBB) { 68 PreserveCFG = false; 69 MBB = NewMBB; 70 I = NewMBB->getIterator(); 71 MBBI = NewMBB->begin(); 72 MBBE = NewMBB->end(); 73 } 74 } 75 } 76 } 77 78 TLI->finalizeLowering(MF); 79 80 return {Changed, PreserveCFG}; 81 } 82 83 char FinalizeISel::ID = 0; 84 char &llvm::FinalizeISelID = FinalizeISel::ID; 85 INITIALIZE_PASS(FinalizeISel, DEBUG_TYPE, 86 "Finalize ISel and expand pseudo-instructions", false, false) 87 88 bool FinalizeISel::runOnMachineFunction(MachineFunction &MF) { 89 return runImpl(MF).first; 90 } 91 92 PreservedAnalyses FinalizeISelPass::run(MachineFunction &MF, 93 MachineFunctionAnalysisManager &) { 94 auto [Changed, PreserveCFG] = runImpl(MF); 95 if (!Changed) 96 return PreservedAnalyses::all(); 97 auto PA = getMachineFunctionPassPreservedAnalyses(); 98 if (PreserveCFG) 99 PA.preserveSet<CFGAnalyses>(); 100 return PA; 101 } 102