Skip to content

Commit 5f7810f

Browse files
committed
blockmap: Split apart return edges from other dynamic edges.
This is required for dealing with compressed returns in the ykpt decoder.
1 parent ccaa673 commit 5f7810f

File tree

4 files changed

+58
-5
lines changed

4 files changed

+58
-5
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,16 @@ class TargetInstrInfo : public MCInstrInfo {
14441444
return false;
14451445
}
14461446

1447+
/// Returns true if MI is a far call.
1448+
///
1449+
/// YKFIXME: x86 only.
1450+
virtual bool isFarCall(const MachineInstr &MI) const { return false; }
1451+
1452+
/// Returns true if MI is a far return.
1453+
///
1454+
/// YKFIXME: x86 only.
1455+
virtual bool isFarRet(const MachineInstr &MI) const { return false; }
1456+
14471457
/// Returns true if the tail call can be made conditional on BranchCond.
14481458
virtual bool canMakeTailCallConditional(SmallVectorImpl<MachineOperand> &Cond,
14491459
const MachineInstr &TailCall) const {

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,18 +1508,20 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
15081508
Unconditional = 0,
15091509
// Choice of two successors.
15101510
Conditional = 1,
1511-
// A control flow edge known only at runtime, e.g. a return or an
1512-
// indirect
1511+
// A return edge.
1512+
Return = 2,
1513+
// Any other control flow edge known only at runtime, e.g. an indirect
15131514
// branch.
1514-
Dynamic = 2,
1515+
Dynamic = 3,
15151516
};
15161517

15171518
// Then depending of the `SuccessorKind` there is a payload describing the
15181519
// successors:
15191520
//
15201521
// `Unconditional`: [target-address: u64]
15211522
// `Conditional`: [taken-address: u64, not-taken-address: u64]
1522-
// `Dynamic`: [] (i.e. nothing, because nothing is statically known)
1523+
// `Return`: []
1524+
// `Dynamic`: []
15231525

15241526
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
15251527
SmallVector<MachineOperand> Conds;
@@ -1573,7 +1575,12 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
15731575
// Wasn't a branch or a fall-thru. Must be a different kind of
15741576
// terminator.
15751577
const MachineInstr *LastI = &*MBB.instr_rbegin();
1576-
if (LastI->isReturn() || LastI->isIndirectBranch()) {
1578+
if (LastI->isReturn()) {
1579+
// Ensure we are only working with near returns. See comment
1580+
// elsewhere about far calls for reasoning.
1581+
assert(!MF.getSubtarget().getInstrInfo()->isFarRet(*LastI));
1582+
OutStreamer->emitInt8(Return);
1583+
} else if (LastI->isIndirectBranch()) {
15771584
OutStreamer->emitInt8(Dynamic);
15781585
} else {
15791586
std::string Msg = "unhandled block terminator in block: ";
@@ -1799,6 +1806,13 @@ void AsmPrinter::emitFunctionBody() {
17991806
// Statically known function address.
18001807
CallTargetSym = getSymbol(CallOpnd.getGlobal());
18011808
}
1809+
1810+
// Ensure we are only working with near calls. This matters because
1811+
// Intel PT optimises near calls, and it simplifies our implementation
1812+
// if we can disregard far calls. Far calls are a hangover from
1813+
// 16-bit X86 that we are unlikley to encounter anyway.
1814+
assert(!MF->getSubtarget().getInstrInfo()->isFarCall(MI));
1815+
18021816
assert(YkCallMarkerSyms.find(&MBB) != YkCallMarkerSyms.end());
18031817
YkCallMarkerSyms[&MBB].push_back({YkPreCallSym, CallTargetSym});
18041818
}

llvm/lib/Target/X86/X86InstrInfo.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2913,6 +2913,33 @@ bool X86InstrInfo::isUnconditionalTailCall(const MachineInstr &MI) const {
29132913
}
29142914
}
29152915

2916+
bool X86InstrInfo::isFarCall(const MachineInstr &MI) const {
2917+
switch (MI.getOpcode()) {
2918+
case X86::FARCALL16i:
2919+
case X86::FARCALL16m:
2920+
case X86::FARCALL32i:
2921+
case X86::FARCALL32m:
2922+
case X86::FARCALL64m:
2923+
return true;
2924+
default:
2925+
return false;
2926+
}
2927+
}
2928+
2929+
bool X86InstrInfo::isFarRet(const MachineInstr &MI) const {
2930+
switch (MI.getOpcode()) {
2931+
case X86::LRET16:
2932+
case X86::LRET32:
2933+
case X86::LRET64:
2934+
case X86::LRETI16:
2935+
case X86::LRETI32:
2936+
case X86::LRETI64:
2937+
return true;
2938+
default:
2939+
return false;
2940+
}
2941+
}
2942+
29162943
bool X86InstrInfo::canMakeTailCallConditional(
29172944
SmallVectorImpl<MachineOperand> &BranchCond,
29182945
const MachineInstr &TailCall) const {

llvm/lib/Target/X86/X86InstrInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ class X86InstrInfo final : public X86GenInstrInfo {
316316

317317
// Branch analysis.
318318
bool isUnconditionalTailCall(const MachineInstr &MI) const override;
319+
bool isFarCall(const MachineInstr &MI) const override;
320+
bool isFarRet(const MachineInstr &MI) const override;
319321
bool canMakeTailCallConditional(SmallVectorImpl<MachineOperand> &Cond,
320322
const MachineInstr &TailCall) const override;
321323
void replaceBranchWithTailCall(MachineBasicBlock &MBB,

0 commit comments

Comments
 (0)