]> granicus.if.org Git - llvm/commitdiff
[XRay][CodeGen] Use PIC-friendly code in XRay sleds; remove synthetic references...
authorDean Michael Berris <dberris@google.com>
Wed, 23 Aug 2017 04:49:41 +0000 (04:49 +0000)
committerDean Michael Berris <dberris@google.com>
Wed, 23 Aug 2017 04:49:41 +0000 (04:49 +0000)
Summary:
This change achieves two things:

  - Redefine the Custom Event handling instrumentation points emitted by
    the compiler to not require dynamic relocation of references to the
    __xray_CustomEvent trampoline.

  - Remove the synthetic reference we emit at the end of a function that
    we used to keep auxiliary sections alive in favour of SHF_LINK_ORDER
    associated with the section where the function is defined.

To achieve the custom event handling change, we've had to introduce the
concept of sled versioning -- this will need to be supported by the
runtime to allow us to understand how to turn on/off the new version of
the custom event handling sleds. That change has to land first before we
change the way we write the sleds.

To remove the synthetic reference, we rely on a relatively new linker
feature that preserves the sections that are associated with each other.
This allows us to limit the effects on the .text section of ELF
binaries.

Because we're still using absolute references that are resolved at
runtime for the instrumentation map (and function index) maps, we mark
these sections write-able. In the future we can re-define the entries in
the map to use relative relocations instead that can be statically
determined by the linker. That change will be a bit more invasive so we
defer this for later.

Depends on D36816.

Reviewers: dblaikie, echristo, pcc

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D36615

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311525 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/CodeGen/AsmPrinter.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/Target/X86/X86MCInstLower.cpp
test/CodeGen/AArch64/xray-attribute-instrumentation.ll
test/CodeGen/AArch64/xray-tail-call-sled.ll
test/CodeGen/ARM/xray-armv6-attribute-instrumentation.ll
test/CodeGen/ARM/xray-armv7-attribute-instrumentation.ll
test/CodeGen/Mips/xray-section-group.ll
test/CodeGen/X86/xray-attribute-instrumentation.ll
test/CodeGen/X86/xray-custom-log.ll
test/CodeGen/X86/xray-log-args.ll
test/CodeGen/X86/xray-loop-detection.ll
test/CodeGen/X86/xray-section-group.ll
test/CodeGen/X86/xray-tail-call-sled.ll

index 1e78ac9b33a29b025eabb8904df85907af875df4..581a1213d71336d7c06630ed7b1774658d672771 100644 (file)
@@ -235,13 +235,15 @@ public:
 
   // 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 @@ public:
   // All the sleds to be emitted.
   SmallVector<XRayFunctionEntry, 4> 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 5e002e7092907276059c909bba05fb7968822af3..87399354945ad10daa4b43a323671650586891c1 100644 (file)
@@ -2767,10 +2767,13 @@ void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out,
   Out->EmitSymbolValue(Sled, Bytes);
   Out->EmitSymbolValue(CurrentFnSym, Bytes);
   auto Kind8 = static_cast<uint8_t>(Kind);
