[PATCH] options -ffunction-sections and -fdata-sections

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] options -ffunction-sections and -fdata-sections

Sylvere Teissier
Hi,

This is a patch that implements "-ffunction-sections" and
"-fdata-sections" options.
These options place each functions and data into its own section in the
output file.
Currently it works only for elf format backend, for other object formats
these options are ignored.

This patch is separated for clang tree and llvm tree.



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

function-data-sections.patch (6K) Download Attachment
function-data-sections-clang.patch (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] options -ffunction-sections and -fdata-sections

Anton Korobeynikov
Hello, Sylvere

> Currently it works only for elf format backend, for other object formats
> these options are ignored.
First of all, please honor the LLVM coding style (or, at least, the
code style of the source files you're modifying).
Second, I belive the approach used is wrong - there is already way to
emit objects into separate sections, which
is used for linkonce objects, you just need to hook in there. No need
to reinvent the wheel :)

--
With best regards, Anton Korobeynikov
Faculty of Mathematics and Mechanics, Saint Petersburg State University
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] options -ffunction-sections and -fdata-sections

Sylvere Teissier
Anton Korobeynikov wrote:
> Hello, Sylvere
>
>  
>> Currently it works only for elf format backend, for other object formats
>> these options are ignored.
>>    
> First of all, please honor the LLVM coding style (or, at least, the
> code style of the source files you're modifying).
>  
Ok, I have checked this point, I hope it's ok now
> Second, I belive the approach used is wrong - there is already way to
> emit objects into separate sections, which
> is used for linkonce objects, you just need to hook in there. No need
> to reinvent the wheel :)
>  
Thanks for the tip, I've changed my patch using the existing code. But I
use different section names than gnu.linkonce when It's not "WeakForLinker"
because gnu.linkonce.* are special sections. (I try to follow GCC
section naming for -ffunction-sections/-fdata-sections)


Index: include/clang/CodeGen/CodeGenOptions.h
===================================================================
--- include/clang/CodeGen/CodeGenOptions.h (revision 100677)
+++ include/clang/CodeGen/CodeGenOptions.h (working copy)
@@ -32,6 +32,7 @@
   unsigned CXAAtExit         : 1; /// Use __cxa_atexit for calling destructors.
   unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
                                   /// aliases to base ctors when possible.
+  unsigned DataSections      : 1; /// Set when -fdata-sections is enabled
   unsigned DebugInfo         : 1; /// Should generate deubg info (-g).
   unsigned DisableFPElim     : 1; /// Set when -fomit-frame-pointer is enabled.
   unsigned DisableLLVMOpts   : 1; /// Don't run any optimizations, for use in
@@ -39,6 +40,7 @@
                                   /// internal state before optimizations are
                                   /// done.
   unsigned DisableRedZone    : 1; /// Set when -mno-red-zone is enabled.
+  unsigned FunctionSections  : 1; /// Set when -ffunction-sections is enabled
   unsigned MergeAllConstants : 1; /// Merge identical constants.
   unsigned NoCommon          : 1; /// Set when -fno-common or C++ is enabled.
   unsigned NoImplicitFloat   : 1; /// Set when -mno-implicit-float is enabled.
@@ -88,10 +90,12 @@
     AsmVerbose = 0;
     CXAAtExit = 1;
     CXXCtorDtorAliases = 0;
+    DataSections = 0;
     DebugInfo = 0;
     DisableFPElim = 0;
     DisableLLVMOpts = 0;
     DisableRedZone = 0;
+    FunctionSections = 0;
     MergeAllConstants = 1;
     NoCommon = 0;
     NoImplicitFloat = 0;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td (revision 100677)
+++ include/clang/Driver/CC1Options.td (working copy)
@@ -123,6 +123,10 @@
   HelpText<"Do not emit code to make initialization of local statics thread safe">;
 def fdump_vtable_layouts : Flag<"-fdump-vtable-layouts">,
   HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
+def ffunction_sections : Flag<"-ffunction-sections">,
+  HelpText<"Place each function in its own section (ELF Only)">;
+def fdata_sections : Flag<"-fdata-sections">,
+  HelpText<"Place each data in its own section (ELF Only)">;
 def masm_verbose : Flag<"-masm-verbose">,
   HelpText<"Generate verbose assembly output">;
 def mcode_model : Separate<"-mcode-model">,
Index: lib/Frontend/CodeGenAction.cpp
===================================================================
--- lib/Frontend/CodeGenAction.cpp (revision 100677)
+++ lib/Frontend/CodeGenAction.cpp (working copy)
@@ -261,6 +261,9 @@
 
   TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
 
