Skip to content

Commit 17ccb84

Browse files
authored
[llvm] Extract and propagate callee_type metadata
Update MachineFunction::CallSiteInfo to extract numeric CalleeTypeIds from callee_type metadata attached to indirect call instructions. Reviewers: nikic, ilovepi Reviewed By: ilovepi Pull Request: #87575
1 parent 254b90f commit 17ccb84

24 files changed

+520
-2
lines changed

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@
2626
#include "llvm/CodeGen/MachineBasicBlock.h"
2727
#include "llvm/CodeGen/MachineInstr.h"
2828
#include "llvm/CodeGen/MachineMemOperand.h"
29+
#include "llvm/IR/Constants.h"
2930
#include "llvm/IR/EHPersonalities.h"
31+
#include "llvm/IR/Instructions.h"
3032
#include "llvm/Support/Allocator.h"
3133
#include "llvm/Support/ArrayRecycler.h"
3234
#include "llvm/Support/AtomicOrdering.h"
3335
#include "llvm/Support/Compiler.h"
36+
#include "llvm/Support/MD5.h"
3437
#include "llvm/Support/Recycler.h"
3538
#include "llvm/Target/TargetOptions.h"
3639
#include <bitset>
@@ -517,6 +520,32 @@ class LLVM_ABI MachineFunction {
517520
SmallVector<ArgRegPair, 1> ArgRegPairs;
518521
/// Callee type ids.
519522
SmallVector<ConstantInt *, 4> CalleeTypeIds;
523+
524+
CallSiteInfo() = default;
525+
526+
/// Extracts the numeric type id from the CallBase's callee_type Metadata,
527+
/// and sets CalleeTypeIds. This is used as type id for the indirect call in
528+
/// the call graph section.
529+
CallSiteInfo(const CallBase &CB) {
530+
// Call graph section needs numeric callee_type id only for indirect
531+
// calls.
532+
if (!CB.isIndirectCall())
533+
return;
534+
535+
MDNode *CalleeTypeList = CB.getMetadata(LLVMContext::MD_callee_type);
536+
if (!CalleeTypeList)
537+
return;
538+
539+
for (const MDOperand &Op : CalleeTypeList->operands()) {
540+
MDNode *TypeMD = cast<MDNode>(Op);
541+
MDString *TypeIdStr = cast<MDString>(TypeMD->getOperand(1));
542+
// Compute numeric type id from generalized type id string
543+
uint64_t TypeIdVal = MD5Hash(TypeIdStr->getString());
544+
IntegerType *Int64Ty = Type::getInt64Ty(CB.getContext());
545+
CalleeTypeIds.push_back(
546+
ConstantInt::get(Int64Ty, TypeIdVal, /*IsSigned=*/false));
547+
}
548+
}
520549
};
521550

522551
struct CalledGlobalInfo {

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,8 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
888888
}
889889

890890
if (MI->isCandidateForAdditionalCallInfo()) {
891-
if (DAG->getTarget().Options.EmitCallSiteInfo)
891+
if (DAG->getTarget().Options.EmitCallSiteInfo ||
892+
DAG->getTarget().Options.EmitCallGraphSection)
892893
MF.addCallSiteInfo(MI, DAG->getCallSiteInfo(Node));
893894

894895
if (auto CalledGlobal = DAG->getCalledGlobal(Node))

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8952,6 +8952,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
89528952
bool &IsTailCall = CLI.IsTailCall;
89538953
CallingConv::ID &CallConv = CLI.CallConv;
89548954
bool IsVarArg = CLI.IsVarArg;
8955+
const CallBase *CB = CLI.CB;
89558956

89568957
MachineFunction &MF = DAG.getMachineFunction();
89578958
MachineFunction::CallSiteInfo CSInfo;
@@ -8991,6 +8992,10 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
89918992
*DAG.getContext());
89928993
RetCCInfo.AnalyzeCallResult(Ins, RetCC);
89938994

