LLVM: lib/Target/Hexagon/HexagonGenMemAbsolute.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

24

25#define DEBUG_TYPE "hexagon-abs"

26

27using namespace llvm;

28

30 "Number of Load instructions converted to absolute-set form");

32 "Number of Store instructions converted to absolute-set form");

33

34namespace {

35

40

41public:

42 static char ID;

44

45 StringRef getPassName() const override {

46 return "Hexagon Generate Load/Store Set Absolute Address Instruction";

47 }

48

49 void getAnalysisUsage(AnalysisUsage &AU) const override {

51 AU.addRequired();

52 AU.addPreserved();

53 }

54

55 bool runOnMachineFunction(MachineFunction &Fn) override;

56

57private:

59 static bool isValidIndexedStore(int &Opcode, int &NewOpcode);

60};

61}

62

63char HexagonGenMemAbsolute::ID = 0;

64

65INITIALIZE_PASS(HexagonGenMemAbsolute, "hexagon-gen-load-absolute",

66 "Hexagon Generate Load/Store Set Absolute Address Instruction",

67 false, false)

68

70 if (skipFunction(Fn.getFunction()))

71 return false;

72

74 MRI = &Fn.getRegInfo();

75 TRI = Fn.getRegInfo().getTargetRegisterInfo();

76

78 getAnalysis().getDomTree();

79

80

82

84 ++MII) {

86 int Opc = MI->getOpcode();

87 if (Opc != Hexagon::CONST32 && Opc != Hexagon::A2_tfrsi)

88 continue;

89

92 continue;

93

94 unsigned DstReg = MO.getReg();

95 if (MRI->use_nodbg_empty(DstReg))

96 continue;

97

99 use_iterator NextUseMI = MRI->use_nodbg_begin(DstReg);

100

102 int NextOpc = NextMI->getOpcode();

103 int NewOpc;

105

106 if (!IsLoad && !isValidIndexedStore(NextOpc, NewOpc))

107 continue;

108

109

110

111

112 unsigned BaseRegPos, ImmPos, RegPos;

113 if (TII->getBaseAndOffsetPosition(*NextMI, BaseRegPos, ImmPos))

114 continue;

115 RegPos = IsLoad ? 0 : 2;

116

117 bool IsGlobal = MI->getOperand(1).isGlobal();

118 if (MI->getOperand(1).isImm() && !IsGlobal)

119 continue;

120

123 bool Scalable;

124 TII->getMemOperandWithOffset(*NextMI, BaseOp, Offset, Scalable, TRI);

125

126

127 if (!BaseOp || !BaseOp->isReg())

128 continue;

129

130 if (Scalable)

131 continue;

132

133 unsigned BaseReg = BaseOp->getReg();

134 if ((DstReg != BaseReg) || (Offset != 0))

135 continue;

136

138

139 if (!MO0.isReg())

140 continue;

141

142 unsigned LoadStoreReg = MO0.getReg();

143

144

145

146 if (LoadStoreReg == BaseReg)

147 continue;

148

149

150

151

152 bool Dominates = true;

153 unsigned Counter = 0;

154 for (use_iterator I = NextUseMI, E = MRI->use_nodbg_end(); I != E; ++I) {

155 Counter++;

156 if (!MDT.dominates(NextMI, I->getParent()))

157 Dominates = false;

158 }

159

160 if ((!Dominates) || (Counter < 3))

161 continue;

162

163

164

166 dbgs() << "Found a pair of instructions for absolute-set "

167 << (IsLoad ? "load" : "store") << "\n";

169 dbgs() << *NextMI;

170 });

173 if (IsLoad) {

174 ++HexagonNumLoadAbsConversions;

176 TII->get(NewOpc), LoadStoreReg)

178 } else {

179 ++HexagonNumStoreAbsConversions;

181 TII->get(NewOpc), DstReg);

182 }

183

185 if (IsGlobal)

188 else

190

191 if (IsLoad)

193 else

195

196 LLVM_DEBUG(dbgs() << "Replaced with " << *MIB << "\n");

197

198 MII = MBB.erase(MI);

199 --MII;

201 }

202 }

203

204 return true;

205}

206

207bool HexagonGenMemAbsolute::isValidIndexedLoad(int &Opc, int &NewOpc) {

208

210 switch (Opc) {

211 case Hexagon::L2_loadrb_io:

212 NewOpc = Hexagon::L4_loadrb_ap;

213 break;

214 case Hexagon::L2_loadrh_io:

215 NewOpc = Hexagon::L4_loadrh_ap;

216 break;

217 case Hexagon::L2_loadri_io:

218 NewOpc = Hexagon::L4_loadri_ap;

219 break;

220 case Hexagon::L2_loadrd_io:

221 NewOpc = Hexagon::L4_loadrd_ap;

222 break;

223 case Hexagon::L2_loadruh_io:

224 NewOpc = Hexagon::L4_loadruh_ap;

225 break;

226 case Hexagon::L2_loadrub_io:

227 NewOpc = Hexagon::L4_loadrub_ap;

228 break;

229 default:

231 }

232

234}

235

236bool HexagonGenMemAbsolute::isValidIndexedStore(int &Opc, int &NewOpc) {

237

239 switch (Opc) {

240 case Hexagon::S2_storerd_io:

241 NewOpc = Hexagon::S4_storerd_ap;

242 break;

243 case Hexagon::S2_storeri_io:

244 NewOpc = Hexagon::S4_storeri_ap;

245 break;

246 case Hexagon::S2_storerh_io:

247 NewOpc = Hexagon::S4_storerh_ap;

248 break;

249 case Hexagon::S2_storerb_io:

250 NewOpc = Hexagon::S4_storerb_ap;

251 break;

252 default:

254 }

255

257}

258

259

260

261

262

264 return new HexagonGenMemAbsolute();

265}

unsigned const MachineRegisterInfo * MRI

for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))

const TargetInstrInfo & TII

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static bool isValidIndexedLoad(const LoadSDNode *LD)

Register const TargetRegisterInfo * TRI

#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)

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

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

const HexagonInstrInfo * getInstrInfo() const override

LLVM_ABI instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

MachineInstrBundleIterator< MachineInstr > iterator

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

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 MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const

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

Add a new virtual register operand.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

void setSubReg(unsigned subReg)

unsigned getSubReg() const

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

unsigned getTargetFlags() const

Register getReg() const

getReg - Returns the register number.

int64_t getOffset() const

Return the offset from the symbol in this operand.

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

defusechain_iterator< true, false, true, true, false > use_nodbg_iterator

use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the specified register,...

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

unsigned ID

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

@ Define

Register definition.

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.

LLVM_ABI raw_ostream & dbgs()

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

FunctionPass * createHexagonGenMemAbsolute()

Definition HexagonGenMemAbsolute.cpp:263