//===- IndirectBrExpandPass.cpp - Expand indirectbr to switch -------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// /// Implements an expansion pass to turn `indirectbr` instructions in the IR /// into `switch` instructions. This works by enumerating the basic blocks in /// a dense range of integers, replacing each `blockaddr` constant with the /// corresponding integer constant, and then building a switch that maps from /// the integers to the actual blocks. All of the indirectbr instructions in the /// function are redirected to this common switch. /// /// While this is generically useful if a target is unable to codegen /// `indirectbr` natively, it is primarily useful when there is some desire to /// get the builtin non-jump-table lowering of a switch even when the input /// source contained an explicit indirect branch construct. /// /// Note that it doesn't make any sense to enable this pass unless a target also /// disables jump-table lowering of switches. Doing that is likely to pessimize /// the code. /// //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/DomTreeUpdater.h" #include "llvm/CodeGen/IndirectBrExpand.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetMachine.h" #include <optional> usingnamespacellvm; #define DEBUG_TYPE … namespace { class IndirectBrExpandLegacyPass : public FunctionPass { … }; } // end anonymous namespace static bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU); PreservedAnalyses IndirectBrExpandPass::run(Function &F, FunctionAnalysisManager &FAM) { … } char IndirectBrExpandLegacyPass::ID = …; INITIALIZE_PASS_BEGIN(IndirectBrExpandLegacyPass, DEBUG_TYPE, "Expand indirectbr instructions", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_END(IndirectBrExpandLegacyPass, DEBUG_TYPE, "Expand indirectbr instructions", false, false) FunctionPass *llvm::createIndirectBrExpandPass() { … } bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU) { … } bool IndirectBrExpandLegacyPass::runOnFunction(Function &F) { … }