Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -16,11 +16,13 @@ #include "SystemZConstantPoolValue.h" #include "SystemZMCInstLower.h" #include "TargetInfo/SystemZTargetInfo.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/IR/Mangler.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/TargetRegistry.h" @@ -552,18 +554,30 @@ void SystemZAsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &Lower) { + bool RecordMCount = MF->getFunction().hasFnAttribute("mrecord-mcount"); + if (RecordMCount) { + MCSymbol *DotSym = OutContext.createTempSymbol(); + OutStreamer->EmitLabel(DotSym); + } + MCContext &Ctx = MF->getContext(); if (MF->getFunction().getFnAttribute("mnop-mcount") .getValueAsString() == "true") { EmitNop(Ctx, *OutStreamer, 6, getSubtargetInfo()); - return; + } else { + MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__"); + const MCSymbolRefExpr *Op = + MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx); + OutStreamer->EmitInstruction(MCInstBuilder(SystemZ::BRASL) + .addReg(SystemZ::R0D).addExpr(Op), getSubtargetInfo()); } - MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__"); - const MCSymbolRefExpr *Op = - MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_PLT, Ctx); - OutStreamer->EmitInstruction(MCInstBuilder(SystemZ::BRASL) - .addReg(SystemZ::R0D).addExpr(Op), getSubtargetInfo()); + if (RecordMCount) { + OutStreamer->SwitchSection( + Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC)); + OutStreamer->EmitIntValue(0x1b, 8); + OutStreamer->SwitchSection(OutStreamer->getPreviousSection().first); + } } void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { Index: llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -350,6 +350,9 @@ if (F.getFnAttribute("mnop-mcount").getValueAsString() == "true" && F.getFnAttribute("fentry-call").getValueAsString() != "true") report_fatal_error("mnop-mcount only supported with fentry-call"); + if (F.hasFnAttribute("mrecord-mcount") && + F.getFnAttribute("fentry-call").getValueAsString() != "true") + report_fatal_error("mrecord-mcount only supported with fentry-call"); Subtarget = &MF.getSubtarget(); return SelectionDAGISel::runOnMachineFunction(MF); Index: llvm/test/CodeGen/SystemZ/mrecord-mcount-01.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/mrecord-mcount-01.ll @@ -0,0 +1,33 @@ +; RUN: llc %s -mtriple=s390x-linux-gnu -mcpu=z10 -o - -verify-machineinstrs \ +; RUN: | FileCheck %s + +define void @test1() #0 { +entry: + ret void + +; CHECK-LABEL: test1: +; CHECK: .Ltmp0: +; CHECK: brasl %r0, __fentry__@PLT +; CHECK: .section __mcount_loc,"a",@progbits +; CHECK: .quad 27 +; CHECK: .text +; CHECK: br %r14 +} + +define void @test2() #1 { +entry: + ret void + +; CHECK-LABEL: test2: +; CHECK: .Ltmp1: +; CHECK: brcl 0, .Ltmp2 +; CHECK: .Ltmp2: +; CHECK: .section __mcount_loc,"a",@progbits +; CHECK: .quad 27 +; CHECK: .text +; CHECK: br %r14 +} + +attributes #0 = { "fentry-call"="true" "mrecord-mcount" } +attributes #1 = { "fentry-call"="true" "mnop-mcount"="true" "mrecord-mcount" } + Index: llvm/test/CodeGen/SystemZ/mrecord-mcount-02.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/mrecord-mcount-02.ll @@ -0,0 +1,11 @@ +; RUN: not llc %s -mtriple=s390x-linux-gnu -o - 2>&1 | FileCheck %s +; +; CHECK: LLVM ERROR: mrecord-mcount only supported with fentry-call + +define void @test1() #0 { +entry: + ret void +} + +attributes #0 = { "instrument-function-entry-inlined"="mcount" "mrecord-mcount" } +