LLVM: lib/Target/X86/X86SpeculativeExecutionSideEffectSuppression.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

26using namespace llvm;

27

28#define DEBUG_TYPE "x86-seses"

29

30STATISTIC(NumLFENCEsInserted, "Number of lfence instructions inserted");

31

33 "x86-seses-enable-without-lvi-cfi",

34 cl::desc("Force enable speculative execution side effect suppression. "

35 "(Note: User must pass -mlvi-cfi in order to mitigate indirect "

36 "branches and returns.)"),

38

40 "x86-seses-one-lfence-per-bb",

42 "Omit all lfences other than the first to be placed in a basic block."),

44

46 "x86-seses-only-lfence-non-const",

47 cl::desc("Only lfence before groups of terminators where at least one "

48 "branch instruction has an input to the addressing mode that is a "

49 "register other than %rip."),

51

54 cl::desc("Omit all lfences before branch instructions."),

56

57namespace {

58

59class X86SpeculativeExecutionSideEffectSuppression

61public:

63

64 static char ID;

65 StringRef getPassName() const override {

66 return "X86 Speculative Execution Side Effect Suppression";

67 }

68

69 bool runOnMachineFunction(MachineFunction &MF) override;

70};

71}

72

73char X86SpeculativeExecutionSideEffectSuppression::ID = 0;

74

75

76

77

78

79

80

83 if (MO.isReg() && X86::RIP != MO.getReg())

84 return false;

85 return true;

86}

87

88bool X86SpeculativeExecutionSideEffectSuppression::runOnMachineFunction(

90

92 const X86Subtarget &Subtarget = MF.getSubtarget();

93

94

95

96

98 !(Subtarget.useLVILoadHardening() && OptLevel == CodeGenOptLevel::None) &&

99 !Subtarget.useSpeculativeExecutionSideEffectSuppression())

100 return false;

101

103 << " **********\n");

106 for (MachineBasicBlock &MBB : MF) {

107 MachineInstr *FirstTerminator = nullptr;

108

109

110 bool PrevInstIsLFENCE = false;

111 for (auto &MI : MBB) {

112

113 if (MI.getOpcode() == X86::LFENCE) {

114 PrevInstIsLFENCE = true;

115 continue;

116 }

117

118

119

120

121

122 if (MI.mayLoadOrStore() && MI.isTerminator()) {

123 if (!PrevInstIsLFENCE) {

125 NumLFENCEsInserted++;

127 }

129 break;

130 }

131

132

133

134

135

136

137

138

139

140

141

142

143

144 if (MI.isTerminator() && FirstTerminator == nullptr)

145 FirstTerminator = &MI;

146

147

148

150

151 PrevInstIsLFENCE = false;

152 continue;

153 }

154

156

157

158 PrevInstIsLFENCE = false;

159 continue;

160 }

161

162

163 if (!PrevInstIsLFENCE) {

164 assert(FirstTerminator && "Unknown terminator instruction");

166 NumLFENCEsInserted++;

168 }

169 break;

170 }

171 }

172

174}

175

177 return new X86SpeculativeExecutionSideEffectSuppression();

178}

179

180INITIALIZE_PASS(X86SpeculativeExecutionSideEffectSuppression, "x86-seses",

181 "X86 Speculative Execution Side Effect Suppression", false,

182 false)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const HexagonInstrInfo * TII

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

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static cl::opt< bool > OmitBranchLFENCEs("x86-seses-omit-branch-lfences", cl::desc("Omit all lfences before branch instructions."), cl::init(false), cl::Hidden)

static cl::opt< bool > OnlyLFENCENonConst("x86-seses-only-lfence-non-const", cl::desc("Only lfence before groups of terminators where at least one " "branch instruction has an input to the addressing mode that is a " "register other than %rip."), cl::init(false), cl::Hidden)

static cl::opt< bool > OneLFENCEPerBasicBlock("x86-seses-one-lfence-per-bb", cl::desc("Omit all lfences other than the first to be placed in a basic block."), cl::init(false), cl::Hidden)

static cl::opt< bool > EnableSpeculativeExecutionSideEffectSuppression("x86-seses-enable-without-lvi-cfi", cl::desc("Force enable speculative execution side effect suppression. " "(Note: User must pass -mlvi-cfi in order to mitigate indirect " "branches and returns.)"), cl::init(false), cl::Hidden)

static bool hasConstantAddressingMode(const MachineInstr &MI)

Definition X86SpeculativeExecutionSideEffectSuppression.cpp:81

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

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

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.

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

CodeGenOptLevel getOptLevel() const

Returns the optimization level: None, Less, Default, or Aggressive.

const X86InstrInfo * getInstrInfo() const override

unsigned ID

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

initializer< Ty > init(const Ty &Val)

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.

FunctionPass * createX86SpeculativeExecutionSideEffectSuppression()

Definition X86SpeculativeExecutionSideEffectSuppression.cpp:176

LLVM_ABI raw_ostream & dbgs()

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