diff options
author | Ian Levesque <ianlevesque@fb.com> | 2020-09-18 14:45:51 -0400 |
---|---|---|
committer | Ian Levesque <ianlevesque@fb.com> | 2020-09-24 22:09:53 -0400 |
commit | 6f7fbdd2857fc8a7280afbb26fd4e1a6450069e4 (patch) | |
tree | 830555b1f045c819c3da54f7d6c7ca26ba491f8e /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 8c98c8803430804010da06a07cfb291dab59067c (diff) | |
download | llvm-6f7fbdd2857fc8a7280afbb26fd4e1a6450069e4.zip llvm-6f7fbdd2857fc8a7280afbb26fd4e1a6450069e4.tar.gz llvm-6f7fbdd2857fc8a7280afbb26fd4e1a6450069e4.tar.bz2 |
[xray] Function coverage groups
Add the ability to selectively instrument a subset of functions by dividing the functions into N logical groups and then selecting a group to cover. By selecting different groups over time you could cover the entire application incrementally with lower overhead than instrumenting the entire application at once.
Differential Revision: https://reviews.llvm.org/D87953
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 016c710..47ef5c8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -32,6 +32,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" @@ -40,6 +41,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Operator.h" +#include "llvm/Support/CRC.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" using namespace clang; using namespace CodeGen; @@ -772,13 +774,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, SanOpts.Mask &= ~SanitizerKind::Null; // Apply xray attributes to the function (as a string, for now) + bool AlwaysXRayAttr = false; if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) { if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has( XRayInstrKind::FunctionEntry) || CGM.getCodeGenOpts().XRayInstrumentationBundle.has( XRayInstrKind::FunctionExit)) { - if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) + if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) { Fn->addFnAttr("function-instrument", "xray-always"); + AlwaysXRayAttr = true; + } if (XRayAttr->neverXRayInstrument()) Fn->addFnAttr("function-instrument", "xray-never"); if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) @@ -804,6 +809,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( XRayInstrKind::FunctionEntry)) Fn->addFnAttr("xray-skip-entry"); + + auto FuncGroups = CGM.getCodeGenOpts().XRayTotalFunctionGroups; + if (FuncGroups > 1) { + auto FuncName = llvm::makeArrayRef<uint8_t>( + CurFn->getName().bytes_begin(), CurFn->getName().bytes_end()); + auto Group = crc32(FuncName) % FuncGroups; + if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup && + !AlwaysXRayAttr) + Fn->addFnAttr("function-instrument", "xray-never"); + } } unsigned Count, Offset; |