LLVM: lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

21using namespace llvm;

22

23#define DEBUG_TYPE "riscv-insert-read-write-csr"

24#define RISCV_INSERT_READ_WRITE_CSR_NAME "RISC-V Insert Read/Write CSR Pass"

25

29 cl::desc("Disable optimized frm insertion."));

30

31namespace {

32

35

36public:

37 static char ID;

38

40

41 bool runOnMachineFunction(MachineFunction &MF) override;

42

43 void getAnalysisUsage(AnalysisUsage &AU) const override {

46 }

47

48 StringRef getPassName() const override {

50 }

51

52private:

53 bool emitWriteRoundingMode(MachineBasicBlock &MBB);

54 bool emitWriteRoundingModeOpt(MachineBasicBlock &MBB);

55};

56

57}

58

59char RISCVInsertReadWriteCSR::ID = 0;

60

63

64

70

72 if (MI.getOpcode() == RISCV::SwapFRMImm ||

73 MI.getOpcode() == RISCV::WriteFRMImm) {

74 CurrentRM = MI.getOperand(0).getImm();

76 continue;

77 }

78

79 if (MI.getOpcode() == RISCV::WriteFRM) {

82 continue;

83 }

84

85 if (MI.isCall() || MI.isInlineAsm() ||

86 MI.readsRegister(RISCV::FRM, nullptr)) {

87

93 continue;

94 }

95

96 assert(MI.modifiesRegister(RISCV::FRM, nullptr) &&

97 "Expected that MI could not modify FRM.");

98

100 if (FRMIdx < 0)

101 continue;

102 unsigned InstrRM = MI.getOperand(FRMIdx).getImm();

103

104 LastFRMChanger = &MI;

105

106

108 true));

110

111

112 if (InstrRM == CurrentRM)

113 continue;

114

115 if (!SavedFRM.isValid()) {

116

118 SavedFRM = MRI->createVirtualRegister(&RISCV::GPRRegClass);

119 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::SwapFRMImm), SavedFRM)

121 } else {

122

125 }

126 CurrentRM = InstrRM;

127 }

128

129

130 if (SavedFRM.isValid()) {

131 assert(LastFRMChanger && "Expected valid pointer.");

132 MachineInstrBuilder MIB =

133 BuildMI(*MBB.getParent(), {}, TII->get(RISCV::WriteFRM))

134 .addReg(SavedFRM);

135 MBB.insertAfter(LastFRMChanger, MIB);

136 }

137

139}

140

141

142

145 for (MachineInstr &MI : MBB) {

147 if (FRMIdx < 0)

148 continue;

149

150 unsigned FRMImm = MI.getOperand(FRMIdx).getImm();

151

152

154 continue;

155

157

158

160 Register SavedFRM = MRI->createVirtualRegister(&RISCV::GPRRegClass);

162 SavedFRM)

165 true));

166

167 MachineInstrBuilder MIB =

171 }

173}

174

175bool RISCVInsertReadWriteCSR::runOnMachineFunction(MachineFunction &MF) {

176

177 const RISCVSubtarget &ST = MF.getSubtarget();

178 if (ST.hasVInstructions())

179 return false;

180

181 TII = ST.getInstrInfo();

182

184

185 for (MachineBasicBlock &MBB : MF) {

187 Changed |= emitWriteRoundingMode(MBB);

188 else

189 Changed |= emitWriteRoundingModeOpt(MBB);

190 }

191

193}

194

196 return new RISCVInsertReadWriteCSR();

197}

unsigned const MachineRegisterInfo * MRI

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

const TargetInstrInfo & TII

Promote Memory to Register

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

#define RISCV_INSERT_READ_WRITE_CSR_NAME

Definition RISCVInsertReadWriteCSR.cpp:24

static cl::opt< bool > DisableFRMInsertOpt("riscv-disable-frm-insert-opt", cl::init(false), cl::Hidden, cl::desc("Disable optimized frm insertion."))

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

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.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

iterator insertAfter(iterator I, MachineInstr *MI)

Insert MI into the instruction list after I.

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.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

Representation of each machine instruction.

static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

Wrapper class representing virtual and physical registers.

constexpr bool isValid() const

TargetInstrInfo - Interface to description of machine instruction set.

unsigned ID

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

static int getFRMOpNum(const MCInstrDesc &Desc)

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 * createRISCVInsertReadWriteCSRPass()

Definition RISCVInsertReadWriteCSR.cpp:195