8995+
// Set type id for call site info.
8996+
if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
8997+
CSInfo = MachineFunction::CallSiteInfo(*CB);
8998+
89948999
// Check callee args/returns for SVE registers and set calling convention
89959000
// accordingly.
89969001
if (CallConv == CallingConv::C || CallConv == CallingConv::Fast) {

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,6 +2423,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
24232423
CallingConv::ID CallConv = CLI.CallConv;
24242424
bool doesNotRet = CLI.DoesNotReturn;
24252425
bool isVarArg = CLI.IsVarArg;
2426+
const CallBase *CB = CLI.CB;
24262427

24272428
MachineFunction &MF = DAG.getMachineFunction();
24282429
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
@@ -2446,6 +2447,10 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
24462447
!Subtarget->noBTIAtReturnTwice())
24472448
GuardWithBTI = AFI->branchTargetEnforcement();
24482449

2450+
// Set type id for call site info.
2451+
if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
2452+
CSInfo = MachineFunction::CallSiteInfo(*CB);
2453+
24492454
// Determine whether this is a non-secure function call.
24502455
if (CLI.CB && CLI.CB->getAttributes().hasFnAttr("cmse_nonsecure_call"))
24512456
isCmseNSCall = true;

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3341,6 +3341,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
33413341
bool &IsTailCall = CLI.IsTailCall;
33423342
CallingConv::ID CallConv = CLI.CallConv;
33433343
bool IsVarArg = CLI.IsVarArg;
3344+
const CallBase *CB = CLI.CB;
33443345

33453346
MachineFunction &MF = DAG.getMachineFunction();
33463347
MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -3397,8 +3398,11 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
33973398
// Get a count of how many bytes are to be pushed on the stack.
33983399
unsigned StackSize = CCInfo.getStackSize();
33993400

3400-
// Call site info for function parameters tracking.
3401+
// Call site info for function parameters tracking and call base type info.
34013402
MachineFunction::CallSiteInfo CSInfo;
3403+
// Set type id for call site info.
3404+
if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
3405+
CSInfo = MachineFunction::CallSiteInfo(*CB);
34023406

34033407
// Check if it's really possible to do a tail call. Restrict it to functions
34043408
// that are part of this compilation unit.

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22725,8 +22725,14 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
2272522725
bool IsVarArg = CLI.IsVarArg;
2272622726
EVT PtrVT = getPointerTy(DAG.getDataLayout());
2272722727
MVT XLenVT = Subtarget.getXLenVT();
22728+
const CallBase *CB = CLI.CB;
2272822729

2272922730
MachineFunction &MF = DAG.getMachineFunction();
22731+
MachineFunction::CallSiteInfo CSInfo;
22732+
22733+
// Set type id for call site info.
22734+
if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
22735+
CSInfo = MachineFunction::CallSiteInfo(*CB);
2273022736

2273122737
// Analyze the operands of the call, assigning locations to each operand.
2273222738
SmallVector<CCValAssign, 16> ArgLocs;
@@ -22984,13 +22990,20 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
2298422990
if (CLI.CFIType)
2298522991
Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
2298622992
DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
22993+
if (MF.getTarget().Options.EmitCallGraphSection && CB &&
22994+
CB->isIndirectCall())
22995+
DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
2298722996
return Ret;
2298822997
}
2298922998

2299022999
unsigned CallOpc = NeedSWGuarded ? RISCVISD::SW_GUARDED_CALL : RISCVISD::CALL;
2299123000
Chain = DAG.getNode(CallOpc, DL, NodeTys, Ops);
2299223001
if (CLI.CFIType)
2299323002
Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
23003+
23004+
if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
23005+
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
23006+
2299423007
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
2299523008
Glue = Chain.getValue(1);
2299623009

llvm/lib/Target/X86/X86FastISel.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,6 +3673,12 @@ bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
36733673
CLI.NumResultRegs = RVLocs.size();
36743674
CLI.Call = MIB;
36753675

