tmsriram updated this revision to Diff 242196.
tmsriram added a comment.

Splitting the clang patch into several pieces:

1. This is the parent patch and just contains support for basic block section 
options.
2. A separate patch for unique internal function names
3. A separate patch for an option to relocate with symbols instead of sections
4. A separate patch for Propeller flags for clang


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

https://reviews.llvm.org/D68049

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/basicblock-sections.c

Index: clang/test/CodeGen/basicblock-sections.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/basicblock-sections.c
@@ -0,0 +1,47 @@
+// REQUIRES: x86-registered-target
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -o - < %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasicblock-sections=all -fbasicblock-sections=none -o - < %s | FileCheck %s --check-prefix=PLAIN
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasicblock-sections=labels -o - < %s | FileCheck %s --check-prefix=BB_LABELS
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasicblock-sections=all -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_ALL
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasicblock-sections=%S/basicblock-sections.funcnames -o - < %s | FileCheck %s --check-prefix=BB_WORLD --check-prefix=BB_LIST
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fbasicblock-sections=all -funique-bb-section-names -o - < %s | FileCheck %s --check-prefix=UNIQUE
+
+int world(int a) {
+  if (a > 10)
+    return 10;
+  else if (a > 5)
+    return 5;
+  else
+    return 0;
+}
+
+int another(int a) {
+  if (a > 10)
+    return 20;
+  return 0;
+}
+
+// PLAIN-NOT: section
+// PLAIN: world
+//
+// BB_LABELS-NOT: section
+// BB_LABELS: world
+// BB_LABELS-LABEL: a.BB.world
+// BB_LABELS-LABEL: aa.BB.world
+// BB_LABEL-LABEL: a.BB.another
+//
+// BB_WORLD: .section .text.world,"ax",@progbits
+// BB_WORLD: world
+// BB_WORLD: .section .text.world,"ax",@progbits,unique
+// BB_WORLD: a.BB.world
+// BB_WORLD: .section .text.another,"ax",@progbits
+// BB_ALL: .section .text.another,"ax",@progbits,unique
+// BB_ALL: a.BB.another
+// BB_LIST-NOT: .section .text.another,"ax",@progbits,unique
+// BB_LIST: another
+// BB_LIST-NOT: a.BB.another
+//
+// UNIQUE: .section .text.world.a.BB.world
+// UNIQUE: .section .text.another.a.BB.another
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -955,14 +955,27 @@
   Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ);
   Opts.UseInitArray = !Args.hasArg(OPT_fno_use_init_array);
 
-  Opts.FunctionSections = Args.hasFlag(OPT_ffunction_sections,
-                                       OPT_fno_function_sections, false);
+  Opts.BBSections = Args.getLastArgValue(OPT_fbasicblock_sections_EQ, "none");
+  if (Opts.BBSections != "all" && Opts.BBSections != "labels" &&
+      Opts.BBSections != "none" && !llvm::sys::fs::exists(Opts.BBSections)) {
+    Diags.Report(diag::err_drv_invalid_value)
+        << Args.getLastArg(OPT_fbasicblock_sections_EQ)->getAsString(Args)
+        << Opts.BBSections;
+  }
+
+  // Basic Block Sections implies Function Sections.
+  Opts.FunctionSections =
+      Args.hasFlag(OPT_ffunction_sections, OPT_fno_function_sections, false) ||
+      (Opts.BBSections != "none" && Opts.BBSections != "labels");
+
   Opts.DataSections = Args.hasFlag(OPT_fdata_sections,
                                    OPT_fno_data_sections, false);
   Opts.StackSizeSection =
       Args.hasFlag(OPT_fstack_size_section, OPT_fno_stack_size_section, false);
   Opts.UniqueSectionNames = Args.hasFlag(OPT_funique_section_names,
                                          OPT_fno_unique_section_names, true);
+  Opts.UniqueBBSectionNames = Args.hasFlag(
+      OPT_funique_bb_section_names, OPT_fno_unique_bb_section_names, false);
 
   Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions);
 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -4153,8 +4153,11 @@
         options::OPT_fno_function_sections,
         options::OPT_fdata_sections,
         options::OPT_fno_data_sections,
+        options::OPT_fbasicblock_sections_EQ,
         options::OPT_funique_section_names,
         options::OPT_fno_unique_section_names,
+        options::OPT_funique_bb_section_names,
+        options::OPT_fno_unique_bb_section_names,
         options::OPT_mrestrict_it,
         options::OPT_mno_restrict_it,
         options::OPT_mstackrealign,
@@ -4686,6 +4689,11 @@
     CmdArgs.push_back("-ffunction-sections");
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fbasicblock_sections_EQ)) {
+    CmdArgs.push_back(
+        Args.MakeArgString(Twine("-fbasicblock-sections=") + A->getValue()));
+  }
+
   if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
                    UseSeparateSections)) {
     CmdArgs.push_back("-fdata-sections");
@@ -4694,6 +4702,11 @@
   if (!Args.hasFlag(options::OPT_funique_section_names,
                     options::OPT_fno_unique_section_names, true))
     CmdArgs.push_back("-fno-unique-section-names");
+
+  if (Args.hasFlag(options::OPT_funique_bb_section_names,
+                   options::OPT_fno_unique_bb_section_names, false))
+    CmdArgs.push_back("-funique-bb-section-names");
+
   Args.AddLastArg(CmdArgs, options::OPT_finstrument_functions,
                   options::OPT_finstrument_functions_after_inlining,
                   options::OPT_finstrument_function_entry_bare);
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/CodeGen/BackendUtil.h"
+#include "fstream"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
@@ -413,6 +414,56 @@
   }
 }
 
