Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
213799 views
//===------ RISCVIndirectBranchTracking.cpp - Enables lpad mechanism ------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// The pass adds LPAD (AUIPC with rs1 = X0) machine instructions at the9// beginning of each basic block or function that is referenced by an indirect10// jump/call instruction.11//12//===----------------------------------------------------------------------===//1314#include "RISCV.h"15#include "RISCVInstrInfo.h"16#include "RISCVSubtarget.h"17#include "llvm/ADT/Statistic.h"18#include "llvm/CodeGen/MachineFunctionPass.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/MachineModuleInfo.h"2122#define DEBUG_TYPE "riscv-indrect-branch-tracking"23#define PASS_NAME "RISC-V Indirect Branch Tracking"2425using namespace llvm;2627cl::opt<uint32_t> PreferredLandingPadLabel(28"riscv-landing-pad-label", cl::ReallyHidden,29cl::desc("Use preferred fixed label for all labels"));3031namespace {32class RISCVIndirectBranchTracking : public MachineFunctionPass {33public:34static char ID;35RISCVIndirectBranchTracking() : MachineFunctionPass(ID) {}3637StringRef getPassName() const override { return PASS_NAME; }3839bool runOnMachineFunction(MachineFunction &MF) override;4041private:42const Align LpadAlign = Align(4);43};4445} // end anonymous namespace4647INITIALIZE_PASS(RISCVIndirectBranchTracking, DEBUG_TYPE, PASS_NAME, false,48false)4950char RISCVIndirectBranchTracking::ID = 0;5152FunctionPass *llvm::createRISCVIndirectBranchTrackingPass() {53return new RISCVIndirectBranchTracking();54}5556static void emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII,57uint32_t Label) {58auto I = MBB.begin();59BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(RISCV::AUIPC), RISCV::X0)60.addImm(Label);61}6263bool RISCVIndirectBranchTracking::runOnMachineFunction(MachineFunction &MF) {64const auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();65const RISCVInstrInfo *TII = Subtarget.getInstrInfo();66if (!Subtarget.hasStdExtZicfilp())67return false;6869uint32_t FixedLabel = 0;70if (PreferredLandingPadLabel.getNumOccurrences() > 0) {71if (!isUInt<20>(PreferredLandingPadLabel))72report_fatal_error("riscv-landing-pad-label=<val>, <val> needs to fit in "73"unsigned 20-bits");74FixedLabel = PreferredLandingPadLabel;75}7677bool Changed = false;78for (MachineBasicBlock &MBB : MF) {79if (&MBB == &MF.front()) {80Function &F = MF.getFunction();81// When trap is taken, landing pad is not needed.82if (F.hasFnAttribute("interrupt"))83continue;8485if (F.hasAddressTaken() || !F.hasLocalLinkage()) {86emitLpad(MBB, TII, FixedLabel);87if (MF.getAlignment() < LpadAlign)88MF.setAlignment(LpadAlign);89Changed = true;90}91continue;92}9394if (MBB.hasAddressTaken()) {95emitLpad(MBB, TII, FixedLabel);96if (MBB.getAlignment() < LpadAlign)97MBB.setAlignment(LpadAlign);98Changed = true;99}100}101102return Changed;103}104105106