Skip to content

Commit cfdd5e0

Browse files
committed
[BOLT][Aarch64] Add isPush & isPop checking
This functionality is needed for inliner pass and also for correct dyno stats.
1 parent 59c7d6f commit cfdd5e0

File tree

1 file changed

+325
-8
lines changed

1 file changed

+325
-8
lines changed

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 325 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
133133
public:
134134
using MCPlusBuilder::MCPlusBuilder;
135135

136+
bool isPush(const MCInst &Inst) const override {
137+
return isStoreToStack(Inst);
138+
};
139+
140+
bool isPop(const MCInst &Inst) const override {
141+
return isLoadFromStack(Inst);
142+
};
143+
136144
bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
137145
CompFuncTy Comp) const override {
138146
const auto &AArch64ExprA = cast<AArch64MCExpr>(A);
@@ -214,11 +222,16 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
214222
}
215223

216224
bool isLDRB(const MCInst &Inst) const {
217-
return (Inst.getOpcode() == AArch64::LDRBBpost ||
225+
return (Inst.getOpcode() == AArch64::LDRBpost ||
226+
Inst.getOpcode() == AArch64::LDRBBpost ||
218227
Inst.getOpcode() == AArch64::LDRBBpre ||
219228
Inst.getOpcode() == AArch64::LDRBBroW ||
229+
Inst.getOpcode() == AArch64::LDRBroW ||
230+
Inst.getOpcode() == AArch64::LDRBroX ||
220231
Inst.getOpcode() == AArch64::LDRBBroX ||
221232
Inst.getOpcode() == AArch64::LDRBBui ||
233+
Inst.getOpcode() == AArch64::LDRBui ||
234+
Inst.getOpcode() == AArch64::LDRBpre ||
222235
Inst.getOpcode() == AArch64::LDRSBWpost ||
223236
Inst.getOpcode() == AArch64::LDRSBWpre ||
224237
Inst.getOpcode() == AArch64::LDRSBWroW ||
@@ -228,15 +241,27 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
228241
Inst.getOpcode() == AArch64::LDRSBXpre ||
229242
Inst.getOpcode() == AArch64::LDRSBXroW ||
230243
Inst.getOpcode() == AArch64::LDRSBXroX ||
231-
Inst.getOpcode() == AArch64::LDRSBXui);
244+
Inst.getOpcode() == AArch64::LDRSBXui ||
245+
Inst.getOpcode() == AArch64::LDURBi ||
246+
Inst.getOpcode() == AArch64::LDURBBi ||
247+
Inst.getOpcode() == AArch64::LDURSBWi ||
248+
Inst.getOpcode() == AArch64::LDURSBXi ||
249+
Inst.getOpcode() == AArch64::LDTRBi ||
250+
Inst.getOpcode() == AArch64::LDTRSBWi ||
251+
Inst.getOpcode() == AArch64::LDTRSBXi);
232252
}
233253

234254
bool isLDRH(const MCInst &Inst) const {
235-
return (Inst.getOpcode() == AArch64::LDRHHpost ||
255+
return (Inst.getOpcode() == AArch64::LDRHpost ||
256+
Inst.getOpcode() == AArch64::LDRHHpost ||
236257
Inst.getOpcode() == AArch64::LDRHHpre ||
258+
Inst.getOpcode() == AArch64::LDRHroW ||
237259
Inst.getOpcode() == AArch64::LDRHHroW ||
260+
Inst.getOpcode() == AArch64::LDRHroX ||
238261
Inst.getOpcode() == AArch64::LDRHHroX ||
239262
Inst.getOpcode() == AArch64::LDRHHui ||
263+
Inst.getOpcode() == AArch64::LDRHui ||
264+
Inst.getOpcode() == AArch64::LDRHpre ||
240265
Inst.getOpcode() == AArch64::LDRSHWpost ||
241266
Inst.getOpcode() == AArch64::LDRSHWpre ||
242267
Inst.getOpcode() == AArch64::LDRSHWroW ||
@@ -246,27 +271,97 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
246271
Inst.getOpcode() == AArch64::LDRSHXpre ||
247272
Inst.getOpcode() == AArch64::LDRSHXroW ||
248273
Inst.getOpcode() == AArch64::LDRSHXroX ||
249-
Inst.getOpcode() == AArch64::LDRSHXui);
274+
Inst.getOpcode() == AArch64::LDRSHXui ||
275+
Inst.getOpcode() == AArch64::LDURHi ||
276+
Inst.getOpcode() == AArch64::LDURHHi ||
277+
Inst.getOpcode() == AArch64::LDURSHWi ||
278+
Inst.getOpcode() == AArch64::LDURSHXi ||
279+
Inst.getOpcode() == AArch64::LDTRHi ||
280+
Inst.getOpcode() == AArch64::LDTRSHWi ||
281+
Inst.getOpcode() == AArch64::LDTRSHXi);
250282
}
251283

