24
24
#include " llvm/ADT/Statistic.h"
25
25
#include " llvm/ADT/StringRef.h"
26
26
#include " llvm/ADT/TinyPtrVector.h"
27
- #include " llvm/Analysis/TargetTransformInfo.h"
28
27
#include " llvm/Analysis/TypeMetadataUtils.h"
29
28
#include " llvm/Analysis/ValueTracking.h"
30
29
#include " llvm/IR/Attributes.h"
@@ -407,15 +406,6 @@ class LowerTypeTestsModule {
407
406
Triple::OSType OS;
408
407
Triple::ObjectFormatType ObjectFormat;
409
408
410
- // Determines which kind of Thumb jump table we generate. If arch is
411
- // either 'arm' or 'thumb' we need to find this out, because
412
- // selectJumpTableArmEncoding may decide to use Thumb in either case.
413
- bool CanUseArmJumpTable = false , CanUseThumbBWJumpTable = false ;
414
-
415
- // The jump table type we ended up deciding on. (Usually the same as
416
- // Arch, except that 'arm' and 'thumb' are often interchangeable.)
417
- Triple::ArchType JumpTableArch = Triple::UnknownArch;
418
-
419
409
IntegerType *Int1Ty = Type::getInt1Ty(M.getContext());
420
410
IntegerType *Int8Ty = Type::getInt8Ty(M.getContext());
421
411
PointerType *Int8PtrTy = Type::getInt8PtrTy(M.getContext());
@@ -491,8 +481,6 @@ class LowerTypeTestsModule {
491
481
492
482
void buildBitSetsFromGlobalVariables (ArrayRef<Metadata *> TypeIds,
493
483
ArrayRef<GlobalTypeMember *> Globals);
494
- Triple::ArchType
495
- selectJumpTableArmEncoding (ArrayRef<GlobalTypeMember *> Functions);
496
484
unsigned getJumpTableEntrySize ();
497
485
Type *getJumpTableEntryType ();
498
486
void createJumpTableEntry (raw_ostream &AsmOS, raw_ostream &ConstraintOS,
@@ -530,16 +518,15 @@ class LowerTypeTestsModule {
530
518
void replaceDirectCalls (Value *Old, Value *New);
531
519
532
520
public:
533
- LowerTypeTestsModule (Module &M, ModuleAnalysisManager &AM,
534
- ModuleSummaryIndex *ExportSummary,
521
+ LowerTypeTestsModule (Module &M, ModuleSummaryIndex *ExportSummary,
535
522
const ModuleSummaryIndex *ImportSummary,
536
523
bool DropTypeTests);
537
524
538
525
bool lower ();
539
526
540
527
// Lower the module using the action and summary passed as command line
541
528
// arguments. For testing purposes only.
542
- static bool runForTesting (Module &M, ModuleAnalysisManager &AM );
529
+ static bool runForTesting (Module &M);
543
530
};
544
531
} // end anonymous namespace
545
532
@@ -1195,36 +1182,31 @@ static const unsigned kX86JumpTableEntrySize = 8;
1195
1182
static const unsigned kX86IBTJumpTableEntrySize = 16 ;
1196
1183
static const unsigned kARMJumpTableEntrySize = 4 ;
1197
1184
static const unsigned kARMBTIJumpTableEntrySize = 8 ;
1198
- static const unsigned kARMv6MJumpTableEntrySize = 16 ;
1199
1185
static const unsigned kRISCVJumpTableEntrySize = 8 ;
1200
1186
1201
1187
unsigned LowerTypeTestsModule::getJumpTableEntrySize () {
1202
- switch (JumpTableArch ) {
1203
- case Triple::x86:
1204
- case Triple::x86_64:
1205
- if (const auto *MD = mdconst::extract_or_null<ConstantInt>(
1188
+ switch (Arch ) {
1189
+ case Triple::x86:
1190
+ case Triple::x86_64:
1191
+ if (const auto *MD = mdconst::extract_or_null<ConstantInt>(
1206
1192
M.getModuleFlag (" cf-protection-branch" )))
1207
- if (MD->getZExtValue ())
1208
- return kX86IBTJumpTableEntrySize ;
1209
- return kX86JumpTableEntrySize ;
1210
- case Triple::arm:
1211
- return kARMJumpTableEntrySize ;
1212
- case Triple::thumb:
1213
- if (CanUseThumbBWJumpTable)
1193
+ if (MD->getZExtValue ())
1194
+ return kX86IBTJumpTableEntrySize ;
1195
+ return kX86JumpTableEntrySize ;
1196
+ case Triple::arm:
1197
+ case Triple::thumb:
1214
1198
return kARMJumpTableEntrySize ;
1215
- else
1216
- return kARMv6MJumpTableEntrySize ;
1217
- case Triple::aarch64:
1218
- if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
1199
+ case Triple::aarch64:
1200
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
1219
1201
M.getModuleFlag (" branch-target-enforcement" )))
1220
- if (BTE->getZExtValue ())
1221
- return kARMBTIJumpTableEntrySize ;
1222
- return kARMJumpTableEntrySize ;
1223
- case Triple::riscv32:
1224
- case Triple::riscv64:
1225
- return kRISCVJumpTableEntrySize ;
1226
- default :
1227
- report_fatal_error (" Unsupported architecture for jump tables" );
1202
+ if (BTE->getZExtValue ())
1203
+ return kARMBTIJumpTableEntrySize ;
1204
+ return kARMJumpTableEntrySize ;
1205
+ case Triple::riscv32:
1206
+ case Triple::riscv64:
1207
+ return kRISCVJumpTableEntrySize ;
1208
+ default :
1209
+ report_fatal_error (" Unsupported architecture for jump tables" );
1228
1210
}
1229
1211
}
1230
1212
@@ -1258,32 +1240,7 @@ void LowerTypeTestsModule::createJumpTableEntry(
1258
1240
AsmOS << " bti c\n " ;
1259
1241
AsmOS << " b $" << ArgIndex << " \n " ;
1260
1242
} else if (JumpTableArch == Triple::thumb) {
1261
- if (!CanUseThumbBWJumpTable) {
1262
- // In Armv6-M, this sequence will generate a branch without corrupting
1263
- // any registers. We use two stack words; in the second, we construct the
1264
- // address we'll pop into pc, and the first is used to save and restore
1265
- // r0 which we use as a temporary register.
1266
- //
1267
- // To support position-independent use cases, the offset of the target
1268
- // function is stored as a relative offset (which will expand into an
1269
- // R_ARM_REL32 relocation in ELF, and presumably the equivalent in other
1270
- // object file types), and added to pc after we load it. (The alternative
1271
- // B.W is automatically pc-relative.)
1272
- //
1273
- // There are five 16-bit Thumb instructions here, so the .balign 4 adds a
1274
- // sixth halfword of padding, and then the offset consumes a further 4
1275
- // bytes, for a total of 16, which is very convenient since entries in
1276
- // this jump table need to have power-of-two size.
1277
- AsmOS << " push {r0,r1}\n "
1278
- << " ldr r0, 1f\n "
1279
- << " 0: add r0, r0, pc\n "
1280
- << " str r0, [sp, #4]\n "
1281
- << " pop {r0,pc}\n "
1282
- << " .balign 4\n "
1283
- << " 1: .word $" << ArgIndex << " - (0b + 4)\n " ;
1284
- } else {
1285
- AsmOS << " b.w $" << ArgIndex << " \n " ;
1286
- }
1243
+ AsmOS << " b.w $" << ArgIndex << " \n " ;
1287
1244
} else if (JumpTableArch == Triple::riscv32 ||
1288
1245
JumpTableArch == Triple::riscv64) {
1289
1246
AsmOS << " tail $" << ArgIndex << " @plt\n " ;
@@ -1395,19 +1352,12 @@ static bool isThumbFunction(Function *F, Triple::ArchType ModuleArch) {
1395
1352
// Each jump table must be either ARM or Thumb as a whole for the bit-test math
1396
1353
// to work. Pick one that matches the majority of members to minimize interop
1397
1354
// veneers inserted by the linker.
1398
- Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding (
1399
- ArrayRef<GlobalTypeMember *> Functions) {
1400
- if (Arch != Triple::arm && Arch != Triple::thumb)
1401
- return Arch;
1402
-
1403
- if (!CanUseThumbBWJumpTable && CanUseArmJumpTable) {
1404
- // In architectures that provide Arm and Thumb-1 but not Thumb-2,
1405
- // we should always prefer the Arm jump table format, because the
1406
- // Thumb-1 one is larger and slower.
1407
- return Triple::arm;
1408
- }
1355
+ static Triple::ArchType
1356
+ selectJumpTableArmEncoding (ArrayRef<GlobalTypeMember *> Functions,
1357
+ Triple::ArchType ModuleArch) {
1358
+ if (ModuleArch != Triple::arm && ModuleArch != Triple::thumb)
1359
+ return ModuleArch;
1409
1360
1410
- // Otherwise, go with majority vote.
1411
1361
unsigned ArmCount = 0 , ThumbCount = 0 ;
1412
1362
for (const auto GTM : Functions) {
1413
1363
if (!GTM->isJumpTableCanonical ()) {
@@ -1418,7 +1368,7 @@ Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding(
1418
1368
}
1419
1369
1420
1370
Function *F = cast<Function>(GTM->getGlobal ());
1421
- ++(isThumbFunction (F, Arch ) ? ThumbCount : ArmCount);
1371
+ ++(isThumbFunction (F, ModuleArch ) ? ThumbCount : ArmCount);
1422
1372
}
1423
1373
1424
1374
return ArmCount > ThumbCount ? Triple::arm : Triple::thumb;
@@ -1431,6 +1381,8 @@ void LowerTypeTestsModule::createJumpTable(
1431
1381
SmallVector<Value *, 16 > AsmArgs;
1432
1382
AsmArgs.reserve (Functions.size () * 2 );
1433
1383
1384
+ Triple::ArchType JumpTableArch = selectJumpTableArmEncoding (Functions, Arch);
1385
+
1434
1386
for (GlobalTypeMember *GTM : Functions)
1435
1387
createJumpTableEntry (AsmOS, ConstraintOS, JumpTableArch, AsmArgs,
1436
1388
cast<Function>(GTM->getGlobal ()));
@@ -1447,11 +1399,9 @@ void LowerTypeTestsModule::createJumpTable(
1447
1399
F->addFnAttr (" target-features" , " -thumb-mode" );
1448
1400
if (JumpTableArch == Triple::thumb) {
1449
1401
F->addFnAttr (" target-features" , " +thumb-mode" );
1450
- if (CanUseThumbBWJumpTable) {
1451
- // Thumb jump table assembly needs Thumb2. The following attribute is
1452
- // added by Clang for -march=armv7.
1453
- F->addFnAttr (" target-cpu" , " cortex-a8" );
1454
- }
1402
+ // Thumb jump table assembly needs Thumb2. The following attribute is added
1403
+ // by Clang for -march=armv7.
1404
+ F->addFnAttr (" target-cpu" , " cortex-a8" );
1455
1405
}
1456
1406
// When -mbranch-protection= is used, the inline asm adds a BTI. Suppress BTI
1457
1407
// for the function to avoid double BTI. This is a no-op without
@@ -1571,10 +1521,6 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
1571
1521
// FIXME: find a better way to represent the jumptable in the IR.
1572
1522
assert (!Functions.empty ());
1573
1523
1574
- // Decide on the jump table encoding, so that we know how big the
1575
- // entries will be.
1576
- JumpTableArch = selectJumpTableArmEncoding (Functions);
1577
-
1578
1524
// Build a simple layout based on the regular layout of jump tables.
1579
1525
DenseMap<GlobalTypeMember *, uint64_t > GlobalLayout;
1580
1526
unsigned EntrySize = getJumpTableEntrySize ();
@@ -1760,31 +1706,18 @@ void LowerTypeTestsModule::buildBitSetsFromDisjointSet(
1760
1706
1761
1707
// / Lower all type tests in this module.
1762
1708
LowerTypeTestsModule::LowerTypeTestsModule (
1763
- Module &M, ModuleAnalysisManager &AM, ModuleSummaryIndex *ExportSummary,
1709
+ Module &M, ModuleSummaryIndex *ExportSummary,
1764
1710
const ModuleSummaryIndex *ImportSummary, bool DropTypeTests)
1765
1711
: M(M), ExportSummary(ExportSummary), ImportSummary(ImportSummary),
1766
1712
DropTypeTests(DropTypeTests || ClDropTypeTests) {
1767
1713
assert (!(ExportSummary && ImportSummary));
1768
1714
Triple TargetTriple (M.getTargetTriple ());
1769
1715
Arch = TargetTriple.getArch ();
1770
- if (Arch == Triple::arm)
1771
- CanUseArmJumpTable = true ;
1772
- if (Arch == Triple::arm || Arch == Triple::thumb) {
1773
- auto &FAM =
1774
- AM.getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
1775
- for (Function &F : M) {
1776
- auto &TTI = FAM.getResult <TargetIRAnalysis>(F);
1777
- if (TTI.hasArmWideBranch (false ))
1778
- CanUseArmJumpTable = true ;
1779
- if (TTI.hasArmWideBranch (true ))
1780
- CanUseThumbBWJumpTable = true ;
1781
- }
1782
- }
1783
1716
OS = TargetTriple.getOS ();
1784
1717
ObjectFormat = TargetTriple.getObjectFormat ();
1785
1718
}
1786
1719
1787
- bool LowerTypeTestsModule::runForTesting (Module &M, ModuleAnalysisManager &AM ) {
1720
+ bool LowerTypeTestsModule::runForTesting (Module &M) {
1788
1721
ModuleSummaryIndex Summary (/* HaveGVs=*/ false );
1789
1722
1790
1723
// Handle the command-line summary arguments. This code is for testing
@@ -1802,8 +1735,7 @@ bool LowerTypeTestsModule::runForTesting(Module &M, ModuleAnalysisManager &AM) {
1802
1735
1803
1736
bool Changed =
1804
1737
LowerTypeTestsModule (
1805
- M, AM,
1806
- ClSummaryAction == PassSummaryAction::Export ? &Summary : nullptr ,
1738
+ M, ClSummaryAction == PassSummaryAction::Export ? &Summary : nullptr ,
1807
1739
ClSummaryAction == PassSummaryAction::Import ? &Summary : nullptr ,
1808
1740
/* DropTypeTests*/ false )
1809
1741
.lower ();
@@ -2366,10 +2298,10 @@ PreservedAnalyses LowerTypeTestsPass::run(Module &M,
2366
2298
ModuleAnalysisManager &AM) {
2367
2299
bool Changed;
2368
2300
if (UseCommandLine)
2369
- Changed = LowerTypeTestsModule::runForTesting (M, AM );
2301
+ Changed = LowerTypeTestsModule::runForTesting (M);
2370
2302
else
2371
2303
Changed =
2372
- LowerTypeTestsModule (M, AM, ExportSummary, ImportSummary, DropTypeTests)
2304
+ LowerTypeTestsModule (M, ExportSummary, ImportSummary, DropTypeTests)
2373
2305
.lower ();
2374
2306
if (!Changed)
2375
2307
return PreservedAnalyses::all ();
0 commit comments