Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVIndirectBranchTracking.cpp
213799 views
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 rs1 = 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"
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
26
using namespace llvm;
27
28
cl::opt<uint32_t> PreferredLandingPadLabel(
29
"riscv-landing-pad-label", cl::ReallyHidden,
30
cl::desc("Use preferred fixed label for all labels"));
31
32
namespace {
33
class RISCVIndirectBranchTracking : public MachineFunctionPass {
34
public:
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
42
private:
43
const Align LpadAlign = Align(4);
44
};
45
46
} // end anonymous namespace
47
48
INITIALIZE_PASS(RISCVIndirectBranchTracking, DEBUG_TYPE, PASS_NAME, false,
49
false)
50
51
char RISCVIndirectBranchTracking::ID = 0;
52
53
FunctionPass *llvm::createRISCVIndirectBranchTrackingPass() {
54
return new RISCVIndirectBranchTracking();
55
}
56
57
static 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
64
bool 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
106