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