@@ -134,6 +134,7 @@ static cl::opt<bool>
134
134
" optimisations and transformations have run." ));
135
135
136
136
extern bool YkAllocLLVMBBAddrMapSection;
137
+ extern bool YkExtendedLLVMBBAddrMapSection;
137
138
138
139
const char DWARFGroupName[] = " dwarf" ;
139
140
const char DWARFGroupDescription[] = " DWARF Emission" ;
@@ -1438,141 +1439,147 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
1438
1439
emitLabelDifferenceAsULEB128 (MBB.getEndSymbol (), MBBSymbol);
1439
1440
OutStreamer->emitULEB128IntValue (getBBAddrMapMetadata (MBB));
1440
1441
PrevMBBEndSymbol = MBB.getEndSymbol ();
1441
- // Find BBs corresponding with this MBB as described above.
1442
- const BasicBlock *CorrBB = MBB.getBasicBlock ();
1443
- std::vector<const BasicBlock *> CorrBBs;
1444
- while (CorrBB != nullptr ) {
1445
- CorrBBs.push_back (CorrBB);
1446
- const Instruction *Term = CorrBB->getTerminator ();
1447
- assert (Term != nullptr );
1448
- if ((isa<BranchInst>(Term)) &&
1449
- (!(dyn_cast<const BranchInst>(Term))->isConditional ())) {
1450
- CorrBB = CorrBB->getUniqueSuccessor ();
1451
- assert (CorrBB != nullptr );
1452
- if (MergedBBs.count (CorrBB) == 0 ) {
1442
+
1443
+ if (YkExtendedLLVMBBAddrMapSection) {
1444
+ // Find BBs corresponding with this MBB as described above.
1445
+ const BasicBlock *CorrBB = MBB.getBasicBlock ();
1446
+ std::vector<const BasicBlock *> CorrBBs;
1447
+ while (CorrBB != nullptr ) {
1448
+ CorrBBs.push_back (CorrBB);
1449
+ const Instruction *Term = CorrBB->getTerminator ();
1450
+ assert (Term != nullptr );
1451
+ if ((isa<BranchInst>(Term)) &&
1452
+ (!(dyn_cast<const BranchInst>(Term))->isConditional ())) {
1453
+ CorrBB = CorrBB->getUniqueSuccessor ();
1454
+ assert (CorrBB != nullptr );
1455
+ if (MergedBBs.count (CorrBB) == 0 ) {
1456
+ CorrBB = nullptr ;
1457
+ }
1458
+ } else {
1453
1459
CorrBB = nullptr ;
1454
1460
}
1455
- } else {
1456
- CorrBB = nullptr ;
1457
1461
}
1458
- }
1459
- // Emit the number of corresponding BasicBlocks.
1460
- OutStreamer->emitULEB128IntValue (CorrBBs.size ());
1461
- // Emit the corresponding block indices.
1462
- for (auto CorrBB : CorrBBs) {
1463
- size_t I = 0 ;
1464
- bool Found = false ;
1465
- for (auto It = F.begin (); It != F.end (); It++) {
1466
- const BasicBlock *BB = &*It;
1467
- if (BB == CorrBB) {
1468
- Found = true ;
1469
- break ;
1462
+ // Emit the number of corresponding BasicBlocks.
1463
+ OutStreamer->emitULEB128IntValue (CorrBBs.size ());
1464
+ // Emit the corresponding block indices.
1465
+ for (auto CorrBB : CorrBBs) {
1466
+ size_t I = 0 ;
1467
+ bool Found = false ;
1468
+ for (auto It = F.begin (); It != F.end (); It++) {
1469
+ const BasicBlock *BB = &*It;
1470
+ if (BB == CorrBB) {
1471
+ Found = true ;
1472
+ break ;
1473
+ }
1474
+ I++;
1470
1475
}
1471
- I++;
1476
+ if (!Found)
1477
+ OutContext.reportError (SMLoc (), " Couldn't find the block's index" );
1478
+ OutStreamer->emitULEB128IntValue (I);
1472
1479
}
1473
- if (!Found)
1474
- OutContext.reportError (SMLoc (), " Couldn't find the block's index" );
1475
- OutStreamer->emitULEB128IntValue (I);
1476
- }
1477
1480
1478
- // Emit call marker table for the Yk JIT.
1479
- //
1480
- // The table is a size header, followed by call instruction addresses.
1481
- //
1482
- // YKOPT: to save space, instead of using absolute symbol addresses, compute
1483
- // the distance from the start of the block and use uleb128 encoding.
1484
- const size_t NumCalls = YkCallMarkerSyms[&MBB].size ();
1485
- OutStreamer->emitULEB128IntValue (NumCalls);
1486
- for (auto Tup : YkCallMarkerSyms[&MBB]) {
1487
- // Emit address of the call instruction.
1488
- OutStreamer->emitSymbolValue (std::get<0 >(Tup), getPointerSize ());
1489
- // Emit address of target if known, or 0.
1490
- MCSymbol *Target = std::get<1 >(Tup);
1491
- if (Target)
1492
- OutStreamer->emitSymbolValue (Target, getPointerSize ());
1493
- else
1494
- OutStreamer->emitIntValue (0 , getPointerSize ());
1495
- }
1481
+ // Emit call marker table for the Yk JIT.
1482
+ //
1483
+ // The table is a size header, followed by call instruction addresses.
1484
+ //
1485
+ // YKOPT: to save space, instead of using absolute symbol addresses,
1486
+ // compute the distance from the start of the block and use uleb128
1487
+ // encoding.
1488
+ const size_t NumCalls = YkCallMarkerSyms[&MBB].size ();
1489
+ OutStreamer->emitULEB128IntValue (NumCalls);
1490
+ for (auto Tup : YkCallMarkerSyms[&MBB]) {
1491
+ // Emit address of the call instruction.
1492
+ OutStreamer->emitSymbolValue (std::get<0 >(Tup), getPointerSize ());
1493
+ // Emit address of target if known, or 0.
1494
+ MCSymbol *Target = std::get<1 >(Tup);
1495
+ if (Target)
1496
+ OutStreamer->emitSymbolValue (Target, getPointerSize ());
1497
+ else
1498
+ OutStreamer->emitIntValue (0 , getPointerSize ());
1499
+ }
1496
1500
1497
- // Emit successor information.
1498
- //
1499
- // Each codegenned block gets a record indicating any statically known
1500
- // successors. The record starts with a `SuccessorKind` byte:
1501
- enum SuccessorKind {
1502
- // One successor.
1503
- Unconditional = 0 ,
1504
- // Choice of two successors.
1505
- Conditional = 1 ,
1506
- // A control flow edge known only at runtime, e.g. a return or an indirect
1507
- // branch.
1508
- Dynamic = 2 ,
1509
- };
1510
-
1511
- // Then depending of the `SuccessorKind` there is a payload describing the
1512
- // successors:
1513
- //
1514
- // `Unconditional`: [target-address: u64]
1515
- // `Conditional`: [taken-address: u64, not-taken-address: u64]
1516
- // `Dynamic`: [] (i.e. nothing, because nothing is statically known)
1517
-
1518
- MachineBasicBlock *TBB = nullptr , *FBB = nullptr ;
1519
- SmallVector<MachineOperand> Conds;
1520
-
1521
- if (!TI->analyzeBranch (const_cast <MachineBasicBlock &>(MBB), TBB, FBB,
1522
- Conds)) {
1523
- // The block ends with a branch or a fall-thru.
1524
- if (!TBB && !FBB) {
1525
- // Both null: block has no terminator and either falls through or
1526
- // diverges.
1527
- OutStreamer->emitInt8 (Unconditional);
1528
- MachineBasicBlock *ThruBB = findFallthruBlock (&MBB);
1529
- if (ThruBB) {
1530
- OutStreamer->emitSymbolValue (BBSym (ThruBB, FunctionSymbol),
1531
- getPointerSize ());
1532
- } else {
1533
- OutStreamer->emitInt64 (0 ); // Divergent.
1534
- }
1535
- } else if (TBB && !FBB) {
1536
- // Only FBB null: block either ends with an unconditional branch or a
1537
- // conditional branch whose false arm falls through or diverges.
1538
- if (Conds.empty ()) {
1539
- // No conditions: unconditional branch.
1501
+ // Emit successor information.
1502
+ //
1503
+ // Each codegenned block gets a record indicating any statically known
1504
+ // successors. The record starts with a `SuccessorKind` byte:
1505
+ enum SuccessorKind {
1506
+ // One successor.
1507
+ Unconditional = 0 ,
1508
+ // Choice of two successors.
1509
+ Conditional = 1 ,
1510
+ // A control flow edge known only at runtime, e.g. a return or an
1511
+ // indirect
1512
+ // branch.
1513
+ Dynamic = 2 ,
1514
+ };
1515
+
1516
+ // Then depending of the `SuccessorKind` there is a payload describing the
1517
+ // successors:
1518
+ //
1519
+ // `Unconditional`: [target-address: u64]
1520
+ // `Conditional`: [taken-address: u64, not-taken-address: u64]
1521
+ // `Dynamic`: [] (i.e. nothing, because nothing is statically known)
1522
+
1523
+ MachineBasicBlock *TBB = nullptr , *FBB = nullptr ;
1524
+ SmallVector<MachineOperand> Conds;
1525
+
1526
+ if (!TI->analyzeBranch (const_cast <MachineBasicBlock &>(MBB), TBB, FBB,
1527
+ Conds)) {
1528
+ // The block ends with a branch or a fall-thru.
1529
+ if (!TBB && !FBB) {
1530
+ // Both null: block has no terminator and either falls through or
1531
+ // diverges.
1540
1532
OutStreamer->emitInt8 (Unconditional);
1541
- OutStreamer->emitSymbolValue (BBSym (TBB, FunctionSymbol),
1542
- getPointerSize ());
1543
- } else {
1544
- // Has conditions: conditional branch followed by fallthru or
1545
- // divergence.
1546
1533
MachineBasicBlock *ThruBB = findFallthruBlock (&MBB);
1547
- OutStreamer->emitInt8 (Conditional);
1548
- OutStreamer->emitSymbolValue (BBSym (TBB, FunctionSymbol),
1549
- getPointerSize ());
1550
1534
if (ThruBB) {
1551
1535
OutStreamer->emitSymbolValue (BBSym (ThruBB, FunctionSymbol),
1552
1536
getPointerSize ());
1553
1537
} else {
1554
1538
OutStreamer->emitInt64 (0 ); // Divergent.
1555
1539
}
1540
+ } else if (TBB && !FBB) {
1541
+ // Only FBB null: block either ends with an unconditional branch or a
1542
+ // conditional branch whose false arm falls through or diverges.
1543
+ if (Conds.empty ()) {
1544
+ // No conditions: unconditional branch.
1545
+ OutStreamer->emitInt8 (Unconditional);
1546
+ OutStreamer->emitSymbolValue (BBSym (TBB, FunctionSymbol),
1547
+ getPointerSize ());
1548
+ } else {
1549
+ // Has conditions: conditional branch followed by fallthru or
1550
+ // divergence.
1551
+ MachineBasicBlock *ThruBB = findFallthruBlock (&MBB);
1552
+ OutStreamer->emitInt8 (Conditional);
1553
+ OutStreamer->emitSymbolValue (BBSym (TBB, FunctionSymbol),
1554
+ getPointerSize ());
1555
+ if (ThruBB) {
1556
+ OutStreamer->emitSymbolValue (BBSym (ThruBB, FunctionSymbol),
1557
+ getPointerSize ());
1558
+ } else {
1559
+ OutStreamer->emitInt64 (0 ); // Divergent.
1560
+ }
1561
+ }
1562
+ } else {
1563
+ // Conditional branch followed by an unconditional branch.
1564
+ assert (TBB && FBB);
1565
+ OutStreamer->emitInt8 (Conditional);
1566
+ OutStreamer->emitSymbolValue (BBSym (TBB, FunctionSymbol),
1567
+ getPointerSize ());
1568
+ OutStreamer->emitSymbolValue (BBSym (FBB, FunctionSymbol),
1569
+ getPointerSize ());
1556
1570
}
1557
1571
} else {
1558
- // Conditional branch followed by an unconditional branch.
1559
- assert (TBB && FBB);
1560
- OutStreamer->emitInt8 (Conditional);
1561
- OutStreamer->emitSymbolValue (BBSym (TBB, FunctionSymbol),
1562
- getPointerSize ());
1563
- OutStreamer->emitSymbolValue (BBSym (FBB, FunctionSymbol),
1564
- getPointerSize ());
1565
- }
1566
- } else {
1567
- // Wasn't a branch or a fall-thru. Must be a different kind of terminator.
1568
- const MachineInstr *LastI = &*MBB.instr_rbegin ();
1569
- if (LastI->isReturn () || LastI->isIndirectBranch ()) {
1570
- OutStreamer->emitInt8 (Dynamic);
1571
- } else {
1572
- std::string Msg = " unhandled block terminator in block: " ;
1573
- raw_string_ostream OS (Msg);
1574
- LastI->print (OS);
1575
- OutContext.reportError (SMLoc (), Msg);
1572
+ // Wasn't a branch or a fall-thru. Must be a different kind of
1573
+ // terminator.
1574
+ const MachineInstr *LastI = &*MBB.instr_rbegin ();
1575
+ if (LastI->isReturn () || LastI->isIndirectBranch ()) {
1576
+ OutStreamer->emitInt8 (Dynamic);
1577
+ } else {
1578
+ std::string Msg = " unhandled block terminator in block: " ;
1579
+ raw_string_ostream OS (Msg);
1580
+ LastI->print (OS);
1581
+ OutContext.reportError (SMLoc (), Msg);
1582
+ }
1576
1583
}
1577
1584
}
1578
1585
}
@@ -1697,7 +1704,8 @@ void AsmPrinter::emitFunctionBody() {
1697
1704
// Print a label for the basic block.
1698
1705
emitBasicBlockStart (MBB);
1699
1706
1700
- YkCallMarkerSyms.insert ({&MBB, {}});
1707
+ if (YkExtendedLLVMBBAddrMapSection)
1708
+ YkCallMarkerSyms.insert ({&MBB, {}});
1701
1709
1702
1710
DenseMap<StringRef, unsigned > MnemonicCounts;
1703
1711
for (auto &MI : MBB) {
@@ -1774,7 +1782,7 @@ void AsmPrinter::emitFunctionBody() {
1774
1782
break ;
1775
1783
default :
1776
1784
1777
- if (YkAllocLLVMBBAddrMapSection && MI.isCall () &&
1785
+ if (YkExtendedLLVMBBAddrMapSection && MI.isCall () &&
1778
1786
(MI.getOpcode () != TargetOpcode::STACKMAP) &&
1779
1787
(MI.getOpcode () != TargetOpcode::PATCHPOINT) &&
1780
1788
(MI.getOpcode () != TargetOpcode::STATEPOINT)) {
0 commit comments