MaskRay updated this revision to Diff 339833.
MaskRay added a comment.

improve doc


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101016/new/

https://reviews.llvm.org/D101016

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/asan-frame-pointer.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/CodeGen/CommandFlags.h
  llvm/include/llvm/IR/Module.h
  llvm/include/llvm/Support/CodeGen.h
  llvm/lib/CodeGen/CommandFlags.cpp
  llvm/lib/IR/Function.cpp
  llvm/lib/IR/Module.cpp
  llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
  llvm/test/Instrumentation/AddressSanitizer/uwtable.ll

Index: llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
+++ llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
@@ -10,12 +10,15 @@
   ret i32 %tmp
 }
 
-!llvm.module.flags = !{!0}
+!llvm.module.flags = !{!0, !1}
 
 ;; Due to -fasynchronous-unwind-tables.
 !0 = !{i32 7, !"uwtable", i32 1}
 
+;; Due to -fno-omit-frame-pointer.
+!1 = !{i32 7, !"frame-pointer", i32 2}
+
 ;; Set the uwtable attribute on ctor/dtor.
 ; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]]
 ; CHECK: define internal void @asan.module_dtor() #[[#ATTR]]
-; CHECK: attributes #[[#ATTR]] = { nounwind uwtable }
+; CHECK: attributes #[[#ATTR]] = { nounwind uwtable "frame-pointer"="all" }
Index: llvm/lib/IR/Module.cpp
===================================================================
--- llvm/lib/IR/Module.cpp
+++ llvm/lib/IR/Module.cpp
@@ -676,6 +676,16 @@
 
 void Module::setUwtable() { addModuleFlag(ModFlagBehavior::Max, "uwtable", 1); }
 
+FramePointerKind Module::getFramePointer() const {
+  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("frame-pointer"));
+  return static_cast<FramePointerKind>(
+      Val ? cast<ConstantInt>(Val->getValue())->getZExtValue() : 0);
+}
+
+void Module::setFramePointer(FramePointerKind Kind) {
+  addModuleFlag(ModFlagBehavior::Max, "frame-pointer", static_cast<int>(Kind));
+}
+
 void Module::setSDKVersion(const VersionTuple &V) {
   SmallVector<unsigned, 3> Entries;
   Entries.push_back(V.getMajor());
Index: llvm/lib/IR/Function.cpp
===================================================================
--- llvm/lib/IR/Function.cpp
+++ llvm/lib/IR/Function.cpp
@@ -335,8 +335,21 @@
                                           unsigned AddrSpace, const Twine &N,
                                           Module *M) {
   auto *F = new Function(Ty, Linkage, AddrSpace, N, M);
+  AttrBuilder B;
   if (M->getUwtable())
-    F->addAttribute(AttributeList::FunctionIndex, Attribute::UWTable);
+    B.addAttribute(Attribute::UWTable);
+  switch (M->getFramePointer()) {
+  case FramePointerKind::None:
+    // 0 ("none") is the default.
+    break;
+  case FramePointerKind::NonLeaf:
+    B.addAttribute("frame-pointer", "non-leaf");
+    break;
+  case FramePointerKind::All:
+    B.addAttribute("frame-pointer", "all");
+    break;
+  }
+  F->addAttributes(AttributeList::FunctionIndex, B);
   return F;
 }
 
Index: llvm/lib/CodeGen/CommandFlags.cpp
===================================================================
--- llvm/lib/CodeGen/CommandFlags.cpp
+++ llvm/lib/CodeGen/CommandFlags.cpp
@@ -53,7 +53,7 @@
 CGOPT_EXP(CodeModel::Model, CodeModel)
 CGOPT(ExceptionHandling, ExceptionModel)
 CGOPT_EXP(CodeGenFileType, FileType)
-CGOPT(FramePointer::FP, FramePointerUsage)
+CGOPT(FramePointerKind, FramePointerUsage)
 CGOPT(bool, EnableUnsafeFPMath)
 CGOPT(bool, EnableNoInfsFPMath)
 CGOPT(bool, EnableNoNaNsFPMath)
@@ -183,16 +183,16 @@
                      "Emit nothing, for performance testing")));
   CGBINDOPT(FileType);
 
-  static cl::opt<FramePointer::FP> FramePointerUsage(
+  static cl::opt<FramePointerKind> FramePointerUsage(
       "frame-pointer",
       cl::desc("Specify frame pointer elimination optimization"),
-      cl::init(FramePointer::None),
+      cl::init(FramePointerKind::None),
       cl::values(
-          clEnumValN(FramePointer::All, "all",
+          clEnumValN(FramePointerKind::All, "all",
                      "Disable frame pointer elimination"),
-          clEnumValN(FramePointer::NonLeaf, "non-leaf",
+          clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
                      "Disable frame pointer elimination for non-leaf frame"),
-          clEnumValN(FramePointer::None, "none",
+          clEnumValN(FramePointerKind::None, "none",
                      "Enable frame pointer elimination")));
   CGBINDOPT(FramePointerUsage);
 
@@ -662,11 +662,11 @@
   }
   if (FramePointerUsageView->getNumOccurrences() > 0 &&
       !F.hasFnAttribute("frame-pointer")) {
-    if (getFramePointerUsage() == FramePointer::All)
+    if (getFramePointerUsage() == FramePointerKind::All)
       NewAttrs.addAttribute("frame-pointer", "all");
-    else if (getFramePointerUsage() == FramePointer::NonLeaf)
+    else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
       NewAttrs.addAttribute("frame-pointer", "non-leaf");
-    else if (getFramePointerUsage() == FramePointer::None)
+    else if (getFramePointerUsage() == FramePointerKind::None)
       NewAttrs.addAttribute("frame-pointer", "none");
   }
   if (DisableTailCallsView->getNumOccurrences() > 0)
Index: llvm/include/llvm/Support/CodeGen.h
===================================================================
--- llvm/include/llvm/Support/CodeGen.h
+++ llvm/include/llvm/Support/CodeGen.h
@@ -66,10 +66,8 @@
     CGFT_Null         // Do not emit any output.
   };
 
-  // Specify effect of frame pointer elimination optimization.
-  namespace FramePointer {
-    enum FP {All, NonLeaf, None};
-  }
+  // Specify what functions should keep the frame pointer.
+  enum class FramePointerKind { None, NonLeaf, All };
 
 }  // end llvm namespace
 
