summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2020-01-20 14:30:06 -0800
committerFangrui Song <maskray@google.com>2020-01-24 10:38:40 -0800
commit5d1fe1a1a9f18c5009e9e282b755e52c5e7ce5a2 (patch)
tree91d714b21bc6223116db128f18b1ae1f2a2fd2a8 /clang
parent6f4edc606b2088bcac066640d5107d2042c203c1 (diff)
downloadbcm5719-llvm-5d1fe1a1a9f18c5009e9e282b755e52c5e7ce5a2.tar.gz
bcm5719-llvm-5d1fe1a1a9f18c5009e9e282b755e52c5e7ce5a2.zip
[Driver][CodeGen] Support -fpatchable-function-entry=N,M and __attribute__((patchable_function_entry(N,M))) where M>0
Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D73072 (cherry picked from commit 69bf40c45fd7f6dfe11b47de42571d8bff5ef94f)
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/AttrDocs.td2
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.def1
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td2
-rw-r--r--clang/include/clang/Driver/CC1Options.td3
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp17
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp11
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp4
-rw-r--r--clang/test/CodeGen/patchable-function-entry.c18
-rw-r--r--clang/test/Driver/fpatchable-function-entry.c8
-rw-r--r--clang/test/Sema/patchable-function-entry-attr.c4
12 files changed, 49 insertions, 25 deletions
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 03d36ae7ab3..7976d08a525 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3995,8 +3995,6 @@ def PatchableFunctionEntryDocs : Documentation {
before the function entry and N-M NOPs after the function entry. This attribute
takes precedence over the command line option ``-fpatchable-function-entry=N,M``.
``M`` defaults to 0 if omitted.
-
-Currently, only M=0 is supported.
}];
}
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 50fc1836282..1ecae98b13b 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -111,6 +111,7 @@ CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0)
VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
VALUE_CODEGENOPT(PatchableFunctionEntryCount , 32, 0) ///< Number of NOPs at function entry
+VALUE_CODEGENOPT(PatchableFunctionEntryOffset , 32, 0)
CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled.
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 0fe14e4e05b..2da41bef266 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -408,7 +408,7 @@ def err_drv_unsupported_indirect_jump_opt : Error<
def err_drv_unknown_indirect_jump_opt : Error<
"unknown '-mindirect-jump=' option '%0'">;
def err_drv_unsupported_fpatchable_function_entry_argument : Error<
- "the second argument of '-fpatchable-function-entry' must be 0 or omitted">;
+ "the second argument of '-fpatchable-function-entry' must be smaller than the first argument">;
def warn_drv_unable_to_find_directory_expected : Warning<
"unable to find %0 directory, expected to be in '%1'">,
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
index dd95aa6bbbb..9387285518d 100644
--- a/clang/include/clang/Driver/CC1Options.td
+++ b/clang/include/clang/Driver/CC1Options.td
@@ -372,6 +372,9 @@ def fsanitize_coverage_no_prune
def fsanitize_coverage_stack_depth
: Flag<["-"], "fsanitize-coverage-stack-depth">,
HelpText<"Enable max stack depth tracing">;
+def fpatchable_function_entry_offset_EQ
+ : Joined<["-"], "fpatchable-function-entry-offset=">, MetaVarName<"<M>">,
+ HelpText<"Generate M NOPs before function entry">;
def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, "
"or none">, Values<"none,clang,llvm">;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index abfa767afea..0a60873443f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1707,7 +1707,7 @@ def fno_max_type_align : Flag<["-"], "fno-max-type-align">, Group<f_Group>;
def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Recognize and construct Pascal-style string literals">;
def fpatchable_function_entry_EQ : Joined<["-"], "fpatchable-function-entry=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Generate N NOPs at function entry">;
+ MetaVarName<"<N,M>">, HelpText<"Generate M NOPs before function entry and N-M NOPs after function entry">;
def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Override the default ABI to return all structs on the stack">;
def fpch_preprocess : Flag<["-"], "fpch-preprocess">, Group<f_Group>;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 2bf94f697e0..648e6d9c214 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -820,13 +820,18 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
}
+ unsigned Count, Offset;
if (const auto *Attr = D->getAttr<PatchableFunctionEntryAttr>()) {
- // Attr->getStart is currently ignored.
- Fn->addFnAttr("patchable-function-entry",
- std::to_string(Attr->getCount()));
- } else if (unsigned Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount) {
- Fn->addFnAttr("patchable-function-entry",
- std::to_string(Count));
+ Count = Attr->getCount();
+ Offset = Attr->getOffset();
+ } else {
+ Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount;
+ Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset;
+ }
+ if (Count && Offset <= Count) {
+ Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset));
+ if (Offset)
+ Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset));
}
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 9b3055413e9..647465863d3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5077,20 +5077,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) {
StringRef S0 = A->getValue(), S = S0;
- unsigned Size, Start = 0;
+ unsigned Size, Offset = 0;
if (!Triple.isAArch64() && Triple.getArch() != llvm::Triple::x86 &&
Triple.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
else if (S.consumeInteger(10, Size) ||
(!S.empty() && (!S.consume_front(",") ||
- S.consumeInteger(10, Start) || !S.empty())))
+ S.consumeInteger(10, Offset) || !S.empty())))
D.Diag(diag::err_drv_invalid_argument_to_option)
<< S0 << A->getOption().getName();
- else if (Start)
+ else if (Size < Offset)
D.Diag(diag::err_drv_unsupported_fpatchable_function_entry_argument);
- else
+ else {
CmdArgs.push_back(Args.MakeArgString(A->getSpelling() + Twine(Size)));
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fpatchable-function-entry-offset=" + Twine(Offset)));
+ }
}
if (TC.SupportsProfiling()) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index edf1f27b7c5..4e5babdbaa0 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1103,6 +1103,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.PatchableFunctionEntryCount =
getLastArgIntValue(Args, OPT_fpatchable_function_entry_EQ, 0, Diags);
+ Opts.PatchableFunctionEntryOffset = getLastArgIntValue(
+ Args, OPT_fpatchable_function_entry_offset_EQ, 0, Diags);
Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
Opts.CallFEntry = Args.hasArg(OPT_mfentry);
Opts.MNopMCount = Args.hasArg(OPT_mnop_mcount);
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5c51b0f9b8c..849bc09063b 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -4924,9 +4924,9 @@ static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
Expr *Arg = AL.getArgAsExpr(1);
if (!checkUInt32Argument(S, AL, Arg, Offset, 1, true))
return;
- if (Offset) {
+ if (Count < Offset) {
S.Diag(getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
- << &AL << 0 << 0 << Arg->getBeginLoc();
+ << &AL << 0 << Count << Arg->getBeginLoc();
return;
}
}
diff --git a/clang/test/CodeGen/patchable-function-entry.c b/clang/test/CodeGen/patchable-function-entry.c
index 50b96ea883a..f41f12d0669 100644
--- a/clang/test/CodeGen/patchable-function-entry.c
+++ b/clang/test/CodeGen/patchable-function-entry.c
@@ -17,10 +17,20 @@ __attribute__((patchable_function_entry(2, 0))) void f20() {}
__attribute__((patchable_function_entry(2, 0))) void f20decl();
void f20decl() {}
-// OPT: define void @f() #2
+// CHECK: define void @f44() #2
+__attribute__((patchable_function_entry(4, 4))) void f44() {}
+
+// CHECK: define void @f52() #3
+__attribute__((patchable_function_entry(5, 2))) void f52() {}
+
+// OPT: define void @f() #4
void f() {}
-/// M in patchable_function_entry(N,M) is currently ignored.
-// CHECK: attributes #0 = { {{.*}} "patchable-function-entry"="0"
+/// No need to emit "patchable-function-entry"="0"
+// CHECK: attributes #0 = { {{.*}}
+// CHECK-NOT: "patchable-function-entry"
+
// CHECK: attributes #1 = { {{.*}} "patchable-function-entry"="2"
-// OPT: attributes #2 = { {{.*}} "patchable-function-entry"="1"
+// CHECK: attributes #2 = { {{.*}} "patchable-function-entry"="0" "patchable-function-prefix"="4"
+// CHECK: attributes #3 = { {{.*}} "patchable-function-entry"="3" "patchable-function-prefix"="2"
+// OPT: attributes #4 = { {{.*}} "patchable-function-entry"="1"
diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c
index 36076dc393c..5ac262c1a46 100644
--- a/clang/test/Driver/fpatchable-function-entry.c
+++ b/clang/test/Driver/fpatchable-function-entry.c
@@ -4,12 +4,14 @@
// RUN: %clang -target aarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// CHECK: "-fpatchable-function-entry=1"
+// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=1,1 -c -### 2>&1 | FileCheck --check-prefix=11 %s
+// 11: "-fpatchable-function-entry=1" "-fpatchable-function-entry-offset=1"
+// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=2,1 -c -### 2>&1 | FileCheck --check-prefix=21 %s
+// 21: "-fpatchable-function-entry=2" "-fpatchable-function-entry-offset=1"
+
// RUN: not %clang -target ppc64 -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=TARGET %s
// TARGET: error: unsupported option '-fpatchable-function-entry=1' for target 'ppc64'
-// RUN: not %clang -target i386 -fsyntax-only %s -fpatchable-function-entry=1,1 2>&1 | FileCheck --check-prefix=NONZERO %s
-// NONZERO: error: the second argument of '-fpatchable-function-entry' must be 0 or omitted
-
// RUN: not %clang -target x86_64 -fsyntax-only %s -fpatchable-function-entry=1,0, 2>&1 | FileCheck --check-prefix=EXCESS %s
// EXCESS: error: invalid argument '1,0,' to -fpatchable-function-entry=
diff --git a/clang/test/Sema/patchable-function-entry-attr.c b/clang/test/Sema/patchable-function-entry-attr.c
index f807bd45e42..0fa1abdbd8a 100644
--- a/clang/test/Sema/patchable-function-entry-attr.c
+++ b/clang/test/Sema/patchable-function-entry-attr.c
@@ -13,5 +13,5 @@ int i;
// expected-error@+1 {{'patchable_function_entry' attribute requires parameter 0 to be an integer constant}}
__attribute__((patchable_function_entry(i))) void f();
-// expected-error@+1 {{'patchable_function_entry' attribute requires integer constant between 0 and 0 inclusive}}
-__attribute__((patchable_function_entry(1, 1))) void f();
+// expected-error@+1 {{'patchable_function_entry' attribute requires integer constant between 0 and 2 inclusive}}
+__attribute__((patchable_function_entry(2, 3))) void f();
OpenPOWER on IntegriCloud