252284
bool isLDRW(const MCInst &Inst) const {
253285
return (Inst.getOpcode() == AArch64::LDRWpost ||
254286
Inst.getOpcode() == AArch64::LDRWpre ||
255287
Inst.getOpcode() == AArch64::LDRWroW ||
256288
Inst.getOpcode() == AArch64::LDRWroX ||
257-
Inst.getOpcode() == AArch64::LDRWui);
289+
Inst.getOpcode() == AArch64::LDRWui ||
290+
Inst.getOpcode() == AArch64::LDURWi ||
291+
Inst.getOpcode() == AArch64::LDRSWpost ||
292+
Inst.getOpcode() == AArch64::LDRSWpre ||
293+
Inst.getOpcode() == AArch64::LDRSWroW ||
294+
Inst.getOpcode() == AArch64::LDRSWroX ||
295+
Inst.getOpcode() == AArch64::LDRSWui ||
296+
Inst.getOpcode() == AArch64::LDURSWi ||
297+
Inst.getOpcode() == AArch64::LDTRWi ||
298+
Inst.getOpcode() == AArch64::LDTRSWi ||
299+
Inst.getOpcode() == AArch64::LDPWi ||
300+
Inst.getOpcode() == AArch64::LDPWpost ||
301+
Inst.getOpcode() == AArch64::LDPWpre ||
302+
Inst.getOpcode() == AArch64::LDPSWi ||
303+
Inst.getOpcode() == AArch64::LDPSWpost ||
304+
Inst.getOpcode() == AArch64::LDPSWpre ||
305+
Inst.getOpcode() == AArch64::LDNPWi);
258306
}
259307

260308
bool isLDRX(const MCInst &Inst) const {
261309
return (Inst.getOpcode() == AArch64::LDRXpost ||
262310
Inst.getOpcode() == AArch64::LDRXpre ||
263311
Inst.getOpcode() == AArch64::LDRXroW ||
264312
Inst.getOpcode() == AArch64::LDRXroX ||
265-
Inst.getOpcode() == AArch64::LDRXui);
313+
Inst.getOpcode() == AArch64::LDRXui ||
314+
Inst.getOpcode() == AArch64::LDURXi ||
315+
Inst.getOpcode() == AArch64::LDTRXi ||
316+
Inst.getOpcode() == AArch64::LDNPXi ||
317+
Inst.getOpcode() == AArch64::LDPXi ||
318+
Inst.getOpcode() == AArch64::LDPXpost ||
319+
Inst.getOpcode() == AArch64::LDPXpre ||
320+
Inst.getOpcode() == AArch64::LDNPXi);
321+
}
322+
323+
bool isLDRS(const MCInst &Inst) const {
324+
return (Inst.getOpcode() == AArch64::LDRSui ||
325+
Inst.getOpcode() == AArch64::LDRSroW ||
326+
Inst.getOpcode() == AArch64::LDRSroX ||
327+
Inst.getOpcode() == AArch64::LDURSi ||
328+
Inst.getOpcode() == AArch64::LDPSi ||
329+
Inst.getOpcode() == AArch64::LDNPSi ||
330+
Inst.getOpcode() == AArch64::LDRSpre ||
331+
Inst.getOpcode() == AArch64::LDRSpost ||
332+
Inst.getOpcode() == AArch64::LDPSpost ||
333+
Inst.getOpcode() == AArch64::LDPSpre);
334+
}
335+
336+
bool isLDRD(const MCInst &Inst) const {
337+
return (Inst.getOpcode() == AArch64::LDRDui ||
338+
Inst.getOpcode() == AArch64::LDRDpre ||
339+
Inst.getOpcode() == AArch64::LDRDpost ||
340+
Inst.getOpcode() == AArch64::LDRDroW ||
341+
Inst.getOpcode() == AArch64::LDRDroX ||
342+
Inst.getOpcode() == AArch64::LDURDi ||
343+
Inst.getOpcode() == AArch64::LDPDi ||
344+
Inst.getOpcode() == AArch64::LDNPDi ||
345+
Inst.getOpcode() == AArch64::LDPDpost ||
346+
Inst.getOpcode() == AArch64::LDPDpre);
347+
}
348+
349+
bool isLDRQ(const MCInst &Inst) const {
350+
return (Inst.getOpcode() == AArch64::LDRQui ||
351+
Inst.getOpcode() == AArch64::LDRQpre ||
352+
Inst.getOpcode() == AArch64::LDRQpost ||
353+
Inst.getOpcode() == AArch64::LDRQroW ||
354+
Inst.getOpcode() == AArch64::LDRQroX ||
355+
Inst.getOpcode() == AArch64::LDURQi ||
356+
Inst.getOpcode() == AArch64::LDPQi ||
357+
Inst.getOpcode() == AArch64::LDNPQi ||
358+
Inst.getOpcode() == AArch64::LDPQpost ||
359+
Inst.getOpcode() == AArch64::LDPQpre);
266360
}
267361

