kpw updated this revision to Diff 142790.
kpw added a comment.

Undoing formatting change.


Repository:
  rC Clang

https://reviews.llvm.org/D45716

Files:
  include/clang/Basic/Builtins.def
  include/clang/Basic/LangOptions.def
  include/clang/Basic/XRayInstr.h
  include/clang/Driver/Options.td
  include/clang/Driver/XRayArgs.h
  include/clang/Frontend/CodeGenOptions.def
  lib/Basic/XRayInstr.cpp
  lib/CodeGen/CGBuiltin.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Driver/XRayArgs.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/xray-always-emit-typedevent.cpp
  test/CodeGen/xray-instrumentation-bundles.cpp
  test/CodeGen/xray-typedevent.cpp

Index: test/CodeGen/xray-typedevent.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/xray-typedevent.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fxray-instrument -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: @_Z16alwaysInstrumentv
+[[clang::xray_always_instrument]] void alwaysInstrument() {
+  // Event types would normally come from calling __xray_register_event_type
+  // from compiler-rt
+  auto EventType = 1;
+  static constexpr char kPhase[] = "instrument";
+  __xray_typedevent(EventType, kPhase, 10);
+  // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 10)
+}
+
+// CHECK-LABEL: @_Z15neverInstrumentv
+[[clang::xray_never_instrument]] void neverInstrument() {
+  auto EventType = 2;
+  static constexpr char kPhase[] = "never";
+  __xray_typedevent(EventType, kPhase, 5);
+  // CHECK-NOT: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 5)
+}
+
+// CHECK-LABEL: @_Z21conditionalInstrumenti
+[[clang::xray_always_instrument]] void conditionalInstrument(int v) {
+  auto TrueEventType = 3;
+  auto UntrueEventType = 4;
+  static constexpr char kTrue[] = "true";
+  static constexpr char kUntrue[] = "untrue";
+  if (v % 2)
+    __xray_typedevent(TrueEventType, kTrue, 4);
+  else
+    __xray_typedevent(UntrueEventType, kUntrue, 6);
+
+  // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 4)
+  // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 6)
+}
Index: test/CodeGen/xray-instrumentation-bundles.cpp
===================================================================
--- test/CodeGen/xray-instrumentation-bundles.cpp
+++ test/CodeGen/xray-instrumentation-bundles.cpp
@@ -1,30 +1,49 @@
 // RUN: %clang_cc1 -fxray-instrument -fxray-instrumentation-bundle=none -x c++ \
 // RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN:     | FileCheck --check-prefixes CHECK,NOFUNCTION,NOCUSTOM %s
-// RUN: %clang_cc1 -fxray-instrument \
-// RUN:     -fxray-instrumentation-bundle=function -x c++ \
+// RUN:     | FileCheck --check-prefixes CHECK,NOFUNCTION,NOCUSTOM,NOTYPED %s
+// RUN: %clang_cc1 -fxray-instrument -fxray-instrumentation-bundle=function -x c++ \
 // RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM %s
+// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM,NOTYPED %s
 // RUN: %clang_cc1 -fxray-instrument \
 // RUN:     -fxray-instrumentation-bundle=custom -x c++ \
 // RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN:     | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM %s
+// RUN:     | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM,NOTYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN:     -fxray-instrumentation-bundle=typed -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck --check-prefixes CHECK,NOFUNCTION,NOCUSTOM,TYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN:     -fxray-instrumentation-bundle=custom,typed -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM,TYPED %s
 // RUN: %clang_cc1 -fxray-instrument \
 // RUN:     -fxray-instrumentation-bundle=function,custom -x c++ \
 // RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM %s
+// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM,NOTYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN:     -fxray-instrumentation-bundle=function,typed -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM,TYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN:     -fxray-instrumentation-bundle=function,custom,typed -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM,TYPED %s
 // RUN: %clang_cc1 -fxray-instrument \
 // RUN:     -fxray-instrumentation-bundle=function \
-// RUN:     -fxray-instrumentation-bundle=custom -x c++ \
+// RUN:     -fxray-instrumentation-bundle=custom \
+// RUN:     -fxray-instrumentation-bundle=typed -x c++ \
 // RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM %s
+// RUN:     | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM,TYPED %s
 
 // CHECK: define void @_Z16alwaysInstrumentv() #[[ALWAYSATTR:[0-9]+]] {
 [[clang::xray_always_instrument]] void alwaysInstrument() {
   static constexpr char kPhase[] = "always";
   __xray_customevent(kPhase, 6);
+  __xray_typedevent(1, kPhase, 6);
   // CUSTOM: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
   // NOCUSTOM-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
+  // TYPED: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 6)
+  // NOTYPED-NOT: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 6)
 }
 
 // FUNCTION: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}}
