dberris created this revision.
Herald added a subscriber: mehdi_amini.

We define the `__xray_customeevent` builtin that gets translated to
IR calls to the correct intrinsic. The default implementation of this is
a no-op function. The codegen side of this follows the following logic:

- When `-fxray-instrument` is not provided in the driver, we elide all

calls to `__xray_customevent`.

- When `-fxray-instrument` is enabled and a function is marked as "never

instrumented", we elide all calls to `__xray_customevent` in that
function; if either marked as "always instrumented" or subject to
threshold-based instrumentation, we emit a call to the
`llvm.xray.customevent` intrinsic from LLVM for each
`__xray_customevent` occurrence in the function.

This change depends on https://reviews.llvm.org/D27503 (to land in LLVM first).


https://reviews.llvm.org/D30018

Files:
  include/clang/Basic/Builtins.def
  lib/CodeGen/CGBuiltin.cpp
  lib/Headers/xrayintrin.h
  test/CodeGen/xray-customevent.cpp

Index: test/CodeGen/xray-customevent.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/xray-customevent.cpp
@@ -0,0 +1,28 @@
+// 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() {
+  static constexpr char kPhase[] = "instrument";
+  __xray_customevent(kPhase, 10);
+  // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i8 10)
+}
+
+// CHECK-LABEL: @_Z15neverInstrumentv
+[[clang::xray_never_instrument]] void neverInstrument() {
+  static constexpr char kPhase[] = "never";
+  __xray_customevent(kPhase, 5);
+  // CHECK-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i8 5)
+}
+
+// CHECK-LABEL: @_Z21conditionalInstrumenti
+[[clang::xray_always_instrument]] void conditionalInstrument(int v) {
+  static constexpr char kTrue[] = "true";
+  static constexpr char kUntrue[] = "untrue";
+  if (v % 2)
+    __xray_customevent(kTrue, 4);
+  else
+    __xray_customevent(kUntrue, 6);
+
+  // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i8 4)
+  // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i8 6)
+}
Index: lib/Headers/xrayintrin.h
===================================================================
--- /dev/null
+++ lib/Headers/xrayintrin.h
@@ -0,0 +1,34 @@
+/*===---- xrayintrin.h - XRay intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __XRAYINTRIN_H
+#define __XRAYINTRIN_H
+
+extern "C" {
+inline void __xray_customevent(const char*, size_t) {
+  // Does nothing by design. The intent is the compiler's back-end will handle
+  // this particular intrinsic as special, and code-gen this appropriately.
+}
+}
+
+#endif  // __XRAYINTRIN_H
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -2741,6 +2741,38 @@
     return RValue::get(ConstantInt::get(ConvertType(E->getType()),
                                         Layout.size().getQuantity()));
   }
+  case Builtin::BI__xray_customevent: {
+    if (!this->ShouldXRayInstrumentFunction())
+      return RValue::getIgnored();
+    if (const auto *XRayAttr =
+            this->CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
+      if (XRayAttr->neverXRayInstrument())
+        return RValue::getIgnored();
+    }
+    Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
+    // FIXME: assert that the types of the arguments match the intrinsic's
+    // specification.
+    SmallVector<Value *, 2> Args;
+    auto FTy = F->getFunctionType();
+    auto Arg0 = E->getArg(0);
+    auto Arg0Val = EmitScalarExpr(Arg0);
+    auto Arg0Ty = Arg0->getType();
+    auto PTy0 = FTy->getParamType(0);
+    if (PTy0 != Arg0Val->getType()) {
+      if (Arg0Ty->isArrayType())
+        Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer();
+      else
+        Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0);
+    }
+    Args.push_back(Arg0Val);
+    auto Arg1 = EmitScalarExpr(E->getArg(1));
+    auto PTy1 = FTy->getParamType(1);
+    if (PTy1 != Arg1->getType())
+      Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
+    Args.push_back(Arg1);
+    Value *V = Builder.CreateCall(F, Args);
+    return RValue::get(V);
+  }
   }
 
   // If this is an alias for a lib function (e.g. __builtin_sin), emit
Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -1407,6 +1407,9 @@
 BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
 BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
 
+// Builtins for XRay
+BUILTIN(__xray_customevent, "vcC*z", "")
+
 #undef BUILTIN
 #undef LIBBUILTIN
 #undef LANGBUILTIN
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D30018: [XRay]... Dean Michael Berris via Phabricator via cfe-commits

Reply via email to