LLVM 24.0.0git
RISCVIndirectBranchTracking.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// The pass adds LPAD (AUIPC with rd = X0) machine instructions at the
10// beginning of each basic block or function that is referenced by an indirect
11// jump/call instruction.
12//
13//===----------------------------------------------------------------------===//
14
15#include "RISCV.h"
16#include "RISCVInstrInfo.h"
18#include "RISCVSubtarget.h"
19#include "llvm/ADT/Statistic.h"
26#include "llvm/IR/Analysis.h"
27#include "llvm/Pass.h"
28
29#define DEBUG_TYPE "riscv-indirect-branch-tracking"
30#define PASS_NAME "RISC-V Indirect Branch Tracking"
31
32using namespace llvm;
33
34namespace {
35class RISCVIndirectBranchTrackingLegacy : public MachineFunctionPass {
36public:
37 static char ID;
38 RISCVIndirectBranchTrackingLegacy() : MachineFunctionPass(ID) {}
39
40 StringRef getPassName() const override { return PASS_NAME; }
41
42 void getAnalysisUsage(AnalysisUsage &AU) const override {
43 AU.setPreservesCFG();
45 }
46
47 bool runOnMachineFunction(MachineFunction &MF) override;
48};
49
50} // end anonymous namespace
51
52INITIALIZE_PASS(RISCVIndirectBranchTrackingLegacy, DEBUG_TYPE, PASS_NAME, false,
53 false)
54
55char RISCVIndirectBranchTrackingLegacy::ID = 0;
56
58 return new RISCVIndirectBranchTrackingLegacy();
59}
60
61static void
64 if (!I.isValid())
65 I = MBB.begin();
66 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(RISCV::AUIPC), RISCV::X0)
67 .addImm(Label);
68}
69
71 const auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
72 const RISCVInstrInfo *TII = Subtarget.getInstrInfo();
73 const Align LpadAlign = Align(4);
74
76 return false;
77
78 uint32_t FixedLabel = 0;
79 if (std::optional<uint32_t> Label = Subtarget.getCLOpts().landing_pad_label) {
80 if (!isUInt<20>(*Label))
81 report_fatal_error("riscv-landing-pad-label=<val>, <val> needs to fit in "
82 "unsigned 20-bits");
83 FixedLabel = *Label;
84 }
85
86 bool Changed = false;
87 for (MachineBasicBlock &MBB : MF) {
88 if (&MBB == &MF.front()) {
89 Function &F = MF.getFunction();
90 // When trap is taken, landing pad is not needed.
91 if (F.hasFnAttribute("interrupt"))
92 continue;
93
94 if (F.hasAddressTaken() || !F.hasLocalLinkage()) {
95 emitLpad(MBB, TII, FixedLabel);
96 if (MF.getAlignment() < LpadAlign)
97 MF.setAlignment(LpadAlign);
98 Changed = true;
99 }
100 continue;
101 }
102
103 if (MBB.hasAddressTaken()) {
104 emitLpad(MBB, TII, FixedLabel);
105 if (MBB.getAlignment() < LpadAlign)
106 MBB.setAlignment(LpadAlign);
107 Changed = true;
108 }
109 }
110
111 return Changed;
112}
113
114bool RISCVIndirectBranchTrackingLegacy::runOnMachineFunction(
115 MachineFunction &MF) {
116 return runIndirectBranchTracking(MF);
117}
118
119PreservedAnalyses
MachineBasicBlock & MBB
#define DEBUG_TYPE
const HexagonInstrInfo * TII
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static bool runIndirectBranchTracking(MachineFunction &MF)
static void emitLpad(MachineBasicBlock &MBB, const RISCVInstrInfo *TII, uint32_t Label, MachineBasicBlock::iterator I=MachineBasicBlock::iterator{})
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define PASS_NAME
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:280
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void setAlignment(Align A)
setAlignment - Set the alignment of the function.
Align getAlignment() const
getAlignment - Return the alignment of the function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Pass manager infrastructure for declaring and invalidating analyses.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
FunctionPass * createRISCVIndirectBranchTrackingLegacyPass()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39