brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 9664ab3 Raw
105 lines · cpp
1//===------ RISCVIndirectBranchTracking.cpp - Enables lpad mechanism ------===//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// The pass adds LPAD (AUIPC with rd = X0) machine instructions at the10// beginning of each basic block or function that is referenced by an indirect11// jump/call instruction.12//13//===----------------------------------------------------------------------===//14 15#include "RISCV.h"16#include "RISCVInstrInfo.h"17#include "RISCVSubtarget.h"18#include "llvm/ADT/Statistic.h"19#include "llvm/CodeGen/MachineFunctionPass.h"20#include "llvm/CodeGen/MachineInstrBuilder.h"21#include "llvm/CodeGen/MachineModuleInfo.h"22 23#define DEBUG_TYPE "riscv-indrect-branch-tracking"24#define PASS_NAME "RISC-V Indirect Branch Tracking"25 26using namespace llvm;27 28cl::opt<uint32_t> PreferredLandingPadLabel(29    "riscv-landing-pad-label", cl::ReallyHidden,30    cl::desc("Use preferred fixed label for all labels"));31 32namespace {33class RISCVIndirectBranchTracking : public MachineFunctionPass {34public:35  static char ID;36  RISCVIndirectBranchTracking() : MachineFunctionPass(ID) {}37 38  StringRef getPassName() const override { return PASS_NAME; }39 40  bool runOnMachineFunction(MachineFunction &MF) override;41 42private:43  const Align LpadAlign = Align(4);44};45 46} // end anonymous namespace47 48INITIALIZE_PASS(RISCVIndirectBranchTracking, DEBUG_TYPE, PASS_NAME, false,49                false)50 51char RISCVIndirectBranchTracking::ID = 0;52 53FunctionPass *llvm::createRISCVIndirectBranchTrackingPass() {54  return new RISCVIndirectBranchTracking();55}56 57static void emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII,58                     uint32_t Label) {59  auto I = MBB.begin();60  BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(RISCV::AUIPC), RISCV::X0)61      .addImm(Label);62}63 64bool RISCVIndirectBranchTracking::runOnMachineFunction(MachineFunction &MF) {65  const auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();66  const RISCVInstrInfo *TII = Subtarget.getInstrInfo();67  if (!Subtarget.hasStdExtZicfilp())68    return false;69 70  uint32_t FixedLabel = 0;71  if (PreferredLandingPadLabel.getNumOccurrences() > 0) {72    if (!isUInt<20>(PreferredLandingPadLabel))73      report_fatal_error("riscv-landing-pad-label=<val>, <val> needs to fit in "74                         "unsigned 20-bits");75    FixedLabel = PreferredLandingPadLabel;76  }77 78  bool Changed = false;79  for (MachineBasicBlock &MBB : MF) {80    if (&MBB == &MF.front()) {81      Function &F = MF.getFunction();82      // When trap is taken, landing pad is not needed.83      if (F.hasFnAttribute("interrupt"))84        continue;85 86      if (F.hasAddressTaken() || !F.hasLocalLinkage()) {87        emitLpad(MBB, TII, FixedLabel);88        if (MF.getAlignment() < LpadAlign)89          MF.setAlignment(LpadAlign);90        Changed = true;91      }92      continue;93    }94 95    if (MBB.hasAddressTaken()) {96      emitLpad(MBB, TII, FixedLabel);97      if (MBB.getAlignment() < LpadAlign)98        MBB.setAlignment(LpadAlign);99      Changed = true;100    }101  }102 103  return Changed;104}105