LLVM: lib/Target/AArch64/AArch64BranchTargets.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

27

28using namespace llvm;

29

30#define DEBUG_TYPE "aarch64-branch-targets"

31#define AARCH64_BRANCH_TARGETS_NAME "AArch64 Branch Targets"

32

33namespace {

34

35enum : unsigned {

36 BTIBase = 32,

37 BTIC = 1u << 1,

38 BTIJ = 1u << 2,

39 BTIMask = BTIC | BTIJ,

40};

41

43public:

44 static char ID;

46 void getAnalysisUsage(AnalysisUsage &AU) const override;

49

50private:

52

54 bool NeedsWinCFI);

55};

56

57}

58

59char AArch64BranchTargets::ID = 0;

60

63

64void AArch64BranchTargets::getAnalysisUsage(AnalysisUsage &AU) const {

65 AU.setPreservesCFG();

67}

68

70 return new AArch64BranchTargets();

71}

72

73bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {

74 if (!MF.getInfo()->branchTargetEnforcement())

75 return false;

76

77 LLVM_DEBUG(dbgs() << "********** AArch64 Branch Targets **********\n"

78 << "********** Function: " << MF.getName() << '\n');

80

81 Subtarget = &MF.getSubtarget();

82

83

84

85

86 SmallPtrSet<MachineBasicBlock *, 8> JumpTableTargets;

88 for (auto &JTE : JTI->getJumpTables())

89 JumpTableTargets.insert_range(JTE.MBBs);

90

91 bool MadeChange = false;

93 for (MachineBasicBlock &MBB : MF) {

94 bool CouldCall = false, CouldJump = false;

95

96

97

98

99

100

101

102

103

104

105

106

107

109 (F.hasAddressTaken() || F.hasLocalLinkage())))

110 CouldCall = true;

111

112

113

115 JumpTableTargets.count(&MBB))

116 CouldJump = true;

117

120 CouldCall = true;

121 else

122 CouldJump = true;

123 }

124 if (CouldCall || CouldJump) {

125 addBTI(MBB, CouldCall, CouldJump, HasWinCFI);

126 MadeChange = true;

127 }

128 }

129

130 return MadeChange;

131}

132

133void AArch64BranchTargets::addBTI(MachineBasicBlock &MBB, bool CouldCall,

134 bool CouldJump, bool HasWinCFI) {

135 LLVM_DEBUG(dbgs() << "Adding BTI " << (CouldJump ? "j" : "")

136 << (CouldCall ? "c" : "") << " to " << MBB.getName()

137 << "\n");

138

139 unsigned HintNum = getBTIHintNum(CouldCall, CouldJump);

141

142

145 }

146

147

149 (MBBI->isMetaInstruction() || MBBI->getOpcode() == AArch64::EMITBKEY);

151 ;

152

153

154

155

156 if (MBBI != MBB.end() && ((HintNum & BTIMask) == BTIC) &&

157 (MBBI->getOpcode() == AArch64::PACIASP ||

158 MBBI->getOpcode() == AArch64::PACIBSP))

159 return;

160

162

163

168

169

170 if (HasWinCFI && MBBI != MBB.end() &&

174 }

175}

#define AARCH64_BRANCH_TARGETS_NAME

Definition AArch64BranchTargets.cpp:31

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

const AArch64InstrInfo * getInstrInfo() const override

Represent the analysis usage information of a pass.

FunctionPass class - This class is used to implement most global optimizations.

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

bool isEHPad() const

Returns true if the block is a landing pad.

bool isIRBlockAddressTaken() const

Test whether this block is the target of an IR BlockAddress.

bool isEHFuncletEntry() const

Returns true if this is the entry block of an EH funclet.

LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)

Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.

bool isMachineBlockAddressTaken() const

Test whether this block is used as something other than the target of a terminator,...

MachineInstrBundleIterator< MachineInstr > iterator

LLVM_ABI StringRef getName() const

Return the name of the corresponding LLVM basic block, or an empty string.

bool isCleanupFuncletEntry() const

Returns true if this is the entry block of a cleanup funclet.

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.

StringRef getName() const

getName - Return the name of the corresponding LLVM 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 MachineJumpTableInfo * getJumpTableInfo() const

getJumpTableInfo - Return the jump table info object for the current function.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

MachineInstr * getInstr() const

If conversion operators fail, use this method to get the MachineInstr explicitly.

StringRef - Represent a constant reference to a string, i.e.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

static unsigned getBTIHintNum(bool CallTarget, bool JumpTarget)

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionPass * createAArch64BranchTargetsPass()