3676+
// Add call site info for call graph section.
3677+
if (TM.Options.EmitCallGraphSection && CB && CB->isIndirectCall()) {
3678+
MachineFunction::CallSiteInfo CSInfo(*CB);
3679+
MF->addCallSiteInfo(CLI.Call, std::move(CSInfo));
3680+
}
3681+
36763682
return true;
36773683
}
36783684

@@ -4042,6 +4048,8 @@ bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
40424048
MO.setReg(IndexReg);
40434049
}
40444050

4051+
if (MI->isCall())
4052+
FuncInfo.MF->moveAdditionalCallInfo(MI, Result);
40454053
Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
40464054
Result->cloneInstrSymbols(*FuncInfo.MF, *MI);
40474055
MachineBasicBlock::iterator I(MI);

llvm/lib/Target/X86/X86ISelLoweringCall.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,10 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
20602060
if (CallConv == CallingConv::X86_INTR)
20612061
report_fatal_error("X86 interrupts may not be called directly");
20622062

2063+
// Set type id for call site info.
2064+
if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())
2065+
CSInfo = MachineFunction::CallSiteInfo(*CB);
2066+
20632067
if (IsIndirectCall && !IsWin64 &&
20642068
M->getModuleFlag("import-call-optimization"))
20652069
errorUnsupported(DAG, dl,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
;; Tests that callee_type metadata attached to direct call sites are safely ignored.
2+
3+
; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
4+
5+
;; Test that `calleeTypeIds` field is not present in `callSites`
6+
; CHECK-LABEL: callSites:
7+
; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] }
8+
; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] }
9+
; CHECK-NEXT: - { bb: {{[0-9]+}}, offset: {{[0-9]+}}, fwdArgRegs: [] }
10+
define i32 @foo(i32 %x, i32 %y) !type !0 {
11+
entry:
12+
;; Call instruction with accurate callee_type.
13+
;; callee_type should be dropped seemlessly.
14+
%call = call i32 @fizz(i32 %x, i32 %y), !callee_type !1
15+
;; Call instruction with mismatched callee_type.
16+
;; callee_type should be dropped seemlessly without errors.
17+
%call1 = call i32 @fizz(i32 %x, i32 %y), !callee_type !3
18+
%add = add nsw i32 %call, %call1
19+
;; Call instruction with mismatched callee_type.
20+
;; callee_type should be dropped seemlessly without errors.
21+
%call2 = call i32 @fizz(i32 %add, i32 %y), !callee_type !3
22+
%sub = sub nsw i32 %add, %call2
23+
ret i32 %sub
24+
}
25+
26+
declare !type !2 i32 @fizz(i32, i32)
27+
28+
!0 = !{i64 0, !"_ZTSFiiiiE.generalized"}
29+
!1 = !{!2}
30+
!2 = !{i64 0, !"_ZTSFiiiE.generalized"}
31+
!3 = !{!4}
32+
!4 = !{i64 0, !"_ZTSFicE.generalized"}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
;; Tests that call site callee type ids can be extracted and set from
2+
;; callee_type metadata for indirect tail calls.
3+
4+
;; Verify the exact calleeTypeId value to ensure it is not garbage but the value
5+
;; computed as the type id from the callee_type metadata.
6+
; RUN: llc --call-graph-section -mtriple aarch64-linux-gnu < %s -stop-after=finalize-isel -o - | FileCheck --match-full-lines %s
7+
8+
define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
9+
entry:
10+
; CHECK: callSites:
11+
; CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
12+
; CHECK-NEXT: [ 3498816979441845844 ] }
13+
%call = tail call i32 %func(i8 signext %x), !callee_type !1
14+
ret i32 %call
15+
}
16+
17+
!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
18+
!1 = !{!2}
19+
!2 = !{i64 0, !"_ZTSFicE.generalized"}

0 commit comments

Comments
 (0)