-  Out->EmitBytes(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
-  Out->EmitBytes(
+  Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
+  Out->EmitBinaryData(
       StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1));
-  Out->EmitZeros(2 * Bytes - 2);  // Pad the previous two entries
+  Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&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 @@ void AsmPrinter::emitXRayTable() {
   MCSection *InstMap = nullptr;
   MCSection *FnSledIndex = nullptr;
   if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) {
+    auto Associated = dyn_cast<MCSymbolELF>(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 @@ void AsmPrinter::emitXRayTable() {
     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 @@ void AsmPrinter::emitXRayTable() {
   // 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 @@ void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI,
     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 fd2837b79103eecec12bf0ec08f58cd057a85127..3ee1cf710c89ad76af38fd10e834f8e1bc584ba3 100644 (file)
@@ -1047,20 +1047,20 @@ void X86AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
   // We want to emit the following pattern, which follows the x86 calling
   // convention to prepare for the trampoline call to be patched in.
   //
-  //   <args placement according SysV64 calling convention>
   //   .p2align 1, ...
   // .Lxray_event_sled_N:
-  //   jmp +N                    // jump across the call instruction
-  //   callq __xray_CustomEvent  // force relocation to symbol
-  //   <args cleanup, jump to here>
-  //
-  // 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  // force dependency to symbol
+  //   ...
+  //   <jump here>
   //
   // 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,55 @@ void X86AsmPrinter::LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI,
   // 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)));
 
   // 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 +1131,6 @@ void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
   // .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 +1141,12 @@ void X86AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
   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 5f01c7c8be84c3430a1ce492cde20b81d56285de..651130414befdc00739e56f238744920ffbe5068 100644 (file)
@@ -24,9 +24,7 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
 ; 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 a7e993b3dbac9bf24d7e24e5371f87be82daff85..f966362b805e87745c6a4ca49e8b13c8f5a63f63 100644 (file)
@@ -27,15 +27,12 @@ define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-alway
 ; CHECK-LABEL: .Ltmp1:\r
 ; CHECK-NEXT:  ret\r
 }\r
-; CHECK:       .p2align 4\r
-; CHECK-NEXT:  .xword .Lxray_fn_idx_synth_0\r
-; CHECK-NEXT:  .section xray_instr_map,{{.*}}\r
+; CHECK-LABEL: xray_instr_map\r
 ; CHECK-LABEL: Lxray_sleds_start0:\r
 ; CHECK:       .xword .Lxray_sled_0\r
 ; CHECK:       .xword .Lxray_sled_1\r
 ; CHECK-LABEL: Lxray_sleds_end0:\r
-; CHECK:       .section xray_fn_idx,{{.*}}\r
-; CHECK-LABEL: Lxray_fn_idx_synth_0:\r
+; CHECK-LABEL: xray_fn_idx\r
 ; CHECK:       .xword .Lxray_sleds_start0\r
 ; CHECK-NEXT:  .xword .Lxray_sleds_end0\r
 \r
@@ -66,14 +63,11 @@ define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-alway
 ; CHECK:       b       callee\r
   ret i32 %retval\r
 }\r
-; CHECK:       .p2align 4\r
-; CHECK-NEXT:  .xword .Lxray_fn_idx_synth_1\r
-; CHECK-NEXT:  .section xray_instr_map,{{.*}}\r
+; CHECK-LABEL: xray_instr_map\r
 ; CHECK-LABEL: Lxray_sleds_start1:\r
 ; CHECK:       .xword .Lxray_sled_2\r
 ; CHECK:       .xword .Lxray_sled_3\r
 ; CHECK-LABEL: Lxray_sleds_end1:\r
 ; CHECK:       .section xray_fn_idx,{{.*}}\r
-; CHECK-LABEL: Lxray_fn_idx_synth_1:\r
 ; CHECK:       .xword .Lxray_sleds_start1\r
 ; CHECK-NEXT:  .xword .Lxray_sleds_end1\r
index 5017de835b5dae0d35889e740894e09b36878cc6..3cec7cd699ad9437d3000243be07347ee393c9a2 100644 (file)
@@ -23,14 +23,11 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
 ; 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 118c02adeb8aa011cbb4a8f29d06946b53998bfe..e10746d33001f4ef073ee5e90148074b32d83c46 100644 (file)
@@ -23,15 +23,12 @@ define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
 ; 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 d87f178ec4bec845be1b5fe0ea3ddabeb04860bc..f122215c641531d3d0d68a282d9eaa69b90db435 100644 (file)
@@ -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 @@ $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 {
index 00b45f8d95b7271cbab194170863a68a4bef2cf1..7fa2c0e118055ce79bcc69256b72d260003833a8 100644 (file)
@@ -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 @foo() nounwind noinline uwtable "function-instrument"="xray-always"
 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 @@ IsEqual:
   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 69fd0f3e9f772e667cd3486c777a9827ab4e2d8f..c9eff58188422220fc6b14e215eb14b601990815 100644 (file)
@@ -7,16 +7,17 @@ define i32 @fn() nounwind noinline uwtable "function-instrument"="xray-always" {
     %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 6fe450ac8ad33c38769c1c7831efed4079174e91..09d2b10f3d71f038c985e64519d27defa9ba5905 100644 (file)
@@ -7,29 +7,33 @@ define i32 @callee(i32 %arg) nounwind noinline uwtable "function-instrument"="xr
   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 3cd6b4aa6f8c4ea603bebc7ed26900783d017b19..12904d76770b80a06b2289867151f587021db6f1 100644 (file)
@@ -19,5 +19,4 @@ Exit:
 ; CHECK-LABEL: xray_sled_0:
 ; CHECK-NEXT:  .ascii "\353\t"
 ; CHECK-NEXT:  nopw 512(%rax,%rax)
-; CHECK-LABEL: Ltmp0:
 
index 7dab8c2ebf771946d25283cff071cde833050bea..a4c45a0893efba719aeafd6acb51d07ee9297bdb 100644 (file)
@@ -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 c4a973e529f40da51ff795cc55e61be4612a0bbc..59ab8ea5995bb1d603e649216dc5f62df074fb3e 100644 (file)
@@ -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