xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/TailDuplication.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- TailDuplication.cpp - Duplicate blocks into predecessors' tails ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file This pass duplicates basic blocks ending in unconditional branches
100b57cec5SDimitry Andric /// into the tails of their predecessors, using the TailDuplicator utility
110b57cec5SDimitry Andric /// class.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
15480093f4SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h"
16480093f4SDimitry Andric #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
1781ad6265SDimitry Andric #include "llvm/CodeGen/MBFIWrapper.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/TailDuplicator.h"
22480093f4SDimitry Andric #include "llvm/InitializePasses.h"
230b57cec5SDimitry Andric #include "llvm/Pass.h"
2481ad6265SDimitry Andric #include "llvm/PassRegistry.h"
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric #define DEBUG_TYPE "tailduplication"
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric namespace {
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric class TailDuplicateBase : public MachineFunctionPass {
330b57cec5SDimitry Andric   TailDuplicator Duplicator;
345ffd83dbSDimitry Andric   std::unique_ptr<MBFIWrapper> MBFIW;
350b57cec5SDimitry Andric   bool PreRegAlloc;
360b57cec5SDimitry Andric public:
370b57cec5SDimitry Andric   TailDuplicateBase(char &PassID, bool PreRegAlloc)
380b57cec5SDimitry Andric     : MachineFunctionPass(PassID), PreRegAlloc(PreRegAlloc) {}
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
43*0fca6ea1SDimitry Andric     AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
44480093f4SDimitry Andric     AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
45480093f4SDimitry Andric     AU.addRequired<ProfileSummaryInfoWrapperPass>();
460b57cec5SDimitry Andric     MachineFunctionPass::getAnalysisUsage(AU);
470b57cec5SDimitry Andric   }
480b57cec5SDimitry Andric };
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric class TailDuplicate : public TailDuplicateBase {
510b57cec5SDimitry Andric public:
520b57cec5SDimitry Andric   static char ID;
530b57cec5SDimitry Andric   TailDuplicate() : TailDuplicateBase(ID, false) {
540b57cec5SDimitry Andric     initializeTailDuplicatePass(*PassRegistry::getPassRegistry());
550b57cec5SDimitry Andric   }
560b57cec5SDimitry Andric };
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric class EarlyTailDuplicate : public TailDuplicateBase {
590b57cec5SDimitry Andric public:
600b57cec5SDimitry Andric   static char ID;
610b57cec5SDimitry Andric   EarlyTailDuplicate() : TailDuplicateBase(ID, true) {
620b57cec5SDimitry Andric     initializeEarlyTailDuplicatePass(*PassRegistry::getPassRegistry());
630b57cec5SDimitry Andric   }
64480093f4SDimitry Andric 
65480093f4SDimitry Andric   MachineFunctionProperties getClearedProperties() const override {
66480093f4SDimitry Andric     return MachineFunctionProperties()
67480093f4SDimitry Andric       .set(MachineFunctionProperties::Property::NoPHIs);
68480093f4SDimitry Andric   }
690b57cec5SDimitry Andric };
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric } // end anonymous namespace
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric char TailDuplicate::ID;
740b57cec5SDimitry Andric char EarlyTailDuplicate::ID;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric char &llvm::TailDuplicateID = TailDuplicate::ID;
770b57cec5SDimitry Andric char &llvm::EarlyTailDuplicateID = EarlyTailDuplicate::ID;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric INITIALIZE_PASS(TailDuplicate, DEBUG_TYPE, "Tail Duplication", false, false)
800b57cec5SDimitry Andric INITIALIZE_PASS(EarlyTailDuplicate, "early-tailduplication",
810b57cec5SDimitry Andric                 "Early Tail Duplication", false, false)
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric bool TailDuplicateBase::runOnMachineFunction(MachineFunction &MF) {
840b57cec5SDimitry Andric   if (skipFunction(MF.getFunction()))
850b57cec5SDimitry Andric     return false;
860b57cec5SDimitry Andric 
87*0fca6ea1SDimitry Andric   auto MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
88480093f4SDimitry Andric   auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
89480093f4SDimitry Andric   auto *MBFI = (PSI && PSI->hasProfileSummary()) ?
90480093f4SDimitry Andric                &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI() :
91480093f4SDimitry Andric                nullptr;
925ffd83dbSDimitry Andric   if (MBFI)
935ffd83dbSDimitry Andric     MBFIW = std::make_unique<MBFIWrapper>(*MBFI);
945ffd83dbSDimitry Andric   Duplicator.initMF(MF, PreRegAlloc, MBPI, MBFI ? MBFIW.get() : nullptr, PSI,
955ffd83dbSDimitry Andric                     /*LayoutMode=*/false);
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   bool MadeChange = false;
980b57cec5SDimitry Andric   while (Duplicator.tailDuplicateBlocks())
990b57cec5SDimitry Andric     MadeChange = true;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   return MadeChange;
1020b57cec5SDimitry Andric }
103