Index: test/CodeGen/xray-always-emit-typedevent.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/xray-always-emit-typedevent.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-always-emit-typedevents -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck %s
+
+// CHECK-LABEL: @_Z15neverInstrumentv
+[[clang::xray_never_instrument]] void neverInstrument() {
+  static constexpr char kPhase[] = "never";
+  __xray_typedevent(1, kPhase, 5);
+  // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 5)
+}
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -845,6 +845,8 @@
       Args.hasArg(OPT_fxray_instrument);
   Opts.XRayAlwaysEmitCustomEvents =
       Args.hasArg(OPT_fxray_always_emit_customevents);
+  Opts.XRayAlwaysEmitTypedEvents =
+      Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
       getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
 
@@ -2669,6 +2671,11 @@
       Args.hasFlag(OPT_fxray_always_emit_customevents,
                    OPT_fnoxray_always_emit_customevents, false);
 
+  // -fxray-always-emit-typedevents
+  Opts.XRayAlwaysEmitTypedEvents =
+      Args.hasFlag(OPT_fxray_always_emit_typedevents,
+                   OPT_fnoxray_always_emit_customevents, false);
+
   // -fxray-{always,never}-instrument= filenames.
   Opts.XRayAlwaysInstrumentFiles =
       Args.getAllArgValues(OPT_fxray_always_instrument);
Index: lib/Driver/XRayArgs.cpp
===================================================================
--- lib/Driver/XRayArgs.cpp
+++ lib/Driver/XRayArgs.cpp
@@ -77,6 +77,10 @@
                      options::OPT_fnoxray_always_emit_customevents, false))
       XRayAlwaysEmitCustomEvents = true;
 
+    if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents,
+                     options::OPT_fnoxray_always_emit_typedevents, false))
+      XRayAlwaysEmitTypedEvents = true;
+
     if (!Args.hasFlag(options::OPT_fxray_link_deps,
                       options::OPT_fnoxray_link_deps, true))
       XRayRT = false;
@@ -174,6 +178,9 @@
   if (XRayAlwaysEmitCustomEvents)
     CmdArgs.push_back("-fxray-always-emit-customevents");
 
+  if (XRayAlwaysEmitTypedEvents)
+    CmdArgs.push_back("-fxray-always-emit-typedevents");
+
   CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
                                        Twine(InstructionThreshold)));
 
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -1804,6 +1804,10 @@
   /// XRay custom event handling calls.
   bool AlwaysEmitXRayCustomEvents() const;
 
+  /// AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit
+  /// XRay typed event handling calls.
+  bool AlwaysEmitXRayTypedEvents() const;
+
   /// Encode an address into a form suitable for use in a function prologue.
   llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F,
                                              llvm::Constant *Addr);
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -466,14 +466,21 @@
 }
 
 /// AlwaysEmitXRayCustomEvents - Return true if we should emit IR for calls to
-/// the __xray_customevent(...) builin calls, when doing XRay instrumentation.
+/// the __xray_customevent(...) builtin calls, when doing XRay instrumentation.
 bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const {
   return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
          (CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents ||
           CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
               XRayInstrKind::Custom);
 }
 
+bool CodeGenFunction::AlwaysEmitXRayTypedEvents() const {
+  return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
+         (CGM.getCodeGenOpts().XRayAlwaysEmitTypedEvents ||
+          CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
+              XRayInstrKind::Typed);
+}
+
 llvm::Constant *
 CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F,
                                             llvm::Constant *Addr) {
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -3369,6 +3369,44 @@
     return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
   }
 
