Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6884,14 +6884,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
<< A->getAsString(Args) << TripleStr;
}
if (Arg *A = Args.getLastArg(options::OPT_mnop_mcount)) {
if (Arch == llvm::Triple::systemz)
if (Arch == llvm::Triple::systemz ||
(TC.getTriple().isX86() && TC.getTriple().isOSBinFormatELF()))
A->render(Args, CmdArgs);
else
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
}
if (Arg *A = Args.getLastArg(options::OPT_mrecord_mcount)) {
if (Arch == llvm::Triple::systemz)
if (Arch == llvm::Triple::systemz ||
(TC.getTriple().isX86() && TC.getTriple().isOSBinFormatELF()))
A->render(Args, CmdArgs);
else
D.Diag(diag::err_drv_unsupported_opt_for_target)
Expand Down
16 changes: 16 additions & 0 deletions clang/test/CodeGen/mnop-mcount.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@
// RUN: %s 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -mnop-mcount -triple s390x-ibm-linux -emit-llvm -o - %s \
// RUN: 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -pg -mfentry -mnop-mcount -triple x86_64-unknown-linux -emit-llvm \
// RUN: -o - %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -pg -mnop-mcount -triple x86_64-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOMFENTRY %s
// RUN: %clang_cc1 -mfentry -mnop-mcount -triple x86_64-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -mnop-mcount -triple x86_64-unknown-linux -emit-llvm -o - %s \
// RUN: 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -pg -mfentry -mnop-mcount -triple i686-unknown-linux -emit-llvm \
// RUN: -o - %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -pg -mnop-mcount -triple i686-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOMFENTRY %s
// RUN: %clang_cc1 -mfentry -mnop-mcount -triple i686-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -mnop-mcount -triple i686-unknown-linux -emit-llvm -o - %s \
// RUN: 2>&1 | FileCheck -check-prefix=NOPG %s

int foo(void) {
return 0;
Expand Down
16 changes: 16 additions & 0 deletions clang/test/CodeGen/mrecord-mcount.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@
// RUN: %s 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -mrecord-mcount -triple s390x-ibm-linux -emit-llvm -o - %s \
// RUN: 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -pg -mfentry -mrecord-mcount -triple x86_64-unknown-linux -emit-llvm \
// RUN: -o - %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -pg -mrecord-mcount -triple x86_64-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOMFENTRY %s
// RUN: %clang_cc1 -mfentry -mrecord-mcount -triple x86_64-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -mrecord-mcount -triple x86_64-unknown-linux -emit-llvm -o - %s \
// RUN: 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -pg -mfentry -mrecord-mcount -triple i686-unknown-linux -emit-llvm \
// RUN: -o - %s 2>&1 | FileCheck %s
// RUN: not %clang_cc1 -pg -mrecord-mcount -triple i686-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOMFENTRY %s
// RUN: %clang_cc1 -mfentry -mrecord-mcount -triple i686-unknown-linux -emit-llvm -o - \
// RUN: %s 2>&1 | FileCheck -check-prefix=NOPG %s
// RUN: %clang_cc1 -mrecord-mcount -triple i686-unknown-linux -emit-llvm -o - %s \
// RUN: 2>&1 | FileCheck -check-prefix=NOPG %s

int foo(void) {
return 0;
Expand Down
5 changes: 2 additions & 3 deletions clang/test/Driver/mcount.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// RUN: %clang --target=s390x -c -### %s -mnop-mcount -mrecord-mcount 2>&1 | FileCheck %s
// RUN: %clang --target=x86_64 -c -### %s -mnop-mcount -mrecord-mcount 2>&1 | FileCheck %s
// RUN: %clang --target=i686 -c -### %s -mnop-mcount -mrecord-mcount 2>&1 | FileCheck %s

// CHECK: "-mnop-mcount"
// CHECK: "-mrecord-mcount"

// RUN: not %clang --target=x86_64 -c -### %s -mnop-mcount -mrecord-mcount 2>&1 | FileCheck --check-prefix=ERR1 %s
// RUN: not %clang --target=aarch64 -c -### %s -mnop-mcount -mrecord-mcount 2>&1 | FileCheck --check-prefix=ERR2 %s

// ERR1: error: unsupported option '-mnop-mcount' for target 'x86_64'
// ERR1: error: unsupported option '-mrecord-mcount' for target 'x86_64'
// ERR2: error: unsupported option '-mnop-mcount' for target 'aarch64'
// ERR2: error: unsupported option '-mrecord-mcount' for target 'aarch64'
14 changes: 11 additions & 3 deletions llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,19 @@ namespace {
bool runOnMachineFunction(MachineFunction &MF) override {
// Reset the subtarget each time through.
Subtarget = &MF.getSubtarget<X86Subtarget>();
IndirectTlsSegRefs = MF.getFunction().hasFnAttribute(
"indirect-tls-seg-refs");
const Function &F = MF.getFunction();

IndirectTlsSegRefs = F.hasFnAttribute("indirect-tls-seg-refs");

if (F.getFnAttribute("fentry-call").getValueAsString() != "true") {
if (F.hasFnAttribute("mnop-mcount"))
report_fatal_error("mnop-mcount only supported with fentry-call");
if (F.hasFnAttribute("mrecord-mcount"))
report_fatal_error("mrecord-mcount only supported with fentry-call");
}

// OptFor[Min]Size are used in pattern predicates that isel is matching.
OptForMinSize = MF.getFunction().hasMinSize();
OptForMinSize = F.hasMinSize();
return SelectionDAGISel::runOnMachineFunction(MF);
}

Expand Down
40 changes: 30 additions & 10 deletions llvm/lib/Target/X86/X86MCInstLower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
Expand All @@ -44,6 +45,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/TargetRegistry.h"
Expand Down Expand Up @@ -662,9 +664,8 @@ static unsigned emitNop(MCStreamer &OS, unsigned NumBytes,
// target cpu. 15-bytes is the longest single NOP instruction, but some
// platforms can't decode the longest forms efficiently.
unsigned MaxNopLength = 1;
unsigned BaseReg = X86::RAX;
if (Subtarget->is64Bit()) {
// FIXME: We can use NOOPL on 32-bit targets with FeatureNOPL, but the
// IndexReg/BaseReg below need to be updated.
if (Subtarget->hasFeature(X86::TuningFast7ByteNOP))
MaxNopLength = 7;
else if (Subtarget->hasFeature(X86::TuningFast15ByteNOP))
Expand All @@ -673,16 +674,19 @@ static unsigned emitNop(MCStreamer &OS, unsigned NumBytes,
MaxNopLength = 11;
else
MaxNopLength = 10;
} if (Subtarget->is32Bit())
} else if (Subtarget->is32Bit() &&
Subtarget->getFeatureBits()[X86::FeatureNOPL]) {
BaseReg = X86::EAX;
MaxNopLength = 10;
} else if (Subtarget->is32Bit())
MaxNopLength = 2;

// Cap a single nop emission at the profitable value for the target
NumBytes = std::min(NumBytes, MaxNopLength);

unsigned NopSize;
unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg;
unsigned Opc, ScaleVal, IndexReg, Displacement, SegmentReg;
IndexReg = Displacement = SegmentReg = 0;
BaseReg = X86::RAX;
ScaleVal = 1;
switch (NumBytes) {
case 0:
Expand All @@ -709,13 +713,13 @@ static unsigned emitNop(MCStreamer &OS, unsigned NumBytes,
NopSize = 5;
Opc = X86::NOOPL;
Displacement = 8;
IndexReg = X86::RAX;
IndexReg = BaseReg;
break;
case 6:
NopSize = 6;
Opc = X86::NOOPW;
Displacement = 8;
IndexReg = X86::RAX;
IndexReg = BaseReg;
break;
case 7:
NopSize = 7;
Expand All @@ -726,19 +730,19 @@ static unsigned emitNop(MCStreamer &OS, unsigned NumBytes,
NopSize = 8;
Opc = X86::NOOPL;
Displacement = 512;
IndexReg = X86::RAX;
IndexReg = BaseReg;
break;
case 9:
NopSize = 9;
Opc = X86::NOOPW;
Displacement = 512;
IndexReg = X86::RAX;
IndexReg = BaseReg;
break;
default:
NopSize = 10;
Opc = X86::NOOPW;
Displacement = 512;
IndexReg = X86::RAX;
IndexReg = BaseReg;
SegmentReg = X86::CS;
break;
}
Expand Down Expand Up @@ -885,6 +889,22 @@ void X86AsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
X86MCInstLower &MCIL) {
bool Is64Bits = Subtarget->is64Bit();
MCContext &Ctx = OutStreamer->getContext();

if (MF->getFunction().hasFnAttribute("mrecord-mcount")) {
MCSymbol *DotSym = OutContext.createTempSymbol();
OutStreamer->pushSection();
OutStreamer->switchSection(
Ctx.getELFSection("__mcount_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC));
OutStreamer->emitSymbolValue(DotSym, Is64Bits ? 8 : 4);
OutStreamer->popSection();
OutStreamer->emitLabel(DotSym);
}

if (MF->getFunction().hasFnAttribute("mnop-mcount")) {
emitX86Nops(*OutStreamer, 5, Subtarget);
return;
}

MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
const MCSymbolRefExpr *Op = MCSymbolRefExpr::create(fentry, Ctx);

Expand Down
45 changes: 45 additions & 0 deletions llvm/test/CodeGen/X86/mnop-mcount-01.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
; RUN: llc %s -mtriple=x86_64-linux-gnu -o - -verify-machineinstrs \
; RUN: | FileCheck --check-prefixes=X64 %s
; RUN: llc %s -mtriple=i686-linux-gnu -o - -verify-machineinstrs \
; RUN: | FileCheck --check-prefix=X86 %s
; RUN: llc %s -mtriple=i686-linux-gnu -mcpu=pentium_pro -o - -verify-machineinstrs \
; RUN: | FileCheck --check-prefix=PPRO %s

define void @test1() #0 {
entry:
ret void

; X64-LABEL: @test1
; X64: callq __fentry__
; X64: retq
; X86-LABEL: @test1
; X86: calll __fentry__
; X86: retl
; PPRO-LABEL: @test1
; PPRO: calll __fentry__
; PPRO: retl
}

define void @test2() #1 {
entry:
ret void

; X64-LABEL: @test2
; X64-NOT: callq __fentry__
; X64: nopl 8(%rax,%rax)
; X64: retq
; X86-LABEL: @test2
; X86-NOT: calll __fentry__
; X86: xchgw %ax, %ax
; X86: xchgw %ax, %ax
; X86: nop
; X86: retl
; PPRO-LABEL: @test2
; PPRO: nopl 8(%eax,%eax)
; PPRO-NOT: calll __fentry__
; PPRO: retl
}

attributes #0 = { "fentry-call"="true" }
attributes #1 = { "fentry-call"="true" "mnop-mcount" }

11 changes: 11 additions & 0 deletions llvm/test/CodeGen/X86/mnop-mcount-02.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; RUN: not --crash llc %s -mtriple=x86_64-linux-gnu -o - 2>&1 | FileCheck %s
; RUN: not --crash llc %s -mtriple=i686-linux-gnu -o - 2>&1 | FileCheck %s
;
; CHECK: LLVM ERROR: mnop-mcount only supported with fentry-call

define void @test1() #0 {
entry:
ret void
}

attributes #0 = { "instrument-function-entry-inlined"="mcount" "mnop-mcount" }
68 changes: 68 additions & 0 deletions llvm/test/CodeGen/X86/mrecord-mcount-01.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
; RUN: llc %s -mtriple=x86_64-linux-gnu -o - -verify-machineinstrs \
; RUN: | FileCheck --check-prefix=X64 %s
; RUN: llc %s -mtriple=i686-linux-gnu -o - -verify-machineinstrs \
; RUN: | FileCheck --check-prefix=X86 %s
; RUN: llc %s -mtriple=i686-linux-gnu -mcpu=pentium_pro -o - -verify-machineinstrs \
; RUN: | FileCheck --check-prefix=PPRO %s

define void @test1() #0 {
entry:
ret void

; X64-LABEL: test1:
; X64: .section __mcount_loc,"a",@progbits
; X64: .quad .Ltmp0
; X64: .text
; X64: .Ltmp0:
; X64: callq __fentry__
; X64: retq
; X86-LABEL: test1:
; X86: .section __mcount_loc,"a",@progbits
; X86: .long .Ltmp0
; X86: .text
; X86: .Ltmp0:
; X86: calll __fentry__
; X86: retl
; PPRO-LABEL: test1:
; PPRO: .section __mcount_loc,"a",@progbits
; PPRO: .long .Ltmp0
; PPRO: .text
; PPRO: .Ltmp0:
; PPRO: calll __fentry__
; PPRO: retl
}

define void @test2() #1 {
entry:
ret void

; X64-LABEL: test2:
; X64: .section __mcount_loc,"a",@progbits
; X64: .quad .Ltmp1
; X64: .text
; X64: .Ltmp1:
; X64: nopl 8(%rax,%rax)
; X64-NOT: callq __fentry__
; X64: retq
; X86-LABEL: test2:
; X86: .section __mcount_loc,"a",@progbits
; X86: .long .Ltmp1
; X86: .text
; X86: .Ltmp1:
; X86: xchgw %ax, %ax
; X86: xchgw %ax, %ax
; X86: nop
; X86-NOT: calll __fentry__
; X86: retl
; PPRO-LABEL: test2:
; PPRO: .section __mcount_loc,"a",@progbits
; PPRO: .long .Ltmp1
; PPRO: .text
; PPRO: .Ltmp1:
; PPRO: nopl 8(%eax,%eax)
; PPRO-NOT: calll __fentry__
; PPRO: retl
}

attributes #0 = { "fentry-call"="true" "mrecord-mcount" }
attributes #1 = { "fentry-call"="true" "mnop-mcount" "mrecord-mcount" }
11 changes: 11 additions & 0 deletions llvm/test/CodeGen/X86/mrecord-mcount-02.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
; RUN: not --crash llc %s -mtriple=x86_64-linux-gnu -o - 2>&1 | FileCheck %s
; RUN: not --crash llc %s -mtriple=i686-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" }