Skip to content

Commit eac56f7

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 eac56f7

File tree

1 file changed

+326
-8
lines changed

1 file changed

+326
-8
lines changed

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 326 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,98 @@ 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+
324+
bool isLDRS(const MCInst &Inst) const {
325+
return (Inst.getOpcode() == AArch64::LDRSui ||
326+
Inst.getOpcode() == AArch64::LDRSroW ||
327+
Inst.getOpcode() == AArch64::LDRSroX ||
328+
Inst.getOpcode() == AArch64::LDURSi ||
329+
Inst.getOpcode() == AArch64::LDPSi ||
330+
Inst.getOpcode() == AArch64::LDNPSi ||
331+
Inst.getOpcode() == AArch64::LDRSpre ||
332+
Inst.getOpcode() == AArch64::LDRSpost ||
333+
Inst.getOpcode() == AArch64::LDPSpost ||
334+
Inst.getOpcode() == AArch64::LDPSpre);
335+
}
336+
337+
bool isLDRD(const MCInst &Inst) const {
338+
return (Inst.getOpcode() == AArch64::LDRDui ||
339+
Inst.getOpcode() == AArch64::LDRDpre ||
340+
Inst.getOpcode() == AArch64::LDRDpost ||
341+
Inst.getOpcode() == AArch64::LDRDroW ||
342+
Inst.getOpcode() == AArch64::LDRDroX ||
343+
Inst.getOpcode() == AArch64::LDURDi ||
344+
Inst.getOpcode() == AArch64::LDPDi ||
345+
Inst.getOpcode() == AArch64::LDNPDi ||
346+
Inst.getOpcode() == AArch64::LDPDpost ||
347+
Inst.getOpcode() == AArch64::LDPDpre);
348+
}
349+
350+
bool isLDRQ(const MCInst &Inst) const {
351+
return (Inst.getOpcode() == AArch64::LDRQui ||
352+
Inst.getOpcode() == AArch64::LDRQpre ||
353+
Inst.getOpcode() == AArch64::LDRQpost ||
354+
Inst.getOpcode() == AArch64::LDRQroW ||
355+
Inst.getOpcode() == AArch64::LDRQroX ||
356+
Inst.getOpcode() == AArch64::LDURQi ||
357+
Inst.getOpcode() == AArch64::LDPQi ||
358+
Inst.getOpcode() == AArch64::LDNPQi ||
359+
Inst.getOpcode() == AArch64::LDPQpost ||
360+
Inst.getOpcode() == AArch64::LDPQpre);
266361
}
267362

268363
bool mayLoad(const MCInst &Inst) const override {
269-
return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst);
364+
return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst) ||
365+
isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst);
270366
}
271367

272368
bool isAArch64ExclusiveLoad(const MCInst &Inst) const override {
@@ -1140,7 +1236,229 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
11401236
Inst.addOperand(MCOperand::createImm(0));
11411237
}
11421238

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

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

0 commit comments

Comments
 (0)