+  TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
+  TargetMachine::setDataSections    (CodeGenOpts.DataSections);
+
   // FIXME: Parse this earlier.
   if (CodeGenOpts.RelocationModel == "static") {
     TargetMachine::setRelocationModel(llvm::Reloc::Static);
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp (revision 100677)
+++ lib/Frontend/CompilerInvocation.cpp (working copy)
@@ -148,6 +148,10 @@
   // VerifyModule is only derived.
   // Inlining is only derived.
 
+  if(Opts.DataSections)
+    Res.push_back("-fdata-sections");
+  if(Opts.FunctionSections)
+    Res.push_back("-ffunction-sections");
   if (Opts.AsmVerbose)
     Res.push_back("-masm-verbose");
   if (!Opts.CodeModel.empty()) {
@@ -801,6 +805,9 @@
   Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
   Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic");
 
+  Opts.FunctionSections = Args.hasArg(OPT_ffunction_sections);
+  Opts.DataSections = Args.hasArg(OPT_fdata_sections);
+
   Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name);
   Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
 }


Index: include/llvm/Target/TargetMachine.h
===================================================================
--- include/llvm/Target/TargetMachine.h (revision 100677)
+++ include/llvm/Target/TargetMachine.h (working copy)
@@ -171,6 +171,20 @@
   /// is false.
   static void setAsmVerbosityDefault(bool);
 
+  /// getDataSections - Returns if the data are emit into separate sections
+  static bool getDataSections();
+
+  /// getFunctionSections - Returns if the functions are emit into separate
+  /// sections
+  static bool getFunctionSections();
+
+  /// setDataSections - Set if the data are emit into separate sections
+  static void setDataSections(bool);
+
+  /// setFunctionSections - Set if the functions are emit into separate
+  /// sections
+  static void setFunctionSections(bool);
+
   /// CodeGenFileType - These enums are meant to be passed into
   /// addPassesToEmitFile to indicate what type of file to emit, and returned by
   /// it to indicate what type of file could actually be made.
Index: lib/Target/TargetMachine.cpp
===================================================================
--- lib/Target/TargetMachine.cpp (revision 100677)
+++ lib/Target/TargetMachine.cpp (working copy)
@@ -46,6 +46,8 @@
   bool DisableJumpTables;
   bool StrongPHIElim;
   bool AsmVerbosityDefault(false);
+  bool FunctionSections;
+  bool DataSections;
 }
 
 static cl::opt<bool, true>
@@ -197,7 +199,16 @@
   cl::desc("Use strong PHI elimination."),
   cl::location(StrongPHIElim),
   cl::init(false));
-
+static cl::opt<bool, true>
+EnableDataSections("fdata-sections",
+  cl::desc("Emit data into separate sections"),
+  cl::location(DataSections),
+  cl::init(false));
+static cl::opt<bool, true>
+EnableFunctionSections("ffunction-sections",
+  cl::desc("Emit functions into separate sections"),
+  cl::location(FunctionSections),
+  cl::init(false));
 //---------------------------------------------------------------------------
 // TargetMachine Class
 //
@@ -244,6 +255,22 @@
   AsmVerbosityDefault = V;
 }
 
+bool TargetMachine::getFunctionSections() {
+  return FunctionSections;
+}
+
+bool TargetMachine::getDataSections() {
+  return DataSections;
+}
+
+void TargetMachine::setFunctionSections(bool V) {
+  FunctionSections = V;
+}
+
+void TargetMachine::setDataSections(bool V) {
+  DataSections = V;
+}
+
 namespace llvm {
   /// LessPreciseFPMAD - This flag return true when -enable-fp-mad option
   /// is specified on the command line.  When this flag is off(default), the
Index: lib/CodeGen/TargetLoweringObjectFileImpl.cpp
===================================================================
--- lib/CodeGen/TargetLoweringObjectFileImpl.cpp (revision 100677)
+++ lib/CodeGen/TargetLoweringObjectFileImpl.cpp (working copy)
@@ -300,14 +300,46 @@
   return ".gnu.linkonce.d.rel.ro.";
 }
 