Index: llvm/include/llvm/IR/Module.h
===================================================================
--- llvm/include/llvm/IR/Module.h
+++ llvm/include/llvm/IR/Module.h
@@ -890,6 +890,11 @@
   bool getUwtable() const;
   void setUwtable();
 
+  /// Get/set whether synthesized functions should get the "frame-pointer"
+  /// attribute.
+  FramePointerKind getFramePointer() const;
+  void setFramePointer(FramePointerKind Kind);
+
   /// @name Utility functions for querying and setting the build SDK version
   /// @{
 
Index: llvm/include/llvm/CodeGen/CommandFlags.h
===================================================================
--- llvm/include/llvm/CodeGen/CommandFlags.h
+++ llvm/include/llvm/CodeGen/CommandFlags.h
@@ -53,7 +53,7 @@
 
 CodeGenFileType getFileType();
 
-llvm::FramePointer::FP getFramePointerUsage();
+FramePointerKind getFramePointerUsage();
 
 bool getEnableUnsafeFPMath();
 
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -1529,6 +1529,16 @@
     can prove that the function does not execute any convergent operations.
     Similarly, the optimizer may remove ``convergent`` on calls/invokes when it
     can prove that the call/invoke cannot call a convergent function.
+``"frame-pointer"``
+    This attribute tells the code generator whether the function
+    should keep the frame pointer. The code generator may emit the frame pointer
+    even if this attribute says the frame pointer can be eliminated.
+    The allowed string values are:
+
+     * ``"none"`` (default) - the frame pointer can be eliminated.
+     * ``"non-leaf"`` - the frame pointer should be kept if the function calls
+       other functions.
+     * ``"all"`` - the frame pointer should be kept.
 ``hot``
     This attribute indicates that this function is a hot spot of the program
     execution. The function will be optimized more aggressively and will be
@@ -6994,6 +7004,24 @@
    contain a flag with the ID ``!"foo"`` that has the value '1' after linking is
    performed.
 
+Synthesized Functions Module Flags Metadata
+-------------------------------------------
+
+These metadata specify the default attributes synthesized functions should have.
+These metadata are currently respected by a few instrumentation passes, such as
+sanitizers.
+
+These metadata correspond to a few function attributes with significant code
+generation behaviors. Function attributes with just optimization purposes
+should not be listed because the performance impact of these synthesized
+functions is small.
+
+- "frame-pointer": **Max**. The value can be 0, 1, or 2. A synthesized function
+  will get the "frame-pointer" function attribute, with value being "none",
+  "non-leaf", or "all", respectively.
+- "uwtable": **Max**. The value can be 0 or 1. If the value is 1, a synthesized
+  function will get the ``uwtable`` function attribute.
+
 Objective-C Garbage Collection Module Flags Metadata
 ----------------------------------------------------
 
Index: clang/test/CodeGen/asan-frame-pointer.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/asan-frame-pointer.cpp
@@ -0,0 +1,19 @@
+/// -mframe-pointer=none sets the module flag "frame-pointer" (merge behavior: max).
+/// asan synthesized ctor/dtor get the "frame-pointer" function attribute if not zero (default).
+// RUN: %clang_cc1 -emit-llvm -fsanitize=address -mframe-pointer=none %s -o - | FileCheck %s --check-prefix=NONE
+// RUN: %clang_cc1 -emit-llvm -fsanitize=address -mframe-pointer=non-leaf %s -o - | FileCheck %s --check-prefix=NONLEAF
+// RUN: %clang_cc1 -emit-llvm -fsanitize=address -mframe-pointer=all %s -o - | FileCheck %s --check-prefix=ALL
+
+int global;
+
+// NONE: define internal void @asan.module_ctor() #[[#ATTR:]] {
+// NONE: define internal void @asan.module_dtor() #[[#ATTR]] {
+// NONE: attributes #[[#ATTR]] = { nounwind }
+
+// NONLEAF: define internal void @asan.module_ctor() #[[#ATTR:]] {
+// NONLEAF: define internal void @asan.module_dtor() #[[#ATTR]] {
+// NONLEAF: attributes #[[#ATTR]] = { nounwind "frame-pointer"="non-leaf" }
+
+// ALL: define internal void @asan.module_ctor() #[[#ATTR:]] {
+// ALL: define internal void @asan.module_dtor() #[[#ATTR]] {
+// ALL: attributes #[[#ATTR]] = { nounwind "frame-pointer"="all" }
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -744,6 +744,18 @@
   if (CodeGenOpts.UnwindTables)
     getModule().setUwtable();
 
+  switch (CodeGenOpts.getFramePointer()) {
+  case CodeGenOptions::FramePointerKind::None:
+    // 0 ("none") is the default.
+    break;
+  case CodeGenOptions::FramePointerKind::NonLeaf:
+    getModule().setFramePointer(llvm::FramePointerKind::NonLeaf);
+    break;
+  case CodeGenOptions::FramePointerKind::All:
+    getModule().setFramePointer(llvm::FramePointerKind::All);
+    break;
+  }
+
   SimplifyPersonality();
 
   if (getCodeGenOpts().EmitDeclMetadata)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to