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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

50

51using namespace llvm;

52

53#define DEBUG_TYPE "hexagon-peephole"

54

57 cl::desc("Disable Peephole Optimization"));

58

60 cl::desc("Disable Optimization of PNotP"));

61

64 cl::desc("Disable Optimization of Sign/Zero Extends"));

65

69 cl::desc("Disable Optimization of extensions to i64."));

70

71namespace {

76

77 public:

78 static char ID;

80

81 bool runOnMachineFunction(MachineFunction &MF) override;

82

83 StringRef getPassName() const override {

84 return "Hexagon optimize redundant zero and size extends";

85 }

86

87 void getAnalysisUsage(AnalysisUsage &AU) const override {

89 }

90 };

91}

92

93char HexagonPeephole::ID = 0;

94

95INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",

96 false, false)

97

99 if (skipFunction(MF.getFunction()))

100 return false;

101

102 QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());

104 MRI = &MF.getRegInfo();

105

107 DenseMap<unsigned, std::pair<unsigned, unsigned> > PeepholeDoubleRegsMap;

108

110

111

113 PeepholeMap.clear();

114 PeepholeDoubleRegsMap.clear();

115

116

118

119

121 assert(MI.getNumOperands() == 2);

124 Register DstReg = Dst.getReg();

125 Register SrcReg = Src.getReg();

126

128

129

130

131 PeepholeMap[DstReg] = SrcReg;

132 }

133 }

134

135

136

138 assert(MI.getNumOperands() == 3);

142 if (Src1.getImm() != 0)

143 continue;

144 Register DstReg = Dst.getReg();

146 PeepholeMap[DstReg] = SrcReg;

147 }

148

149

150

151

152

153

154 if (MI.getOpcode() == Hexagon::S2_lsr_i_p) {

155 assert(MI.getNumOperands() == 3);

159 if (Src2.getImm() != 32)

160 continue;

161 Register DstReg = Dst.getReg();

163 PeepholeDoubleRegsMap[DstReg] =

164 std::make_pair(*&SrcReg, Hexagon::isub_hi);

165 }

166

167

168 if (DisablePNotP && MI.getOpcode() == Hexagon::C2_not) {

169 assert(MI.getNumOperands() == 2);

172 Register DstReg = Dst.getReg();

173 Register SrcReg = Src.getReg();

174

176

177

178

179 PeepholeMap[DstReg] = SrcReg;

180 }

181 }

182

183

184

186 assert(MI.getNumOperands() == 2);

189

190

191 if (Src.getSubReg() != Hexagon::isub_lo)

192 continue;

193

194 Register DstReg = Dst.getReg();

195 Register SrcReg = Src.getReg();

197

198 if (unsigned PeepholeSrc = PeepholeMap.lookup(SrcReg)) {

199

200 MI.removeOperand(1);

202 } else {

204 PeepholeDoubleRegsMap.find(SrcReg);

205 if (DI != PeepholeDoubleRegsMap.end()) {

206 std::pair<unsigned,unsigned> PeepholeSrc = DI->second;

207 MI.removeOperand(1);

209 PeepholeSrc.first, false , false ,

210 false , false , false ,

211 false , PeepholeSrc.second));

212 }

213 }

214 }

215 }

216

217

219 bool Done = false;

220 if (QII->isPredicated(MI)) {

224 if (RC0->getID() == Hexagon::PredRegsRegClassID) {

225

226

228

229 if (unsigned PeepholeSrc = PeepholeMap.lookup(Reg0)) {

230

231 MI.getOperand(0).setReg(PeepholeSrc);

232 MRI->clearKillFlags(PeepholeSrc);

233 int NewOp = QII->getInvertedPredicatedOpcode(MI.getOpcode());

234 MI.setDesc(QII->get(NewOp));

236 }

237 }

238 }

239 }

240

242

243 unsigned Op = MI.getOpcode();

244 unsigned NewOp = 0;

245 unsigned PR = 1, S1 = 2, S2 = 3;

246

247 switch (Op) {

248 case Hexagon::C2_mux:

249 case Hexagon::C2_muxii:

250 NewOp = Op;

251 break;

252 case Hexagon::C2_muxri:

253 NewOp = Hexagon::C2_muxir;

254 break;

255 case Hexagon::C2_muxir:

256 NewOp = Hexagon::C2_muxri;

257 break;

258 }

259 if (NewOp) {

260 Register PSrc = MI.getOperand(PR).getReg();

261 if (unsigned POrig = PeepholeMap.lookup(PSrc)) {

262 BuildMI(MBB, MI.getIterator(), MI.getDebugLoc(), QII->get(NewOp),

263 MI.getOperand(0).getReg())

265 .add(MI.getOperand(S2))

267 MRI->clearKillFlags(POrig);

268 MI.eraseFromParent();

269 }

270 }

271 }

272

273 }

274

275 }

276 }

277 return true;

278}

279

281 return new HexagonPeephole();

282}

unsigned const MachineRegisterInfo * MRI

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

This file defines the DenseMap class.

static cl::opt< bool > DisableOptExtTo64("disable-hexagon-opt-ext-to-64", cl::Hidden, cl::init(true), cl::desc("Disable Optimization of extensions to i64."))

static cl::opt< bool > DisableHexagonPeephole("disable-hexagon-peephole", cl::Hidden, cl::desc("Disable Peephole Optimization"))

static cl::opt< bool > DisablePNotP("disable-hexagon-pnotp", cl::Hidden, cl::desc("Disable Optimization of PNotP"))

static cl::opt< bool > DisableOptSZExt("disable-hexagon-optszext", cl::Hidden, cl::init(true), cl::desc("Disable Optimization of Sign/Zero Extends"))

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

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

const HexagonRegisterInfo * getRegisterInfo() const override

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 & add(const MachineOperand &MO) const

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

Add a new virtual register operand.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

Register getReg() const

getReg - Returns the register number.

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 isVirtual() const

Return true if the specified register number is in the virtual register namespace.

unsigned getID() const

Return the register class ID number.

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.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

FunctionPass * createHexagonPeephole()

Definition HexagonPeephole.cpp:280

DWARFExpression::Operation Op