+//name of sections used by options FunctionsSections and DataSections
+//it's the same name as normal sections
+static const char *getSectionPrefixForGlobal(SectionKind Kind) {
+  if (Kind.isText())                 return ".text.";
+  if (Kind.isReadOnly())             return ".rodata.";
+
+  if (Kind.isThreadData())           return ".tdata.";
+  if (Kind.isThreadBSS())            return ".tbss.";
+
+  if (Kind.isDataNoRel())            return ".data.";
+  if (Kind.isDataRelLocal())         return ".data.rel.local.";
+  if (Kind.isDataRel())              return ".data.rel.";
+  if (Kind.isReadOnlyWithRelLocal()) return ".data.rel.ro.local.";
+
+  assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+  return ".data.rel.ro.";
+}
+
+
 const MCSection *TargetLoweringObjectFileELF::
 SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
                        Mangler *Mang, const TargetMachine &TM) const {
 
+  //Compute if we have to force to emit the global in a 'uniqued' section name
+  bool EmitUniquedSection;
+  if (Kind.isText())
+    EmitUniquedSection = TM.getFunctionSections();
+  else
+    EmitUniquedSection = TM.getDataSections();
+
   // If this global is linkonce/weak and the target handles this by emitting it
   // into a 'uniqued' section name, create and return the section now.
-  if (GV->isWeakForLinker() && !Kind.isCommon() && !Kind.isBSS()) {
-    const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
+  if ((GV->isWeakForLinker() || EmitUniquedSection) &&
+      !Kind.isCommon() && !Kind.isBSS()) {
+    const char* Prefix;
+    if (EmitUniquedSection && !GV->isWeakForLinker())
+      Prefix = getSectionPrefixForGlobal(Kind);
+    else //GV->isWeakForLinker()
+      Prefix = getSectionPrefixForUniqueGlobal(Kind);
+
     SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
     MCSymbol *Sym = Mang->getSymbol(GV);
     Name.append(Sym->getName().begin(), Sym->getName().end());


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] options -ffunction-sections and -fdata-sections

Chris Lattner

On Apr 7, 2010, at 3:25 PM, Sylvere Teissier wrote:

Anton Korobeynikov wrote:
Hello, Sylvere

 
Currently it works only for elf format backend, for other object formats
these options are ignored.
   
First of all, please honor the LLVM coding style (or, at least, the
code style of the source files you're modifying).
 
Ok, I have checked this point, I hope it's ok now
Second, I belive the approach used is wrong - there is already way to
emit objects into separate sections, which
is used for linkonce objects, you just need to hook in there. No need
to reinvent the wheel :)
 
Thanks for the tip, I've changed my patch using the existing code. But I use different section names than gnu.linkonce when It's not "WeakForLinker"
because gnu.linkonce.* are special sections. (I try to follow GCC section naming for -ffunction-sections/-fdata-sections)

Hi Sylvere,

I agree that they can't be happen with linkonce linkage... but this should be handled in the backend, not in the frontend.  TargetLoweringObjectFileELF::SelectSectionForGlobal is in charge of picking the section to use of a global, can you put this logic there?

-Chris

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] options -ffunction-sections and -fdata-sections

Sylvere Teissier
Chris Lattner a écrit :

>
> On Apr 7, 2010, at 3:25 PM, Sylvere Teissier wrote:
>
> Hi Sylvere,
>
> I agree that they can't be happen with linkonce linkage... but this
> should be handled in the backend, not in the frontend.
>  TargetLoweringObjectFileELF::SelectSectionForGlobal is in charge of
> picking the section to use of a global, can you put this logic there?
>
> -Chris

Hi Chris,

Perhaps I don't understand correctly your remark but that's what this
patch does: The function
TargetLoweringObjectFileELF::SelectSectionForGlobal is modified.

There are 2 patchs: 1 for llvm tree and 1 for clang tree.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] options -ffunction-sections and -fdata-sections

Chris Lattner

On Apr 8, 2010, at 1:43 AM, Sylvere Teissier wrote:

> Chris Lattner a écrit :
>>
>> On Apr 7, 2010, at 3:25 PM, Sylvere Teissier wrote:
>>
>> Hi Sylvere,
>>
>> I agree that they can't be happen with linkonce linkage... but this
>> should be handled in the backend, not in the frontend.
>> TargetLoweringObjectFileELF::SelectSectionForGlobal is in charge of
>> picking the section to use of a global, can you put this logic there?
>>
>> -Chris
>
> Hi Chris,
>
> Perhaps I don't understand correctly your remark but that's what this
> patch does: The function
> TargetLoweringObjectFileELF::SelectSectionForGlobal is modified.
>
> There are 2 patchs: 1 for llvm tree and 1 for clang tree.

Aha, I either wildly misread your patch or read an earlier one, sorry about that!

I applied your llvm patch here (with a few changes + testcase):
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20100412/099668.html

and your clang patch here:
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20100412/029278.html

Can you write a testcase for the clang part?

Thanks!

-Chris
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev