diff --git a/clang/include/clang/Driver/XRayArgs.h b/clang/include/clang/Driver/XRayArgs.h --- a/clang/include/clang/Driver/XRayArgs.h +++ b/clang/include/clang/Driver/XRayArgs.h @@ -30,6 +30,7 @@ bool XRayAlwaysEmitCustomEvents = false; bool XRayAlwaysEmitTypedEvents = false; bool XRayRT = true; + bool XRayIgnoreLoops = false; public: /// Parses the XRay arguments from an argument list. diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -814,23 +814,25 @@ if (ShouldXRayInstrumentFunction()) Fn->addFnAttr("xray-log-args", llvm::utostr(LogArgs->getArgumentCount())); - if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( - XRayInstrKind::FunctionExit)) { - Fn->addFnAttr("xray-skip-exit"); - } - if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( - XRayInstrKind::FunctionEntry)) { - Fn->addFnAttr("xray-skip-entry"); - } } } else { if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc)) Fn->addFnAttr( "xray-instruction-threshold", llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); - if (CGM.getCodeGenOpts().XRayIgnoreLoops) { + } + + if (ShouldXRayInstrumentFunction()) { + if (CGM.getCodeGenOpts().XRayIgnoreLoops) Fn->addFnAttr("xray-ignore-loops"); - } + + if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::FunctionExit)) + Fn->addFnAttr("xray-skip-exit"); + + if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::FunctionEntry)) + Fn->addFnAttr("xray-skip-entry"); } unsigned Count, Offset; diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp --- a/clang/lib/Driver/XRayArgs.cpp +++ b/clang/lib/Driver/XRayArgs.cpp @@ -101,6 +101,10 @@ options::OPT_fnoxray_link_deps, true)) XRayRT = false; + if (Args.hasFlag(options::OPT_fxray_ignore_loops, + options::OPT_fno_xray_ignore_loops, false)) + XRayIgnoreLoops = true; + auto Bundles = Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle); if (Bundles.empty()) @@ -197,6 +201,9 @@ if (XRayAlwaysEmitTypedEvents) CmdArgs.push_back("-fxray-always-emit-typedevents"); + if (XRayIgnoreLoops) + CmdArgs.push_back("-fxray-ignore-loops"); + CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) + Twine(InstructionThreshold))); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1099,8 +1099,7 @@ Args.hasArg(OPT_fxray_always_emit_typedevents); Opts.XRayInstructionThreshold = getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags); - Opts.XRayIgnoreLoops = - Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false); + Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops); auto XRayInstrBundles = Args.getAllArgValues(OPT_fxray_instrumentation_bundle); diff --git a/clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp b/clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fxray-instrument \ +// RUN: -fxray-instrumentation-bundle=function-entry -x c++ \ +// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \ +// RUN: | FileCheck --check-prefixes CHECK,NOCUSTOM,NOTYPED,SKIPEXIT %s +// RUN: %clang_cc1 -fxray-instrument \ +// RUN: -fxray-instrumentation-bundle=function-exit -x c++ \ +// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \ +// RUN: | FileCheck --check-prefixes CHECK,NOCUSTOM,NOTYPED,SKIPENTRY %s +// RUN: %clang_cc1 -fxray-instrument \ +// RUN: -fxray-instrumentation-bundle=function-entry,function-exit -x c++ \ +// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \ +// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM,NOTYPED %s + +// CHECK: define void @_Z13justAFunctionv() #[[ATTR:[0-9]+]] { +void justAFunction() { +} + +// SKIPENTRY: attributes #[[ATTR]] = {{.*}} "xray-skip-entry" {{.*}} +// SKIPEXIT: attributes #[[ATTR]] = {{.*}} "xray-skip-exit" {{.*}} diff --git a/clang/test/CodeGen/xray-ignore-loops.cpp b/clang/test/CodeGen/xray-ignore-loops.cpp --- a/clang/test/CodeGen/xray-ignore-loops.cpp +++ b/clang/test/CodeGen/xray-ignore-loops.cpp @@ -1,8 +1,9 @@ // RUN: %clang_cc1 -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s +// RUN: %clang -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 -S -emit-llvm -o - %s -target x86_64-unknown-linux-gnu | FileCheck %s int foo() { return 1; } -// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] { +// CHECK: define{{.*}} i32 @_Z3foov() #[[ATTRS:[0-9]+]] { // CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}} diff --git a/clang/test/Driver/XRay/xray-ignore-loops-flags.cpp b/clang/test/Driver/XRay/xray-ignore-loops-flags.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/XRay/xray-ignore-loops-flags.cpp @@ -0,0 +1,10 @@ +// This test ensures that when we invoke the clang compiler, that the -cc1 +// options include the -fxray-ignore-loops flag we provide in the +// invocation. +// +// RUN: %clang -fxray-instrument -fxray-ignore-loops -target x86_64-linux- -### \ +// RUN: -x c++ -std=c++11 -emit-llvm -c -o - %s 2>&1 \ +// RUN: | FileCheck %s +// CHECK: -fxray-ignore-loops +// +// REQUIRES: x86_64 || x86_64h \ No newline at end of file