89 lines · cpp
1//===------------ RISCVLandingPadSetup.cpp ---------------------------------==//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-exception6//7//===----------------------------------------------------------------------===//8//9// This is a RISC-V pass to setup landing pad labels for indirect jumps.10// Currently this pass only supports fixed labels.11//12//===----------------------------------------------------------------------===//13 14#include "RISCV.h"15#include "RISCVInstrInfo.h"16#include "RISCVSubtarget.h"17#include "llvm/CodeGen/MachineFunctionPass.h"18#include "llvm/CodeGen/MachineInstrBuilder.h"19 20using namespace llvm;21 22#define DEBUG_TYPE "riscv-lpad-setup"23#define PASS_NAME "RISC-V Landing Pad Setup"24 25extern cl::opt<uint32_t> PreferredLandingPadLabel;26 27namespace {28 29class RISCVLandingPadSetup : public MachineFunctionPass {30public:31 static char ID;32 33 RISCVLandingPadSetup() : MachineFunctionPass(ID) {}34 35 bool runOnMachineFunction(MachineFunction &F) override;36 37 StringRef getPassName() const override { return PASS_NAME; }38 39 void getAnalysisUsage(AnalysisUsage &AU) const override {40 AU.setPreservesCFG();41 MachineFunctionPass::getAnalysisUsage(AU);42 }43};44 45} // end anonymous namespace46 47bool RISCVLandingPadSetup::runOnMachineFunction(MachineFunction &MF) {48 const auto &STI = MF.getSubtarget<RISCVSubtarget>();49 const RISCVInstrInfo &TII = *STI.getInstrInfo();50 51 if (!STI.hasStdExtZicfilp())52 return false;53 54 uint32_t Label = 0;55 if (PreferredLandingPadLabel.getNumOccurrences() > 0) {56 if (!isUInt<20>(PreferredLandingPadLabel))57 report_fatal_error("riscv-landing-pad-label=<val>, <val> needs to fit in "58 "unsigned 20-bits");59 Label = PreferredLandingPadLabel;60 }61 62 // Zicfilp does not check X7 if landing pad label is zero.63 if (Label == 0)64 return false;65 66 bool Changed = false;67 for (MachineBasicBlock &MBB : MF)68 for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {69 if (MI.getOpcode() != RISCV::PseudoBRINDNonX7 &&70 MI.getOpcode() != RISCV::PseudoCALLIndirectNonX7 &&71 MI.getOpcode() != RISCV::PseudoTAILIndirectNonX7)72 continue;73 BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(RISCV::LUI), RISCV::X7)74 .addImm(Label);75 MachineInstrBuilder(MF, &MI).addUse(RISCV::X7, RegState::ImplicitKill);76 Changed = true;77 }78 79 return Changed;80}81 82INITIALIZE_PASS(RISCVLandingPadSetup, DEBUG_TYPE, PASS_NAME, false, false)83 84char RISCVLandingPadSetup::ID = 0;85 86FunctionPass *llvm::createRISCVLandingPadSetupPass() {87 return new RISCVLandingPadSetup();88}89