268362
bool mayLoad(const MCInst &Inst) const override {
269-
return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst);
363+
return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst) ||
364+
isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst);
270365
}
271366

272367
bool isAArch64ExclusiveLoad(const MCInst &Inst) const override {
@@ -1140,7 +1235,229 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
11401235
Inst.addOperand(MCOperand::createImm(0));
11411236
}
11421237

1143-
bool mayStore(const MCInst &Inst) const override { return false; }
1238+
bool isStorePair(const MCInst &Inst) const {
1239+
const unsigned opcode = Inst.getOpcode();
1240+
1241+
auto isStorePairImmOffset = [&]() {
1242+
bool isStorePair = false;
1243+
switch (opcode) {
1244+
case AArch64::STPWi:
1245+
case AArch64::STPXi:
1246+
case AArch64::STPSi:
1247+
case AArch64::STPDi:
1248+
case AArch64::STPQi:
1249+
case AArch64::STNPWi:
1250+
case AArch64::STNPXi:
1251+
case AArch64::STNPSi:
1252+
case AArch64::STNPDi:
1253+
case AArch64::STNPQi:
1254+
isStorePair = true;
1255+
break;
1256+
1257+
default:
1258+
break;
1259+
}
1260+
1261+
return isStorePair;
1262+
};
1263+
1264+
auto isStorePairPostIndex = [&]() {
1265+
bool isStorePair = false;
1266+
switch (opcode) {
1267+
case AArch64::STPWpost:
1268+
case AArch64::STPXpost:
1269+
case AArch64::STPSpost:
1270+
case AArch64::STPDpost:
1271+
case AArch64::STPQpost:
1272+
isStorePair = true;
1273+
break;
1274+
1275+
default:
1276+
break;
1277+
}
1278+
1279+
return isStorePair;
1280+
};
1281+
1282+
auto isStorePairPreIndex = [&]() {
1283+
bool isStorePair = false;
1284+
switch (opcode) {
1285+
case AArch64::STPWpre:
1286+
case AArch64::STPXpre:
1287+
case AArch64::STPSpre:
1288+
case AArch64::STPDpre:
1289+
case AArch64::STPQpre:
1290+
isStorePair = true;
1291+
break;
1292+
1293+
default:
1294+
break;
1295+
}
1296+
1297+
return isStorePair;
1298+
};
1299+
1300+
return isStorePairImmOffset() || isStorePairPostIndex() ||
1301+
isStorePairPreIndex();
1302+
}
1303+
1304+
bool isStoreReg(const MCInst &Inst) const {
1305+
const unsigned opcode = Inst.getOpcode();
1306+
bool isStore = false;
1307+
1308+
auto isStoreRegUnscaleImm = [&]() {
1309+
switch (opcode) {
1310+
case AArch64::STURBi:
1311+
case AArch64::STURBBi:
1312+
case AArch64::STURHi:
1313+
case AArch64::STURHHi:
1314+
case AArch64::STURWi:
1315+
case AArch64::STURXi:
1316+
case AArch64::STURSi:
1317+
case AArch64::STURDi:
1318+
case AArch64::STURQi:
1319+
isStore = true;
1320+
break;
1321+
1322+
default:
1323+
break;
1324+
}
1325+
1326+
return isStore;
1327+
};
1328+
1329+
auto isStoreRegScaledImm = [&]() {
1330+
switch (opcode) {
1331+
case AArch64::STRBui:
1332+
case AArch64::STRBBui:
1333+
case AArch64::STRHui:
1334+
case AArch64::STRHHui:
1335+
case AArch64::STRWui:
1336+
case AArch64::STRXui:
1337+
case AArch64::STRSui:
1338+
case AArch64::STRDui:
1339+
case AArch64::STRQui:
1340+
isStore = true;
1341+
break;
1342+
1343+
default:
1344+
break;
1345+
}
1346+
1347+
return isStore;
1348+
};
1349+
1350+
auto isStoreRegImmPostIndexed = [&]() {
1351+
switch (opcode) {
1352+
case AArch64::STRBpost:
1353+
case AArch64::STRBBpost:
1354+
case AArch64::STRHpost:
1355+
case AArch64::STRHHpost:
1356+
case AArch64::STRWpost:
1357+
case AArch64::STRXpost:
1358+
case AArch64::STRSpost:
1359+
case AArch64::STRDpost:
1360+
case AArch64::STRQpost:
1361+
isStore = true;
1362+
break;
1363+
1364+
default:
1365+
break;
1366+
}
1367+
1368+
return isStore;
1369+
};
1370+
1371+
auto isStoreRegImmPreIndexed = [&]() {
1372+
switch (opcode) {
1373+
case AArch64::STRBpre:
1374+
case AArch64::STRBBpre:
1375+
case AArch64::STRHpre:
1376+
case AArch64::STRHHpre:
1377+
case AArch64::STRWpre:
1378+
case AArch64::STRXpre:
1379+
case AArch64::STRSpre:
1380+
case AArch64::STRDpre:
1381+
case AArch64::STRQpre:
1382+
isStore = true;
1383+
break;
1384+
1385+
default:
1386+
break;
1387+
}
1388+
1389+
return isStore;
1390+
};
1391+
1392+
auto isStoreRegUnscaleUnpriv = [&]() {
1393+
switch (opcode) {
1394+
case AArch64::STTRBi:
1395+
case AArch64::STTRHi:
1396+
case AArch64::STTRWi:
1397+
case AArch64::STTRXi:
1398+
isStore = true;
1399+
break;
1400+
1401+
default:
1402+
break;
1403+
}
1404+
1405+
return isStore;
1406+
};
1407+
1408+
auto isStoreRegTrunc = [&]() {
1409+
switch (opcode) {
1410+
case AArch64::STRBBroW:
1411+
case AArch64::STRBBroX:
1412+
case AArch64::STRBroW:
1413+
case AArch64::STRBroX:
1414+
case AArch64::STRDroW:
1415+
case AArch64::STRDroX:
1416+
case AArch64::STRHHroW:
1417+
case AArch64::STRHHroX:
1418+
case AArch64::STRHroW:
1419+
case AArch64::STRHroX:
1420+
case AArch64::STRQroW:
1421+
case AArch64::STRQroX:
1422+
case AArch64::STRSroW:
1423+
case AArch64::STRSroX:
1424+
case AArch64::STRWroW:
1425+
case AArch64::STRWroX:
1426+
case AArch64::STRXroW:
1427+
case AArch64::STRXroX:
1428+
isStore = true;
1429+
break;
1430+
1431+
default:
1432+
break;
1433+
}
1434+
1435+
return isStore;
1436+
};
1437+
1438+
return isStoreRegUnscaleImm() || isStoreRegScaledImm() ||
1439+
isStoreRegImmPreIndexed() || isStoreRegImmPostIndexed() ||
1440+
isStoreRegUnscaleUnpriv() || isStoreRegTrunc();
1441+
}
1442+
1443+
bool mayStore(const MCInst &Inst) const override {
1444+
return isStorePair(Inst) || isStoreReg(Inst) ||
1445+
isAArch64ExclusiveStore(Inst);
1446+
}
1447+
1448+
bool isStoreToStack(const MCInst &Inst) const {
1449+
if (!mayStore(Inst))
1450+
return false;
1451+
for (const MCOperand &Operand : useOperands(Inst)) {
1452+
if (!Operand.isReg())
1453+
continue;
1454+
unsigned Reg = Operand.getReg();
1455+
if (Reg == AArch64::SP || Reg == AArch64::WSP || Reg == AArch64::FP ||
1456+
Reg == AArch64::W29)
1457+
return true;
1458+
}
1459+
return false;
1460+
}
11441461

11451462
void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx,
11461463
bool IsTailCall) override {

0 commit comments

Comments
 (0)