Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -235,13 +235,15 @@ // The table will contain these structs that point to the sled, the function // containing the sled, and what kind of sled (and whether they should always - // be instrumented). + // be instrumented). We also use a version identifier that the runtime can use + // to decide what to do with the sled, depending on the version of the sled. struct XRayFunctionEntry { const MCSymbol *Sled; const MCSymbol *Function; SledKind Kind; bool AlwaysInstrument; const class Function *Fn; + uint8_t Version; void emit(int, MCStreamer *, const MCSymbol *) const; }; @@ -249,8 +251,12 @@ // All the sleds to be emitted. SmallVector Sleds; + // A unique ID used for ELF sections associated with a particular function. + unsigned XRayFnUniqueID = 0; + // Helper function to record a given XRay sled. - void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind); + void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, + uint8_t Version = 0); /// Emit a table with all XRay instrumentation points. void emitXRayTable(); Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2767,10 +2767,13 @@ Out->EmitSymbolValue(Sled, Bytes); Out->EmitSymbolValue(CurrentFnSym, Bytes); auto Kind8 = static_cast(Kind); - Out->EmitBytes(StringRef(reinterpret_cast(&Kind8), 1)); - Out->EmitBytes( + Out->EmitBinaryData(StringRef(reinterpret_cast(&Kind8), 1)); + Out->EmitBinaryData( StringRef(reinterpret_cast(&AlwaysInstrument), 1)); - Out->EmitZeros(2 * Bytes - 2); // Pad the previous two entries + Out->EmitBinaryData(StringRef(reinterpret_cast(&Version), 1)); + auto Padding = (4 * Bytes) - ((2 * Bytes) + 3); + assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size"); + Out->EmitZeros(Padding); } void AsmPrinter::emitXRayTable() { @@ -2782,19 +2785,22 @@ MCSection *InstMap = nullptr; MCSection *FnSledIndex = nullptr; if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) { + auto Associated = dyn_cast(PrevSection->getBeginSymbol()); + assert(Associated != nullptr); + auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER; + std::string GroupName; if (Fn->hasComdat()) { - InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, - Fn->getComdat()->getName()); - FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, - Fn->getComdat()->getName()); - } else { - InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC); - FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC); + Flags |= ELF::SHF_GROUP; + GroupName = Fn->getComdat()->getName(); } + + auto UniqueID = ++XRayFnUniqueID; + InstMap = + OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, Flags, 0, + GroupName, UniqueID, Associated); + FnSledIndex = + OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0, + GroupName, UniqueID, Associated); } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) { InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, SectionKind::getReadOnlyWithRel()); @@ -2804,15 +2810,7 @@ llvm_unreachable("Unsupported target"); } - // Before we switch over, we force a reference to a label inside the - // xray_fn_idx sections. This makes sure that the xray_fn_idx section is kept - // live by the linker if the function is not garbage-collected. Since this - // function is always called just before the function's end, we assume that - // this is happening after the last return instruction. auto WordSizeBytes = MAI->getCodePointerSize(); - MCSymbol *IdxRef = OutContext.createTempSymbol("xray_fn_idx_synth_", true); - OutStreamer->EmitCodeAlignment(16); - OutStreamer->EmitSymbolValue(IdxRef, WordSizeBytes, false); // Now we switch to the instrumentation map section. Because this is done // per-function, we are able to create an index entry that will represent the @@ -2831,15 +2829,14 @@ // pointers. This should work for both 32-bit and 64-bit platforms. OutStreamer->SwitchSection(FnSledIndex); OutStreamer->EmitCodeAlignment(2 * WordSizeBytes); - OutStreamer->EmitLabel(IdxRef); - OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes); - OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes); + OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes, false); + OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes, false); OutStreamer->SwitchSection(PrevSection); Sleds.clear(); } void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, - SledKind Kind) { + SledKind Kind, uint8_t Version) { auto Fn = MI.getParent()->getParent()->getFunction(); auto Attr = Fn->getFnAttribute("function-instrument"); bool LogArgs = Fn->hasFnAttribute("xray-log-args"); @@ -2847,8 +2844,8 @@ Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always"; if (Kind == SledKind::FUNCTION_ENTER && LogArgs) Kind = SledKind::LOG_ARGS_ENTER; - Sleds.emplace_back( - XRayFunctionEntry{ Sled, CurrentFnSym, Kind, AlwaysInstrument, Fn }); + Sleds.emplace_back(XRayFunctionEntry{Sled, CurrentFnSym, Kind, + AlwaysInstrument, Fn, Version}); } uint16_t AsmPrinter::getDwarfVersion() const { Index: lib/Target/X86/X86MCInstLower.cpp =================================================================== --- lib/Target/X86/X86MCInstLower.cpp +++ lib/Target/X86/X86MCInstLower.cpp @@ -1047,20 +1047,20 @@ // We want to emit the following pattern, which follows the x86 calling // convention to prepare for the trampoline call to be patched in. // - // // .p2align 1, ... // .Lxray_event_sled_N: - // jmp +N // jump across the call instruction - // callq __xray_CustomEvent // force relocation to symbol - // - // - // The relative jump needs to jump forward 24 bytes: - // 10 (args) + 5 (nops) + 9 (cleanup) + // jmp +N // jump across the instrumentation sled + // ... // set up arguments in register + // callq __xray_CustomEvent@plt // force dependency to symbol + // ... + // // // After patching, it would look something like: // // nopw (2-byte nop) + // ... // callq __xrayCustomEvent // already lowered + // ... // // --- // First we emit the label and the jump. @@ -1072,49 +1072,57 @@ // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as // an operand (computed as an offset from the jmp instruction). // FIXME: Find another less hacky way do force the relative jump. - OutStreamer->EmitBytes("\xeb\x14"); + OutStreamer->EmitBinaryData("\xeb\x0f"); // The default C calling convention will place two arguments into %rcx and // %rdx -- so we only work with those. - unsigned UsedRegs[] = {X86::RDI, X86::RSI, X86::RAX}; - - // Because we will use %rax, we preserve that across the call. - EmitAndCountInstruction(MCInstBuilder(X86::PUSH64r).addReg(X86::RAX)); - - // Then we put the operands in the %rdi and %rsi registers. + unsigned UsedRegs[] = {X86::RDI, X86::RSI}; + bool UsedMask[] = {false, false}; + + // Then we put the operands in the %rdi and %rsi registers. We spill the + // values in the register before we clobber them, and mark them as used in + // UsedMask. In case the arguments are already in the correct register, we use + // emit nops appropriately sized to keep the sled the same size in every + // situation. for (unsigned I = 0; I < MI.getNumOperands(); ++I) if (auto Op = MCIL.LowerMachineOperand(&MI, MI.getOperand(I))) { - if (Op->isImm()) - EmitAndCountInstruction(MCInstBuilder(X86::MOV64ri) + assert(Op->isReg() && "Only support arguments in registers"); + if (Op->getReg() != UsedRegs[I]) { + UsedMask[I] = true; + EmitAndCountInstruction( + MCInstBuilder(X86::PUSH64r).addReg(UsedRegs[I])); + EmitAndCountInstruction(MCInstBuilder(X86::MOV64rr) .addReg(UsedRegs[I]) - .addImm(Op->getImm())); - else if (Op->isReg()) { - if (Op->getReg() != UsedRegs[I]) - EmitAndCountInstruction(MCInstBuilder(X86::MOV64rr) - .addReg(UsedRegs[I]) - .addReg(Op->getReg())); - else - EmitNops(*OutStreamer, 3, Subtarget->is64Bit(), getSubtargetInfo()); + .addReg(Op->getReg())); + } else { + EmitNops(*OutStreamer, 4, Subtarget->is64Bit(), getSubtargetInfo()); } } // We emit a hard dependency on the __xray_CustomEvent symbol, which is the - // name of the trampoline to be implemented by the XRay runtime. We put this - // explicitly in the %rax register. + // name of the trampoline to be implemented by the XRay runtime. auto TSym = OutContext.getOrCreateSymbol("__xray_CustomEvent"); MachineOperand TOp = MachineOperand::CreateMCSymbol(TSym); - EmitAndCountInstruction(MCInstBuilder(X86::MOV64ri) - .addReg(X86::RAX) - .addOperand(MCIL.LowerSymbolOperand(TOp, TSym))); + if (isPositionIndependent()) + TOp.setTargetFlags(X86II::MO_PLT); // Emit the call instruction. - EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(X86::RAX)); + EmitAndCountInstruction(MCInstBuilder(X86::CALL64pcrel32) + .addOperand(MCIL.LowerSymbolOperand(TOp, TSym))); // Restore caller-saved and used registers. + for (unsigned I = sizeof UsedMask; I-- > 0;) + if (UsedMask[I]) + EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(UsedRegs[I])); + else + EmitNops(*OutStreamer, 1, Subtarget->is64Bit(), getSubtargetInfo()); + OutStreamer->AddComment("xray custom event end."); - EmitAndCountInstruction(MCInstBuilder(X86::POP64r).addReg(X86::RAX)); - recordSled(CurSled, MI, SledKind::CUSTOM_EVENT); + // Record the sled version. Older versions of this sled were spelled + // differently, so we let the runtime handle the different offsets we're + // using. + recordSled(CurSled, MI, SledKind::CUSTOM_EVENT, 1); } void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI, @@ -1125,7 +1133,6 @@ // .Lxray_sled_N: // jmp .tmpN // # 9 bytes worth of noops - // .tmpN // // We need the 9 bytes because at runtime, we'd be patching over the full 11 // bytes with the following pattern: @@ -1136,14 +1143,12 @@ auto CurSled = OutContext.createTempSymbol("xray_sled_", true); OutStreamer->EmitCodeAlignment(2); OutStreamer->EmitLabel(CurSled); - auto Target = OutContext.createTempSymbol(); // Use a two-byte `jmp`. This version of JMP takes an 8-bit relative offset as // an operand (computed as an offset from the jmp instruction). // FIXME: Find another less hacky way do force the relative jump. OutStreamer->EmitBytes("\xeb\x09"); EmitNops(*OutStreamer, 9, Subtarget->is64Bit(), getSubtargetInfo()); - OutStreamer->EmitLabel(Target); recordSled(CurSled, MI, SledKind::FUNCTION_ENTER); } Index: test/CodeGen/AArch64/xray-attribute-instrumentation.ll =================================================================== --- test/CodeGen/AArch64/xray-attribute-instrumentation.ll +++ test/CodeGen/AArch64/xray-attribute-instrumentation.ll @@ -24,9 +24,7 @@ ; CHECK-LABEL: Ltmp1: ; CHECK-NEXT: ret } -; CHECK: .p2align 4 -; CHECK-NEXT: .xword .Lxray_fn_idx_synth_0 -; CHECK-NEXT: .section xray_instr_map,{{.*}} +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start0 ; CHECK: .xword .Lxray_sled_0 ; CHECK: .xword .Lxray_sled_1 Index: test/CodeGen/AArch64/xray-tail-call-sled.ll =================================================================== --- test/CodeGen/AArch64/xray-tail-call-sled.ll +++ test/CodeGen/AArch64/xray-tail-call-sled.ll @@ -27,15 +27,12 @@ ; CHECK-LABEL: .Ltmp1: ; CHECK-NEXT: ret } -; CHECK: .p2align 4 -; CHECK-NEXT: .xword .Lxray_fn_idx_synth_0 -; CHECK-NEXT: .section xray_instr_map,{{.*}} +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start0: ; CHECK: .xword .Lxray_sled_0 ; CHECK: .xword .Lxray_sled_1 ; CHECK-LABEL: Lxray_sleds_end0: -; CHECK: .section xray_fn_idx,{{.*}} -; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK-LABEL: xray_fn_idx ; CHECK: .xword .Lxray_sleds_start0 ; CHECK-NEXT: .xword .Lxray_sleds_end0 @@ -66,14 +63,11 @@ ; CHECK: b callee ret i32 %retval } -; CHECK: .p2align 4 -; CHECK-NEXT: .xword .Lxray_fn_idx_synth_1 -; CHECK-NEXT: .section xray_instr_map,{{.*}} +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start1: ; CHECK: .xword .Lxray_sled_2 ; CHECK: .xword .Lxray_sled_3 ; CHECK-LABEL: Lxray_sleds_end1: ; CHECK: .section xray_fn_idx,{{.*}} -; CHECK-LABEL: Lxray_fn_idx_synth_1: ; CHECK: .xword .Lxray_sleds_start1 ; CHECK-NEXT: .xword .Lxray_sleds_end1 Index: test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll =================================================================== --- test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll +++ test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll @@ -23,14 +23,11 @@ ; CHECK-LABEL: Ltmp1: ; CHECK-NEXT: bx lr } -; CHECK: .p2align 4 -; CHECK-NEXT: .long {{.*}}Lxray_fn_idx_synth_0 -; CHECK-NEXT: .section {{.*}}xray_instr_map{{.*}} +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start0: ; CHECK: .long {{.*}}Lxray_sled_0 ; CHECK: .long {{.*}}Lxray_sled_1 ; CHECK-LABEL: Lxray_sleds_end0: -; CHECK: .section {{.*}}xray_fn_idx{{.*}} -; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK-LABEL: xray_fn_idx ; CHECK: .long {{.*}}Lxray_sleds_start0 ; CHECK-NEXT: .long {{.*}}Lxray_sleds_end0 Index: test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll =================================================================== --- test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll +++ test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll @@ -23,15 +23,12 @@ ; CHECK-LABEL: Ltmp1: ; CHECK-NEXT: bx lr } -; CHECK: .p2align 4 -; CHECK-NEXT: .long {{.*}}Lxray_fn_idx_synth_0 -; CHECK-NEXT: .section {{.*}}xray_instr_map{{.*}} +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start0: ; CHECK: .long {{.*}}Lxray_sled_0 ; CHECK: .long {{.*}}Lxray_sled_1 ; CHECK-LABEL: Lxray_sleds_end0: -; CHECK: .section {{.*}}xray_fn_idx{{.*}} -; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK-LABEL: xray_fn_idx ; CHECK: .long {{.*}}xray_sleds_start0 ; CHECK-NEXT: .long {{.*}}xray_sleds_end0 Index: test/CodeGen/Mips/xray-section-group.ll =================================================================== --- test/CodeGen/Mips/xray-section-group.ll +++ test/CodeGen/Mips/xray-section-group.ll @@ -14,7 +14,7 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .section .text.foo,"ax",@progbits ret i32 0 -; CHECK: .section xray_instr_map,"a",@progbits +; CHECK: .section xray_instr_map,"awo",@progbits,.text.foo,unique,1 } ; CHECK-OBJ: Section { @@ -24,7 +24,7 @@ define i32 @bar() nounwind noinline uwtable "function-instrument"="xray-always" comdat($bar) { ; CHECK: .section .text.bar,"axG",@progbits,bar,comdat ret i32 1 -; CHECK: .section xray_instr_map,"aG",@progbits,bar,comdat +; CHECK: .section xray_instr_map,"aGwo",@progbits,bar,comdat,.text.bar,unique,2 } ; CHECK-OBJ: Section { Index: test/CodeGen/X86/xray-attribute-instrumentation.ll =================================================================== --- test/CodeGen/X86/xray-attribute-instrumentation.ll +++ test/CodeGen/X86/xray-attribute-instrumentation.ll @@ -1,27 +1,25 @@ ; RUN: llc -filetype=asm -o - -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -filetype=asm -o - -mtriple=x86_64-unknown-linux-gnu \ +; RUN: -relocation-model=pic < %s | FileCheck %s ; RUN: llc -filetype=asm -o - -mtriple=x86_64-darwin-unknown < %s | FileCheck %s define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_0: -; CHECK-NEXT: .ascii "\353\t" +; CHECK: .ascii "\353\t" ; CHECK-NEXT: nopw 512(%rax,%rax) -; CHECK-LABEL: Ltmp0: ret i32 0 ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_1: -; CHECK-NEXT: retq +; CHECK: retq ; CHECK-NEXT: nopw %cs:512(%rax,%rax) } -; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_0 -; CHECK-NEXT: .section {{.*}}xray_instr_map +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start0: ; CHECK: .quad {{.*}}xray_sled_0 ; CHECK: .quad {{.*}}xray_sled_1 ; CHECK-LABEL: Lxray_sleds_end0: -; CHECK: .section {{.*}}xray_fn_idx -; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK-LABEL: xray_fn_idx ; CHECK: .quad {{.*}}xray_sleds_start0 ; CHECK-NEXT: .quad {{.*}}xray_sleds_end0 @@ -31,9 +29,8 @@ define i32 @bar(i32 %i) nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_2: -; CHECK-NEXT: .ascii "\353\t" +; CHECK: .ascii "\353\t" ; CHECK-NEXT: nopw 512(%rax,%rax) -; CHECK-LABEL: Ltmp1: Test: %cond = icmp eq i32 %i, 0 br i1 %cond, label %IsEqual, label %NotEqual @@ -41,24 +38,21 @@ ret i32 0 ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_3: -; CHECK-NEXT: retq +; CHECK: retq ; CHECK-NEXT: nopw %cs:512(%rax,%rax) NotEqual: ret i32 1 ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_4: -; CHECK-NEXT: retq +; CHECK: retq ; CHECK-NEXT: nopw %cs:512(%rax,%rax) } -; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_1 -; CHECK-NEXT: .section {{.*}}xray_instr_map +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start1: ; CHECK: .quad {{.*}}xray_sled_2 ; CHECK: .quad {{.*}}xray_sled_3 ; CHECK: .quad {{.*}}xray_sled_4 ; CHECK-LABEL: Lxray_sleds_end1: -; CHECK: .section {{.*}}xray_fn_idx -; CHECK-LABEL: Lxray_fn_idx_synth_1: +; CHECK-LABEL: xray_fn_idx ; CHECK: .quad {{.*}}xray_sleds_start1 ; CHECK-NEXT: .quad {{.*}}xray_sleds_end1 Index: test/CodeGen/X86/xray-custom-log.ll =================================================================== --- test/CodeGen/X86/xray-custom-log.ll +++ test/CodeGen/X86/xray-custom-log.ll @@ -7,16 +7,17 @@ %val = load i32, i32* %eventsize call void @llvm.xray.customevent(i8* %eventptr, i32 %val) ; CHECK-LABEL: Lxray_event_sled_0: - ; CHECK-NEXT: .ascii "\353\024 - ; CHECK-NEXT: pushq %rax + ; CHECK: .byte 0xeb, 0x0f + ; CHECK-NEXT: pushq %rdi ; CHECK-NEXT: movq {{.*}}, %rdi + ; CHECK-NEXT: pushq %rsi ; CHECK-NEXT: movq {{.*}}, %rsi - ; CHECK-NEXT: movabsq $__xray_CustomEvent, %rax - ; CHECK-NEXT: callq *%rax - ; CHECK-NEXT: popq %rax + ; CHECK-NEXT: callq __xray_CustomEvent + ; CHECK-NEXT: popq %rsi + ; CHECK-NEXT: popq %rdi ret i32 0 } -; CHECK: .section {{.*}}xray_instr_map +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start0: ; CHECK: .quad {{.*}}xray_event_sled_0 Index: test/CodeGen/X86/xray-log-args.ll =================================================================== --- test/CodeGen/X86/xray-log-args.ll +++ test/CodeGen/X86/xray-log-args.ll @@ -7,29 +7,33 @@ ret i32 %arg } ; CHECK-LABEL: Lxray_sleds_start0: -; CHECK: .quad {{\.?}}Lxray_sled_0 -; CHECK: .quad {{_?}}callee -; CHECK: .byte 3 -; CHECK: .byte 1 -; CHECK: .{{(zero|space)}} 14 -; CHECK: .quad {{\.?}}Lxray_sled_1 -; CHECK: .quad {{_?}}callee -; CHECK: .byte 1 -; CHECK: .byte 1 -; CHECK: .{{(zero|space)}} 14 +; CHECK: .quad {{\.?}}Lxray_sled_0 +; CHECK: .quad {{_?}}callee +; CHECK: .byte 0x03 +; CHECK: .byte 0x01 +; CHECK: .byte 0x00 +; CHECK: .{{(zero|space)}} 13 +; CHECK: .quad {{\.?}}Lxray_sled_1 +; CHECK: .quad {{_?}}callee +; CHECK: .byte 0x01 +; CHECK: .byte 0x01 +; CHECK: .byte 0x00 +; CHECK: .{{(zero|space)}} 13 define i32 @caller(i32 %arg) nounwind noinline uwtable "function-instrument"="xray-always" "xray-log-args"="1" { %retval = tail call i32 @callee(i32 %arg) ret i32 %retval } ; CHECK-LABEL: Lxray_sleds_start1: -; CHECK: .quad {{\.?}}Lxray_sled_2 -; CHECK: .quad {{_?}}caller -; CHECK: .byte 3 -; CHECK: .byte 1 -; CHECK: .{{(zero|space)}} 14 -; CHECK: .quad {{\.?}}Lxray_sled_3 -; CHECK: .quad {{_?}}caller -; CHECK: .byte 2 -; CHECK: .byte 1 -; CHECK: .{{(zero|space)}} 14 +; CHECK: .quad {{\.?}}Lxray_sled_2 +; CHECK: .quad {{_?}}caller +; CHECK: .byte 0x03 +; CHECK: .byte 0x01 +; CHECK: .byte 0x00 +; CHECK: .{{(zero|space)}} 13 +; CHECK: .quad {{\.?}}Lxray_sled_3 +; CHECK: .quad {{_?}}caller +; CHECK: .byte 0x02 +; CHECK: .byte 0x01 +; CHECK: .byte 0x00 +; CHECK: .{{(zero|space)}} 13 Index: test/CodeGen/X86/xray-loop-detection.ll =================================================================== --- test/CodeGen/X86/xray-loop-detection.ll +++ test/CodeGen/X86/xray-loop-detection.ll @@ -19,5 +19,4 @@ ; CHECK-LABEL: xray_sled_0: ; CHECK-NEXT: .ascii "\353\t" ; CHECK-NEXT: nopw 512(%rax,%rax) -; CHECK-LABEL: Ltmp0: Index: test/CodeGen/X86/xray-section-group.ll =================================================================== --- test/CodeGen/X86/xray-section-group.ll +++ test/CodeGen/X86/xray-section-group.ll @@ -5,14 +5,14 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .section .text.foo,"ax",@progbits ret i32 0 -; CHECK: .section xray_instr_map,"a",@progbits +; CHECK: .section xray_instr_map,"awo",@progbits,.text.foo,unique,1 } $bar = comdat any define i32 @bar() nounwind noinline uwtable "function-instrument"="xray-always" comdat($bar) { ; CHECK: .section .text.bar,"axG",@progbits,bar,comdat ret i32 1 -; CHECK: .section xray_instr_map,"aG",@progbits,bar,comdat +; CHECK: .section xray_instr_map,"aGwo",@progbits,bar,comdat,.text.bar,unique,2 } ; CHECK-OBJ: section xray_instr_map: Index: test/CodeGen/X86/xray-tail-call-sled.ll =================================================================== --- test/CodeGen/X86/xray-tail-call-sled.ll +++ test/CodeGen/X86/xray-tail-call-sled.ll @@ -4,49 +4,41 @@ define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_0: -; CHECK-NEXT: .ascii "\353\t" +; CHECK: .ascii "\353\t" ; CHECK-NEXT: nopw 512(%rax,%rax) -; CHECK-LABEL: Ltmp0: ret i32 0 ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_1: -; CHECK-NEXT: retq +; CHECK: retq ; CHECK-NEXT: nopw %cs:512(%rax,%rax) } -; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_0{{.*}} -; CHECK-NEXT: .section {{.*}}xray_instr_map +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start0: ; CHECK: .quad {{.*}}xray_sled_0 ; CHECK: .quad {{.*}}xray_sled_1 ; CHECK-LABEL: Lxray_sleds_end0: -; CHECK-NEXT: .section {{.*}}xray_fn_idx -; CHECK-LABEL: Lxray_fn_idx_synth_0: +; CHECK-LABEL: xray_fn_idx ; CHECK: .quad {{.*}}xray_sleds_start0 ; CHECK-NEXT: .quad {{.*}}xray_sleds_end0 define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-always" { ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_2: -; CHECK-NEXT: .ascii "\353\t" +; CHECK: .ascii "\353\t" ; CHECK-NEXT: nopw 512(%rax,%rax) -; CHECK-LABEL: Ltmp1: ; CHECK: .p2align 1, 0x90 ; CHECK-LABEL: Lxray_sled_3: ; CHECK-NEXT: .ascii "\353\t" ; CHECK-NEXT: nopw 512(%rax,%rax) -; CHECK-LABEL: Ltmp2: %retval = tail call i32 @callee() ; CHECK: jmp {{.*}}callee {{.*}}# TAILCALL ret i32 %retval } -; CHECK: .p2align 4, 0x90 -; CHECK-NEXT: .quad {{.*}}xray_fn_idx_synth_1{{.*}} +; CHECK-LABEL: xray_instr_map ; CHECK-LABEL: Lxray_sleds_start1: ; CHECK: .quad {{.*}}xray_sled_2 ; CHECK: .quad {{.*}}xray_sled_3 ; CHECK-LABEL: Lxray_sleds_end1: -; CHECK: .section {{.*}}xray_fn_idx -; CHECK-LABEL: Lxray_fn_idx_synth_1: +; CHECK-LABEL: xray_fn_idx ; CHECK: .quad {{.*}}xray_sleds_start1 ; CHECK: .quad {{.*}}xray_sleds_end1