Skip to content
Merged
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
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4255,6 +4255,13 @@ def YkUnrollSafe : InheritableAttr {
let SimpleHandler = 1;
}

def YkIndirectInline : InheritableAttr {
let Spellings = [GCC<"yk_indirect_inline">, Declspec<"yk_indirect_inline">];
let Subjects = SubjectList<[Function]>;
let Documentation = [YkIndirectInlineDocs];
let SimpleHandler = 1;
}

def WebAssemblyFuncref : TypeAttr, TargetSpecificAttr<TargetWebAssembly> {
let Spellings = [CustomKeyword<"__funcref">];
let Documentation = [WebAssemblyExportNameDocs];
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -7205,6 +7205,14 @@ def YkUnrollSafeDocs : Documentation {
}];
}

def YkIndirectInlineDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
This attribute prevents functions only called indirectly from being
marked yk_outline.
}];
}

def ReadOnlyPlacementDocs : Documentation {
let Category = DocCatType;
let Content = [{This attribute is attached to a structure, class or union declaration.
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2423,6 +2423,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
B.addAttribute(YK_IDEMPOTENT_FNATTR);
}

if (D->hasAttr<YkIndirectInlineAttr>()) {
B.addAttribute(YK_INDIRECT_INLINE_FNATTR);
}

// Mark all functions containing loops with `yk_outline` unless the function
// was annotated `yk_unroll_safe`.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
// CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: YkIdempotent (SubjectMatchRule_function)
// CHECK-NEXT: YkIndirectInline (SubjectMatchRule_function)
// CHECK-NEXT: YkOutline (SubjectMatchRule_function)
// CHECK-NEXT: YkUnrollSafe (SubjectMatchRule_function)
// CHECK-NEXT: ZeroCallUsedRegs (SubjectMatchRule_function)
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/YkIR/YkIRWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "llvm/MC/MCStreamer.h"

#define YK_OUTLINE_FNATTR "yk_outline"
#define YK_INDIRECT_INLINE_FNATTR "yk_indirect_inline"
#define YK_PROMOTE_PREFIX "__yk_promote"
#define YK_DEBUG_STR "yk_debug_str"

Expand Down
18 changes: 15 additions & 3 deletions llvm/lib/Transforms/Yk/OutlineUntraceable.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//===- OutlineUntraceable.cpp - Add yk_outline to untraceable functions -===
////
//
// This pass searches for functions which can never be traced and marks them
// `yk_outline`. This has two effects:
// This pass searches for functions which are unlikely to be traced and marks
// them `yk_outline`. This has two effects:
//
// - It causes instrumentation passes that run after this to ignore the
// untraceable functions. This means that we don't have to pay a runtime
Expand Down Expand Up @@ -94,7 +94,19 @@ class OutlineUntraceable : public ModulePass {
bool Changed = false;

for (Function &F : M) {
if ((!F.isDeclaration()) && (!couldBeTraced(&IG, &F))) {
// Note that the inverted call graph doesn't take into account indirect
// calls. This means that we will sometimes consider functions that could
// be traceable (via indirect calls) untraceable.
//
// An earlier attempt to consider functions called from functions with
// their address taken, as potentially traceable, lead to much worse
// performance overall. We may need to revisit this.
//
// To prevent this pass from `yk_outline`ing a function only called
// indirectly, the interpreter author can annotate it with the
// `yk_indirect_inline` function attribute.
if ((!F.isDeclaration()) && (!couldBeTraced(&IG, &F)) &&
(!F.hasFnAttribute(YK_INDIRECT_INLINE_FNATTR))) {
F.addFnAttr(YK_OUTLINE_FNATTR);
Changed = true;
}
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/YkIR/YkIRWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const int PPArgIdxNumTargetArgs = 3;
// Function flags.
const uint8_t YkFuncFlagOutline = 1;
const uint8_t YkFuncFlagIdempotent = 2;
const uint8_t YkFuncFlagInlineIndirect = 4;

#include <sstream>

Expand Down Expand Up @@ -1714,6 +1715,9 @@ class YkIRWriter {
if (F.hasFnAttribute(YK_IDEMPOTENT_FNATTR)) {
Flags |= YkFuncFlagIdempotent;
}
if (F.hasFnAttribute(YK_INDIRECT_INLINE_FNATTR)) {
Flags |= YkFuncFlagInlineIndirect;
}
OutStreamer.emitInt8(Flags);
}

Expand Down