mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
Minor extension to llvm.experimental.patchpoint: don't require a call.
If a null call target is provided, don't emit a dummy call. This allows the runtime to reserve as little nop space as it needs without the requirement of emitting a call. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194676 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
27df434c5e
commit
72cf01cc7c
@ -6826,7 +6826,7 @@ void SelectionDAGBuilder::visitStackmap(const CallInst &CI) {
|
||||
/// \brief Lower llvm.experimental.patchpoint directly to its target opcode.
|
||||
void SelectionDAGBuilder::visitPatchpoint(const CallInst &CI) {
|
||||
// void|i64 @llvm.experimental.patchpoint.void|i64(i32 <id>,
|
||||
// i32 <numNopBytes>,
|
||||
// i32 <numBytes>,
|
||||
// i8* <target>,
|
||||
// i32 <numArgs>,
|
||||
// [Args...],
|
||||
|
@ -765,6 +765,8 @@ static void LowerSTACKMAP(MCStreamer &OutStreamer,
|
||||
OutStreamer.EmitInstruction(MCInstBuilder(X86::NOOP));
|
||||
}
|
||||
|
||||
// Lower a patchpoint of the form:
|
||||
// [<def>], <id>, <numBytes>, <target>, <numArgs>
|
||||
static void LowerPATCHPOINT(MCStreamer &OutStreamer,
|
||||
X86MCInstLower &MCInstLowering,
|
||||
StackMaps &SM,
|
||||
@ -813,17 +815,20 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer,
|
||||
getStackMapEndMOP(MI.operands_begin(), MI.operands_end()),
|
||||
isAnyRegCC && hasDef);
|
||||
|
||||
// Emit MOV to materialize the target address and the CALL to target.
|
||||
// This is encoded with 12-13 bytes, depending on which register is used.
|
||||
// We conservatively assume that it is 12 bytes and emit in worst case one
|
||||
// extra NOP byte.
|
||||
unsigned EncodedBytes = 12;
|
||||
OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64ri)
|
||||
.addReg(MI.getOperand(ScratchIdx).getReg())
|
||||
.addImm(MI.getOperand(StartIdx + 2).getImm()));
|
||||
OutStreamer.EmitInstruction(MCInstBuilder(X86::CALL64r)
|
||||
.addReg(MI.getOperand(ScratchIdx).getReg()));
|
||||
|
||||
unsigned EncodedBytes = 0;
|
||||
int64_t CallTarget = MI.getOperand(StartIdx + 2).getImm();
|
||||
if (CallTarget) {
|
||||
// Emit MOV to materialize the target address and the CALL to target.
|
||||
// This is encoded with 12-13 bytes, depending on which register is used.
|
||||
// We conservatively assume that it is 12 bytes and emit in worst case one
|
||||
// extra NOP byte.
|
||||
EncodedBytes = 12;
|
||||
OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64ri)
|
||||
.addReg(MI.getOperand(ScratchIdx).getReg())
|
||||
.addImm(CallTarget));
|
||||
OutStreamer.EmitInstruction(MCInstBuilder(X86::CALL64r)
|
||||
.addReg(MI.getOperand(ScratchIdx).getReg()));
|
||||
}
|
||||
// Emit padding.
|
||||
unsigned NumNOPBytes = MI.getOperand(StartIdx + 1).getImm();
|
||||
assert(NumNOPBytes >= EncodedBytes &&
|
||||
|
@ -79,6 +79,22 @@ entry:
|
||||
ret i64 10
|
||||
}
|
||||
|
||||
; Test small patchpoints that don't emit calls.
|
||||
define void @small_patchpoint_codegen(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
|
||||
entry:
|
||||
; CHECK-LABEL: small_patchpoint_codegen:
|
||||
; CHECK: Ltmp
|
||||
; CHECK: nop
|
||||
; CHECK-NEXT: nop
|
||||
; CHECK-NEXT: nop
|
||||
; CHECK-NEXT: nop
|
||||
; CHECK-NEXT: nop
|
||||
; CHECK-NEXT: popq
|
||||
; CHECK-NEXT: ret
|
||||
%result = tail call i64 (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i32 5, i32 5, i8* null, i32 2, i64 %p1, i64 %p2)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.experimental.stackmap(i32, i32, ...)
|
||||
declare void @llvm.experimental.patchpoint.void(i32, i32, i8*, i32, ...)
|
||||
declare i64 @llvm.experimental.patchpoint.i64(i32, i32, i8*, i32, ...)
|
||||
|
Loading…
x
Reference in New Issue
Block a user