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