+  case Builtin::BI__xray_typedevent: {
+    // TODO: There should be a way to always emit events even if the current
+    // function is not instrumented. Losing events in a stream can cripple
+    // a trace.
+    if (!ShouldXRayInstrumentFunction())
+      return RValue::getIgnored();
+
+    if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+            XRayInstrKind::Typed))
+      return RValue::getIgnored();
+
+    if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
+      if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayTypedEvents())
+        return RValue::getIgnored();
+
+    Function *F = CGM.getIntrinsic(Intrinsic::xray_typedevent);
+    auto FTy = F->getFunctionType();
+    auto Arg0 = EmitScalarExpr(E->getArg(0));
+    auto PTy0 = FTy->getParamType(0);
+    if (PTy0 != Arg0->getType())
+      Arg0 = Builder.CreateTruncOrBitCast(Arg0, PTy0);
+    auto Arg1 = E->getArg(1);
+    auto Arg1Val = EmitScalarExpr(Arg1);
+    auto Arg1Ty = Arg1->getType();
+    auto PTy1 = FTy->getParamType(1);
+    if (PTy1 != Arg1Val->getType()) {
+      if (Arg1Ty->isArrayType())
+        Arg1Val = EmitArrayToPointerDecay(Arg1).getPointer();
+      else
+        Arg1Val = Builder.CreatePointerCast(Arg1Val, PTy1);
+    }
+    auto Arg2 = EmitScalarExpr(E->getArg(2));
+    auto PTy2 = FTy->getParamType(2);
+    if (PTy2 != Arg2->getType())
+      Arg2 = Builder.CreateTruncOrBitCast(Arg2, PTy2);
+    return RValue::get(Builder.CreateCall(F, {Arg0, Arg1Val, Arg2}));
+  }
+
   case Builtin::BI__builtin_ms_va_start:
   case Builtin::BI__builtin_ms_va_end:
     return RValue::get(
Index: lib/Basic/XRayInstr.cpp
===================================================================
--- lib/Basic/XRayInstr.cpp
+++ lib/Basic/XRayInstr.cpp
@@ -21,6 +21,7 @@
                                  .Case("all", XRayInstrKind::All)
                                  .Case("custom", XRayInstrKind::Custom)
                                  .Case("function", XRayInstrKind::Function)
+                                 .Case("typed", XRayInstrKind::Typed)
                                  .Case("none", XRayInstrKind::None)
                                  .Default(XRayInstrKind::None);
   return ParsedKind;
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -95,6 +95,9 @@
 ///< Set when -fxray-always-emit-customevents is enabled.
 CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
 
+///< Set when -fxray-always-emit-typedevents is enabled.
+CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0)
+
 ///< Set the minimum number of instructions in a function to determine selective
 ///< XRay instrumentation.
 VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
Index: include/clang/Driver/XRayArgs.h
===================================================================
--- include/clang/Driver/XRayArgs.h
+++ include/clang/Driver/XRayArgs.h
@@ -29,6 +29,7 @@
   bool XRayInstrument = false;
   int InstructionThreshold = 200;
   bool XRayAlwaysEmitCustomEvents = false;
+  bool XRayAlwaysEmitTypedEvents = false;
   bool XRayRT = true;
 
 public:
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1119,6 +1119,12 @@
 def fnoxray_always_emit_customevents : Flag<["-"], "fno-xray-always-emit-customevents">, Group<f_Group>,
   Flags<[CC1Option]>;
 
+def fxray_always_emit_typedevents : Flag<["-"], "fxray-always-emit-typedevents">, Group<f_Group>,
+  Flags<[CC1Option]>,
+  HelpText<"Determine whether to always emit __xray_typedevent(...) calls even if the function it appears in is not always instrumented.">;
+def fnoxray_always_emit_typedevents : Flag<["-"], "fno-xray-always-emit-typedevents">, Group<f_Group>,
+  Flags<[CC1Option]>;
+
 def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group<f_Group>,
   Flags<[CC1Option]>,
   HelpText<"Tells clang to add the link dependencies for XRay.">;
Index: include/clang/Basic/XRayInstr.h
===================================================================
--- include/clang/Basic/XRayInstr.h
+++ include/clang/Basic/XRayInstr.h
@@ -31,13 +31,15 @@
 enum XRayInstrOrdinal : XRayInstrMask {
   XRIO_Function,
   XRIO_Custom,
+  XRIO_Typed,
   XRIO_Count
 };
 
 constexpr XRayInstrMask None = 0;
 constexpr XRayInstrMask Function = 1U << XRIO_Function;
 constexpr XRayInstrMask Custom = 1U << XRIO_Custom;
-constexpr XRayInstrMask All = Function | Custom;
+constexpr XRayInstrMask Typed = 1U << XRIO_Typed;
+constexpr XRayInstrMask All = Function | Custom | Typed;
 
 } // namespace XRayInstrKind
 
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def
+++ include/clang/Basic/LangOptions.def
@@ -281,6 +281,9 @@
 LANGOPT(XRayAlwaysEmitCustomEvents, 1, 0,
         "controls whether to always emit intrinsic calls to "
         "__xray_customevent(...) builtin.")
+LANGOPT(XRayAlwaysEmitTypedEvents, 1, 0,
+        "controls whether to always emit intrinsic calls to "
+        "__xray_typedevent(...) builtin.")
 
 BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
                "allow editor placeholders in source")
@@ -298,4 +301,3 @@
 #undef VALUE_LANGOPT
 #undef COMPATIBLE_VALUE_LANGOPT
 #undef BENIGN_VALUE_LANGOPT
-
Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -1455,6 +1455,7 @@
 
 // Builtins for XRay
 BUILTIN(__xray_customevent, "vcC*z", "")
+BUILTIN(__xray_typedevent, "vzcC*z", "")
 
 // Win64-compatible va_list functions
 BUILTIN(__builtin_ms_va_start, "vc*&.", "nt")
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to