+// Basic Block Sections can be enabled for a subset of machine basic blocks.
+// This is done by passing a file containing names of functions for which basic
+// block sections are desired.  Additionally, machine basic block ids of the
+// functions can also be specified for a finer granularity.
+// A file with basic block sections for all of function main and two blocks for
+// function foo looks like this:
+// ----------------------------
+// list.txt:
+// !main
+// !foo
+// !!2
+// !!4
+static bool getBBSectionsList(llvm::TargetOptions &Options,
+                              std::string FunctionsListFile) {
+  assert((Options.BBSections == llvm::BasicBlockSection::List) &&
+         "Invalid BasicBlock Section Type");
+  if (FunctionsListFile.empty())
+    return false;
+
+  std::ifstream fin(FunctionsListFile);
+  if (!fin.good()) {
+    errs() << "Cannot open " + FunctionsListFile;
+    return false;
+  }
+  StringMap<SmallSet<unsigned, 4>>::iterator fi = Options.BBSectionsList.end();
+  std::string line;
+  while ((std::getline(fin, line)).good()) {
+    StringRef S(line);
+    // Lines beginning with @, # are not useful here.
+    if (S.empty() || S[0] == '@' || S[0] == '#')
+      continue;
+    if (!S.consume_front("!") || S.empty())
+      break;
+    if (S.consume_front("!")) {
+      if (fi != Options.BBSectionsList.end())
+        fi->second.insert(std::stoi(S));
+      else {
+        errs() << "Found \"!!\" without preceding \"!\"";
+        return false;
+      }
+    } else {
+      // Start a new function.
+      auto R = Options.BBSectionsList.try_emplace(S.split('/').first);
+      fi = R.first;
+      assert(R.second);
+    }
+  }
+  return true;
+}
+
 static void initTargetOptions(llvm::TargetOptions &Options,
                               const CodeGenOptions &CodeGenOpts,
                               const clang::TargetOptions &TargetOpts,
@@ -471,9 +522,21 @@
   Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
   Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
   Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
+
+  Options.BBSections = llvm::StringSwitch<llvm::BasicBlockSection::SectionMode>(
+                           CodeGenOpts.BBSections)
+                           .Case("all", llvm::BasicBlockSection::All)
+                           .Case("labels", llvm::BasicBlockSection::Labels)
+                           .Case("none", llvm::BasicBlockSection::None)
+                           .Default(llvm::BasicBlockSection::List);
+
+  if (Options.BBSections == llvm::BasicBlockSection::List)
+    getBBSectionsList(Options, CodeGenOpts.BBSections);
+
   Options.FunctionSections = CodeGenOpts.FunctionSections;
   Options.DataSections = CodeGenOpts.DataSections;
   Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
+  Options.UniqueBBSectionNames = CodeGenOpts.UniqueBBSectionNames;
   Options.TLSSize = CodeGenOpts.TLSSize;
   Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
   Options.ExplicitEmulatedTLS = CodeGenOpts.ExplicitEmulatedTLS;
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1937,6 +1937,8 @@
   HelpText<"Place each function in its own section (ELF Only)">;
 def fno_function_sections : Flag<["-"], "fno-function-sections">,
   Group<f_Group>, Flags<[CC1Option]>;
+def fbasicblock_sections_EQ : Joined<["-"], "fbasicblock-sections=">, Group<f_Group>, Flags<[CC1Option, CC1AsOption]>,
+  HelpText<"Place each function's basic blocks in unique sections (ELF Only) : all | labels | none | <filename>">;
 def fdata_sections : Flag <["-"], "fdata-sections">, Group<f_Group>,
  Flags<[CC1Option]>, HelpText<"Place each data in its own section (ELF Only)">;
 def fno_data_sections : Flag <["-"], "fno-data-sections">, Group<f_Group>,
@@ -1952,6 +1954,11 @@
 def fno_unique_section_names : Flag <["-"], "fno-unique-section-names">,
   Group<f_Group>, Flags<[CC1Option]>;
 
+def funique_bb_section_names : Flag <["-"], "funique-bb-section-names">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Use unique names for basic block sections (ELF Only)">;
+def fno_unique_bb_section_names : Flag <["-"], "fno-unique-bb-section-names">,
+  Group<f_Group>, Flags<[CC1Option]>;
 def fstrict_return : Flag<["-"], "fstrict-return">, Group<f_Group>,
   Flags<[CC1Option]>,
   HelpText<"Always treat control flow paths that fall off the end of a "
Index: clang/include/clang/Basic/CodeGenOptions.h
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.h
+++ clang/include/clang/Basic/CodeGenOptions.h
@@ -118,6 +118,9 @@
 
   enum class SignReturnAddressKeyValue { AKey, BKey };
 
+  // Allowed values are {"all", "labels", "none", "<filename>"}
+  std::string BBSections;
+
   enum class FramePointerKind {
     None,        // Omit all frame pointers.
     NonLeaf,     // Keep non-leaf frame pointers.
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -48,6 +48,9 @@
                                      ///< aliases to base ctors when possible.
 CODEGENOPT(DataSections      , 1, 0) ///< Set when -fdata-sections is enabled.
 CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names.
+CODEGENOPT(UniqueBBSectionNames, 1, 1) ///< Set for -funique-bb-section-names,
+                                       ///< Produce unique section names with
+                                       ///< basic block sections.
 ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
 
 CODEGENOPT(DisableFree       , 1, 0) ///< Don't free memory.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to