MaskRay created this revision.
MaskRay added reviewers: aaron.ballman, craig.topper, nickdesaulniers, nsz, 
ostannard, peter.smith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
MaskRay added a parent revision: D73071: [X86] Support 
-fpatchable-function-entry=N,M where M>0.
MaskRay retitled this revision from "[Driver][CodeGen] Support 
-fpatchable-function-prefix=N,M where M>0" to "[Driver][CodeGen] Support 
-fpatchable-function-entry=N,M where M>0".

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73072

Files:
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/CC1Options.td
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/patchable-function-entry.c
  clang/test/Sema/patchable-function-entry-attr.c

Index: clang/test/Sema/patchable-function-entry-attr.c
===================================================================
--- clang/test/Sema/patchable-function-entry-attr.c
+++ clang/test/Sema/patchable-function-entry-attr.c
@@ -13,5 +13,5 @@
 // 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();
Index: clang/test/CodeGen/patchable-function-entry.c
===================================================================
--- clang/test/CodeGen/patchable-function-entry.c
+++ clang/test/CodeGen/patchable-function-entry.c
@@ -17,10 +17,14 @@
 __attribute__((patchable_function_entry(2, 0))) void f20decl();
 void f20decl() {}
 
-// OPT: define void @f() #2
+// CHECK: define void @f52() #2
+__attribute__((patchable_function_entry(5, 2))) void f52() {}
+
+// OPT: define void @f() #3
 void f() {}
 
 /// M in patchable_function_entry(N,M) is currently ignored.
 // CHECK: attributes #0 = { {{.*}} "patchable-function-entry"="0"
 // CHECK: attributes #1 = { {{.*}} "patchable-function-entry"="2"
-// OPT:   attributes #2 = { {{.*}} "patchable-function-entry"="1"
+// CHECK: attributes #2 = { {{.*}} "patchable-function-entry"="3" "patchable-function-prefix"="2"
+// OPT:   attributes #3 = { {{.*}} "patchable-function-entry"="1"
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -4924,9 +4924,9 @@
     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;
     }
   }
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1102,6 +1102,8 @@
 
   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);
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5111,20 +5111,23 @@
 
   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()) {
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -833,13 +833,18 @@
       }
     }
 
+    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));
     }
   }
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1714,7 +1714,7 @@
 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>;
Index: clang/include/clang/Driver/CC1Options.td
===================================================================
--- clang/include/clang/Driver/CC1Options.td
+++ clang/include/clang/Driver/CC1Options.td
@@ -372,6 +372,9 @@
 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">;
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -408,7 +408,7 @@
 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'">,
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -115,6 +115,7 @@
 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.
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -3995,8 +3995,6 @@
 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.
 }];
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to