浏览代码

+ support for LLVM LTO: compile units with -CLflto -> when compiling a main
program/library also with -Clflto, all units compiled with that option
will be linked using their bitcode files and LTO
o compiling with -CLflto will compile all units twice: once for normal
(static or smart) linking, and once for LTO. So the result can be
used both with and without LTO.

git-svn-id: branches/debug_eh@41910 -

Jonas Maebe 6 年之前
父节点
当前提交
fc60ec2ea4

+ 17 - 8
compiler/assemble.pas

@@ -156,9 +156,12 @@ interface
         function single2str(d : single) : string; virtual;
         function single2str(d : single) : string; virtual;
         function double2str(d : double) : string; virtual;
         function double2str(d : double) : string; virtual;
         function extended2str(e : extended) : string; virtual;
         function extended2str(e : extended) : string; virtual;
-        Function DoPipe:boolean;
+        Function DoPipe:boolean; virtual;
 
 
         function CreateNewAsmWriter: TExternalAssemblerOutputFile; virtual;
         function CreateNewAsmWriter: TExternalAssemblerOutputFile; virtual;
+
+        {# Return true if the external assembler should run again }
+        function RerunAssembler: boolean; virtual;
       public
       public
 
 
         {# Returns the complete path and executable name of the assembler
         {# Returns the complete path and executable name of the assembler
@@ -878,7 +881,7 @@ Implementation
 
 
     Function TExternalAssembler.DoAssemble:boolean;
     Function TExternalAssembler.DoAssemble:boolean;
       begin
       begin
-        DoAssemble:=true;
+        result:=true;
         if DoPipe then
         if DoPipe then
          exit;
          exit;
         if not(cs_asm_extern in current_settings.globalswitches) then
         if not(cs_asm_extern in current_settings.globalswitches) then
@@ -892,13 +895,13 @@ Implementation
            Message1(exec_i_assembling,name);
            Message1(exec_i_assembling,name);
          end;
          end;
 
 
-        if CallAssembler(FindAssembler,MakeCmdLine) then
-         writer.RemoveAsm
+        repeat
+          result:=CallAssembler(FindAssembler,MakeCmdLine)
+        until not(result) or not RerunAssembler;
+        if result then
+          writer.RemoveAsm
         else
         else
-         begin
-            DoAssemble:=false;
-            GenerateError;
-         end;
+          GenerateError;
       end;
       end;
 
 
 
 
@@ -976,6 +979,12 @@ Implementation
       end;
       end;
 
 
 
 
+    function TExternalAssembler.RerunAssembler: boolean;
+      begin
+        result:=false;
+      end;
+
+
     procedure TExternalAssembler.WriteSourceLine(hp: tailineinfo);
     procedure TExternalAssembler.WriteSourceLine(hp: tailineinfo);
       var
       var
         module : tmodule;
         module : tmodule;

+ 1 - 0
compiler/globals.pas

@@ -399,6 +399,7 @@ interface
        defaultmainaliasname = 'main';
        defaultmainaliasname = 'main';
        mainaliasname : string = defaultmainaliasname;
        mainaliasname : string = defaultmainaliasname;
 
 
+      LTOExt: TCmdStr = '';
 
 
     const
     const
       default_settings : TSettings = (
       default_settings : TSettings = (

+ 4 - 1
compiler/globtype.pas

@@ -195,7 +195,9 @@ interface
          cs_huge_code,
          cs_huge_code,
          cs_win16_smartcallbacks,
          cs_win16_smartcallbacks,
          { Record usage of checkpointer experimental feature }
          { Record usage of checkpointer experimental feature }
-         cs_checkpointer_called
+         cs_checkpointer_called,
+         { enable link time optimisation (both unit code generation and optimising the whole program/library) }
+         cs_lto
        );
        );
        tmoduleswitches = set of tmoduleswitch;
        tmoduleswitches = set of tmoduleswitch;
 
 
@@ -797,6 +799,7 @@ interface
        link_static  = $2;
        link_static  = $2;
        link_smart   = $4;
        link_smart   = $4;
        link_shared  = $8;
        link_shared  = $8;
+       link_lto     = $10;
 
 
     type
     type
       { a message state }
       { a message state }

+ 64 - 56
compiler/link.pas

@@ -389,62 +389,70 @@ Implementation
             begin
             begin
               { create mask which unit files need linking }
               { create mask which unit files need linking }
               mask:=link_always;
               mask:=link_always;
-              { static linking ? }
-              if (cs_link_static in current_settings.globalswitches) then
-               begin
-                 if (headerflags and uf_static_linked)=0 then
-                  begin
-                    { if smart not avail then try static linking }
-                    if (headerflags and uf_smart_linked)<>0 then
-                     begin
-                       Message1(exec_t_unit_not_static_linkable_switch_to_smart,modulename^);
-                       mask:=mask or link_smart;
-                     end
-                    else
-                     Message1(exec_e_unit_not_smart_or_static_linkable,modulename^);
-                  end
-                 else
-                   mask:=mask or link_static;
-               end;
-              { smart linking ? }
-
-              if (cs_link_smart in current_settings.globalswitches) then
-               begin
-                 if (headerflags and uf_smart_linked)=0 then
-                  begin
-                    { if smart not avail then try static linking }
-                    if (headerflags and uf_static_linked)<>0 then
-                     begin
-                       { if not create_smartlink_library, then smart linking happens using the
-                         regular object files
-                       }
-                       if create_smartlink_library then
-                         Message1(exec_t_unit_not_smart_linkable_switch_to_static,modulename^);
-                       mask:=mask or link_static;
-                     end
-                    else
-                     Message1(exec_e_unit_not_smart_or_static_linkable,modulename^);
-                  end
-                 else
-                  mask:=mask or link_smart;
-               end;
-              { shared linking }
-              if (cs_link_shared in current_settings.globalswitches) then
-               begin
-                 if (headerflags and uf_shared_linked)=0 then
-                  begin
-                    { if shared not avail then try static linking }
-                    if (headerflags and uf_static_linked)<>0 then
-                     begin
-                       Message1(exec_t_unit_not_shared_linkable_switch_to_static,modulename^);
+              { lto linking ?}
+              if (cs_lto in current_settings.moduleswitches) and
+                 ((headerflags and uf_lto_linked)<>0) then
+                begin
+                  mask:=mask or link_lto;
+                end
+              else
+                begin
+                  { static linking ? }
+                  if (cs_link_static in current_settings.globalswitches) then
+                   begin
+                     if (headerflags and uf_static_linked)=0 then
+                      begin
+                        { if static not avail then try smart linking }
+                        if (headerflags and uf_smart_linked)<>0 then
+                         begin
+                           Message1(exec_t_unit_not_static_linkable_switch_to_smart,modulename^);
+                           mask:=mask or link_smart;
+                         end
+                        else
+                         Message1(exec_e_unit_not_smart_or_static_linkable,modulename^);
+                      end
+                     else
                        mask:=mask or link_static;
                        mask:=mask or link_static;
-                     end
-                    else
-                     Message1(exec_e_unit_not_shared_or_static_linkable,modulename^);
-                  end
-                 else
-                  mask:=mask or link_shared;
-               end;
+                   end;
+                  { smart linking ? }
+                  if (cs_link_smart in current_settings.globalswitches) then
+                   begin
+                     if (headerflags and uf_smart_linked)=0 then
+                      begin
+                        { if smart not avail then try static linking }
+                        if (headerflags and uf_static_linked)<>0 then
+                         begin
+                           { if not create_smartlink_library, then smart linking happens using the
+                             regular object files
+                           }
+                           if create_smartlink_library then
+                             Message1(exec_t_unit_not_smart_linkable_switch_to_static,modulename^);
+                           mask:=mask or link_static;
+                         end
+                        else
+                         Message1(exec_e_unit_not_smart_or_static_linkable,modulename^);
+                      end
+                     else
+                      mask:=mask or link_smart;
+                   end;
+                  { shared linking }
+                  if (cs_link_shared in current_settings.globalswitches) then
+                   begin
+                     if (headerflags and uf_shared_linked)=0 then
+                      begin
+                        { if shared not avail then try static linking }
+                        if (headerflags and uf_static_linked)<>0 then
+                         begin
+                           Message1(exec_t_unit_not_shared_linkable_switch_to_static,modulename^);
+                           mask:=mask or link_static;
+                         end
+                        else
+                         Message1(exec_e_unit_not_shared_or_static_linkable,modulename^);
+                      end
+                     else
+                      mask:=mask or link_shared;
+                   end;
+                end;
               { unit files }
               { unit files }
               while not linkunitofiles.empty do
               while not linkunitofiles.empty do
                 AddObject(linkunitofiles.getusemask(mask),path,true);
                 AddObject(linkunitofiles.getusemask(mask),path,true);
@@ -487,7 +495,7 @@ Implementation
 
 
     Procedure TLinker.AddObject(const S,unitpath : TPathStr;isunit:boolean);
     Procedure TLinker.AddObject(const S,unitpath : TPathStr;isunit:boolean);
       begin
       begin
-        ObjectFiles.Concat(FindObjectFile(s,unitpath,isunit));
+        ObjectFiles.Concat(FindObjectFile(s,unitpath,isunit))
       end;
       end;
 
 
 
 

+ 47 - 0
compiler/llvm/agllvm.pas

@@ -80,6 +80,12 @@ interface
       TLLVMClangAssember=class(TLLVMAssember)
       TLLVMClangAssember=class(TLLVMAssember)
       public
       public
        function MakeCmdLine: TCmdStr; override;
        function MakeCmdLine: TCmdStr; override;
+       function DoAssemble: boolean; override;
+       function RerunAssembler: boolean; override;
+      protected
+       function DoPipe: boolean; override;
+      private
+       fnextpass: byte;
       end;
       end;
 
 
 
 
@@ -1540,8 +1546,24 @@ implementation
 
 
     function TLLVMClangAssember.MakeCmdLine: TCmdStr;
     function TLLVMClangAssember.MakeCmdLine: TCmdStr;
       var
       var
+        wpostr,
         optstr: TCmdStr;
         optstr: TCmdStr;
       begin
       begin
+        wpostr:='';
+        if cs_lto in current_settings.moduleswitches then
+          begin
+            case fnextpass of
+              0:
+                begin
+                  ObjFileName:=ChangeFileExt(ObjFileName,'.bc');
+                  wpostr:=' -flto';
+                end;
+              1:
+                begin
+                  ObjFileName:=ChangeFileExt(ObjFileName,'.o');
+                end;
+            end;
+          end;
         result:=inherited;
         result:=inherited;
         { standard optimization flags for llc -- todo: this needs to be split
         { standard optimization flags for llc -- todo: this needs to be split
           into a call to opt and one to llc }
           into a call to opt and one to llc }
@@ -1553,6 +1575,7 @@ implementation
           optstr:='-O1'
           optstr:='-O1'
         else
         else
           optstr:='-O0';
           optstr:='-O0';
+        optstr:=optstr+wpostr;
         { stack frame elimination }
         { stack frame elimination }
         if not(cs_opt_stackframe in current_settings.optimizerswitches) then
         if not(cs_opt_stackframe in current_settings.optimizerswitches) then
           optstr:=optstr+' -fno-omit-frame-pointer'
           optstr:=optstr+' -fno-omit-frame-pointer'
@@ -1580,6 +1603,30 @@ implementation
           optstr:=optstr+' -m'+fputypestrllvm[current_settings.fputype];
           optstr:=optstr+' -m'+fputypestrllvm[current_settings.fputype];
 
 
         replace(result,'$OPT',optstr);
         replace(result,'$OPT',optstr);
+        inc(fnextpass);
+      end;
+
+
+    function TLLVMClangAssember.DoAssemble: boolean;
+      begin
+        fnextpass:=0;
+        result:=inherited;
+      end;
+
+
+    function TLLVMClangAssember.RerunAssembler: boolean;
+      begin
+        result:=
+          (cs_lto in current_settings.moduleswitches) and
+          (fnextpass<=1);
+      end;
+
+
+    function TLLVMClangAssember.DoPipe: boolean;
+      begin
+        result:=
+          not(cs_lto in current_settings.moduleswitches) and
+          inherited;
       end;
       end;
 
 
 
 

+ 1 - 0
compiler/msg/errore.msg

@@ -3842,6 +3842,7 @@ S*2Aas_Assemble using GNU AS
 **2Ci_IO-checking
 **2Ci_IO-checking
 A*2CI<x>_Select instruction set on ARM: ARM or THUMB
 A*2CI<x>_Select instruction set on ARM: ARM or THUMB
 L*2CL<x>_LLVM code generation options
 L*2CL<x>_LLVM code generation options
+L*3CLflto_Enable Link-time optimisation (needed both when compiling units and programs/libraries)
 L*3CLv<x>_LLVM target version: 3.3, 3.4, .., Xcode-6.4, .., Xcode-10.0, 7.0
 L*3CLv<x>_LLVM target version: 3.3, 3.4, .., Xcode-6.4, .., Xcode-10.0, 7.0
 **2Cn_Omit linking stage
 **2Cn_Omit linking stage
 P*2CN_Generate nil-pointer checks (AIX-only)
 P*2CN_Generate nil-pointer checks (AIX-only)

+ 1 - 1
compiler/msgidx.inc

@@ -1108,7 +1108,7 @@ const
   option_info=11024;
   option_info=11024;
   option_help_pages=11025;
   option_help_pages=11025;
 
 
-  MsgTxtSize = 83040;
+  MsgTxtSize = 83138;
 
 
   MsgIdxMax : array[1..20] of longint=(
   MsgIdxMax : array[1..20] of longint=(
     28,106,351,126,99,59,142,34,221,67,
     28,106,351,126,99,59,142,34,221,67,

+ 177 - 175
compiler/msgtxt.inc

@@ -1479,278 +1479,279 @@ const msgtxt : array[0..000346,1..240] of char=(
   '**2Ci_IO-checking'#010+
   '**2Ci_IO-checking'#010+
   'A*2CI<x>_Select instruction set on ARM: ARM or THUMB'#010+
   'A*2CI<x>_Select instruction set on ARM: ARM or THUMB'#010+
   'L*2CL<x>_LL','VM code generation options'#010+
   'L*2CL<x>_LL','VM code generation options'#010+
+  'L*3CLflto_Enable Link-time optimisation (needed both when compiling un'+
+  'its and programs/libraries)'#010+
   'L*3CLv<x>_LLVM target version: 3.3, 3.4, .., Xcode-6.4, .., Xcode-10.0'+
   'L*3CLv<x>_LLVM target version: 3.3, 3.4, .., Xcode-6.4, .., Xcode-10.0'+
   ', 7.0'#010+
   ', 7.0'#010+
   '**2Cn_Omit linking stage'#010+
   '**2Cn_Omit linking stage'#010+
-  'P*2CN_Generate nil-pointer checks (AIX-only)'#010+
+  'P*2CN_Generate',' nil-pointer checks (AIX-only)'#010+
   '**2Co_Check overflow of integer operations'#010+
   '**2Co_Check overflow of integer operations'#010+
-  '**2CO_Check for possible',' overflow of integer operations'#010+
+  '**2CO_Check for possible overflow of integer operations'#010+
   '**2Cp<x>_Select instruction set; see fpc -i or fpc -ic for possible va'+
   '**2Cp<x>_Select instruction set; see fpc -i or fpc -ic for possible va'+
   'lues'#010+
   'lues'#010+
   '**2CP<x>=<y>_ packing settings'#010+
   '**2CP<x>=<y>_ packing settings'#010+
-  '**3CPPACKSET=<y>_ <y> set allocation: 0, 1 or DEFAULT or NORMAL, 2, 4 '+
-  'and 8'#010+
-  '**3CPPACKENUM=<y>_ <y> enu','m packing: 0, 1, 2 and 4 or DEFAULT or NOR'+
-  'MAL'#010+
+  '**3C','PPACKSET=<y>_ <y> set allocation: 0, 1 or DEFAULT or NORMAL, 2, '+
+  '4 and 8'#010+
+  '**3CPPACKENUM=<y>_ <y> enum packing: 0, 1, 2 and 4 or DEFAULT or NORMA'+
+  'L'#010+
   '**3CPPACKRECORD=<y>_ <y> record packing: 0 or DEFAULT or NORMAL, 1, 2,'+
   '**3CPPACKRECORD=<y>_ <y> record packing: 0 or DEFAULT or NORMAL, 1, 2,'+
   ' 4, 8, 16 and 32'#010+
   ' 4, 8, 16 and 32'#010+
-  '**2Cr_Range checking'#010+
+  '**2Cr_Ran','ge checking'#010+
   '**2CR_Verify object method call validity'#010+
   '**2CR_Verify object method call validity'#010+
   '**2Cs<n>_Set stack checking size to <n>'#010+
   '**2Cs<n>_Set stack checking size to <n>'#010+
-  '**2Ct','_Stack checking (for testing only, see manual)'#010+
+  '**2Ct_Stack checking (for testing only, see manual)'#010+
   '8*2CT<x>_Target-specific code generation options'#010+
   '8*2CT<x>_Target-specific code generation options'#010+
-  '3*2CT<x>_Target-specific code generation options'#010+
+  '3*2CT<x>_Target-specific code generation optio','ns'#010+
   '4*2CT<x>_Target-specific code generation options'#010+
   '4*2CT<x>_Target-specific code generation options'#010+
-  'p*2CT<x>_Target-specific code generation optio','ns'#010+
+  'p*2CT<x>_Target-specific code generation options'#010+
   'P*2CT<x>_Target-specific code generation options'#010+
   'P*2CT<x>_Target-specific code generation options'#010+
   'J*2CT<x>_Target-specific code generation options'#010+
   'J*2CT<x>_Target-specific code generation options'#010+
-  'A*2CT<x>_Target-specific code generation options'#010+
+  'A*2CT<x>_Target-specific code generation ','options'#010+
   'p*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed'+
   'p*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed'+
   ' (AIX)'#010+
   ' (AIX)'#010+
-  'P*3CTsmalltoc','_ Generate smaller TOCs at the expense of execution spe'+
-  'ed (AIX)'#010+
+  'P*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed'+
+  ' (AIX)'#010+
   'J*3CTautogetterprefix=X_  Automatically create getters for properties '+
   'J*3CTautogetterprefix=X_  Automatically create getters for properties '+
+  'with pre','fix X (empty string disables)'#010+
+  'J*3CTautosetterprefix=X_  Automatically create setters for properties '+
   'with prefix X (empty string disables)'#010+
   'with prefix X (empty string disables)'#010+
-  'J*3CTautosetterprefix=X_  Automatically create setters for propertie','s'+
-  ' with prefix X (empty string disables)'#010+
   '8*3CTcld_                 Emit a CLD instruction before using the x86 '+
   '8*3CTcld_                 Emit a CLD instruction before using the x86 '+
   'string instructions'#010+
   'string instructions'#010+
-  '3*3CTcld_                 Emit a CLD instruction before using the x86 '+
-  'string instructions'#010+
-  '4*3CTcld_           ','      Emit a CLD instruction before using the x8'+
+  '3*3CTcld_   ','              Emit a CLD instruction before using the x8'+
   '6 string instructions'#010+
   '6 string instructions'#010+
+  '4*3CTcld_                 Emit a CLD instruction before using the x86 '+
+  'string instructions'#010+
   '8*3CTfarprocspushoddbp_       Increment BP before pushing it in the pr'+
   '8*3CTfarprocspushoddbp_       Increment BP before pushing it in the pr'+
-  'ologue of far functions'#010+
+  'ol','ogue of far functions'#010+
   'J*3CTcompactintarrayinit_ Generate smaller (but potentially slower) co'+
   'J*3CTcompactintarrayinit_ Generate smaller (but potentially slower) co'+
-  'de for',' initializing integer array constants'#010+
+  'de for initializing integer array constants'#010+
   'J*3CTenumfieldinit_       Initialize enumeration fields in constructor'+
   'J*3CTenumfieldinit_       Initialize enumeration fields in constructor'+
-  's to enumtype(0), after calling inherited constructors'#010+
+  's to enumtype(0), after calling in','herited constructors'#010+
   'J*3CTinitlocals_          Initialize local variables that trigger a JV'+
   'J*3CTinitlocals_          Initialize local variables that trigger a JV'+
-  'M bytec','ode verification error if used uninitialized (slows down code'+
-  ')'#010+
+  'M bytecode verification error if used uninitialized (slows down code)'#010+
   'J*3CTlowercaseprocstart_  Lowercase the first character of procedure/f'+
   'J*3CTlowercaseprocstart_  Lowercase the first character of procedure/f'+
-  'unction/method names'#010+
+  'unction/m','ethod names'#010+
   'A*3CTthumbinterworking_ Generate Thumb interworking-safe code if possi'+
   'A*3CTthumbinterworking_ Generate Thumb interworking-safe code if possi'+
   'ble'#010+
   'ble'#010+
-  'J*2Cv_Var/ou','t parameter copy-out checking'#010+
+  'J*2Cv_Var/out parameter copy-out checking'#010+
   '**2CX_Create also smartlinked library'#010+
   '**2CX_Create also smartlinked library'#010+
   '**1d<x>_Defines the symbol <x>'#010+
   '**1d<x>_Defines the symbol <x>'#010+
   '**1D_Generate a DEF file'#010+
   '**1D_Generate a DEF file'#010+
-  '**2Dd<x>_Set description to <x>'#010+
+  '**2Dd<x>_Set descr','iption to <x>'#010+
   '**2Dv<x>_Set DLL version to <x>'#010+
   '**2Dv<x>_Set DLL version to <x>'#010+
   '*O2Dw_PM application'#010+
   '*O2Dw_PM application'#010+
-  '**1e<x>_Set path to executable'#010,
+  '**1e<x>_Set path to executable'#010+
   '**1E_Same as -Cn'#010+
   '**1E_Same as -Cn'#010+
   '**1fPIC_Same as -Cg'#010+
   '**1fPIC_Same as -Cg'#010+
   '**1F<x>_Set file names and paths:'#010+
   '**1F<x>_Set file names and paths:'#010+
   '**2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is par'+
   '**2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is par'+
-  'sed'#010+
+  's','ed'#010+
   '**2Fc<x>_Set input codepage to <x>'#010+
   '**2Fc<x>_Set input codepage to <x>'#010+
   '**2FC<x>_Set RC compiler binary name to <x>'#010+
   '**2FC<x>_Set RC compiler binary name to <x>'#010+
-  '**2Fd_Disable th','e compiler'#039's internal directory cache'#010+
+  '**2Fd_Disable the compiler'#039's internal directory cache'#010+
   '**2FD<x>_Set the directory where to search for compiler utilities'#010+
   '**2FD<x>_Set the directory where to search for compiler utilities'#010+
-  '**2Fe<x>_Redirect error output to <x>'#010+
+  '**2Fe<x>_Redirect error output to <x>'#010,
   '**2Ff<x>_Add <x> to framework path (Darwin only)'#010+
   '**2Ff<x>_Add <x> to framework path (Darwin only)'#010+
   '**2FE<x>_Set exe/unit output path to <x>'#010+
   '**2FE<x>_Set exe/unit output path to <x>'#010+
-  '**2Fi<x>','_Add <x> to include path'#010+
+  '**2Fi<x>_Add <x> to include path'#010+
   '**2Fl<x>_Add <x> to library path'#010+
   '**2Fl<x>_Add <x> to library path'#010+
   '**2FL<x>_Use <x> as dynamic linker'#010+
   '**2FL<x>_Use <x> as dynamic linker'#010+
-  '**2Fm<x>_Load unicode conversion table from <x>.txt in the compiler di'+
-  'r'#010+
+  '**2Fm<x>_Load unicode conversion table from <x>.t','xt in the compiler '+
+  'dir'#010+
   '**2FM<x>_Set the directory where to search for unicode binary files'#010+
   '**2FM<x>_Set the directory where to search for unicode binary files'#010+
-  '**2FN<x','>_Add <x> to list of default unit scopes (namespaces)'#010+
+  '**2FN<x>_Add <x> to list of default unit scopes (namespaces)'#010+
   '**2Fo<x>_Add <x> to object path'#010+
   '**2Fo<x>_Add <x> to object path'#010+
   '**2Fr<x>_Load error message file <x>'#010+
   '**2Fr<x>_Load error message file <x>'#010+
-  '**2FR<x>_Set resource (.res) linker to <x>'#010+
+  '**2FR<x>_Set resour','ce (.res) linker to <x>'#010+
   '**2Fu<x>_Add <x> to unit path'#010+
   '**2Fu<x>_Add <x> to unit path'#010+
-  '**2FU<x>_Set unit output path to <x>, overri','des -FE'#010+
+  '**2FU<x>_Set unit output path to <x>, overrides -FE'#010+
   '**2FW<x>_Store generated whole-program optimization feedback in <x>'#010+
   '**2FW<x>_Store generated whole-program optimization feedback in <x>'#010+
-  '**2Fw<x>_Load previously stored whole-program optimization feedback fr'+
-  'om <x>'#010+
+  '**2Fw<x>_Load previously stored whole-program optimization feedbac','k '+
+  'from <x>'#010+
   '*g1g_Generate debug information (default format for target)'#010+
   '*g1g_Generate debug information (default format for target)'#010+
-  '*g2gc_Generate checks for p','ointers (experimental, only available on '+
-  'some targets, might generate false positive)'#010+
-  '*g2gh_Use heaptrace unit (for memory leak/corruption debugging)'#010+
+  '*g2gc_Generate checks for pointers (experimental, only available on so'+
+  'me targets, might generate false positive)'#010+
+  '*g2gh_Use heaptrace unit (for memory leak/corruption deb','ugging)'#010+
   '*g2gl_Use line info unit (show more info with backtraces)'#010+
   '*g2gl_Use line info unit (show more info with backtraces)'#010+
-  '*g2gm_Generate Microsoft CodeVie','w debug information (experimental)'#010+
+  '*g2gm_Generate Microsoft CodeView debug information (experimental)'#010+
   '*g2go<x>_Set debug information options'#010+
   '*g2go<x>_Set debug information options'#010+
   '*g3godwarfsets_ Enable DWARF '#039'set'#039' type debug information (bre'+
   '*g3godwarfsets_ Enable DWARF '#039'set'#039' type debug information (bre'+
-  'aks gdb < 6.5)'#010+
+  'aks gd','b < 6.5)'#010+
   '*g3gostabsabsincludes_ Store absolute/full include file paths in Stabs'+
   '*g3gostabsabsincludes_ Store absolute/full include file paths in Stabs'+
   #010+
   #010+
-  '*g3godwarfmethodcl','assprefix_ Prefix method names in DWARF with class'+
-  ' name'#010+
+  '*g3godwarfmethodclassprefix_ Prefix method names in DWARF with class n'+
+  'ame'#010+
   '*g3godwarfcpp_ Simulate C++ debug information in DWARF'#010+
   '*g3godwarfcpp_ Simulate C++ debug information in DWARF'#010+
-  '*g3godwarfomflinnum_ Generate line number information in OMF LINNUM re'+
-  'cords in MS LINK format in addition to the DWARF debug info','rmation ('+
+  '*g3godwarfomflinnum_ Generate l','ine number information in OMF LINNUM '+
+  'records in MS LINK format in addition to the DWARF debug information ('+
   'Open Watcom Debugger/Linker compatibility)'#010+
   'Open Watcom Debugger/Linker compatibility)'#010+
   '*g2gp_Preserve case in stabs symbol names'#010+
   '*g2gp_Preserve case in stabs symbol names'#010+
   '*g2gs_Generate Stabs debug information'#010+
   '*g2gs_Generate Stabs debug information'#010+
-  '*g2gt_Trash local variables (to detect uninitialized uses; multiple '#039+
-  't'#039' changes the trashing value)'#010+
-  '*g2gv_G','enerates programs traceable with Valgrind'#010+
+  '*g2gt_Tra','sh local variables (to detect uninitialized uses; multiple '+
+  #039't'#039' changes the trashing value)'#010+
+  '*g2gv_Generates programs traceable with Valgrind'#010+
   '*g2gw_Generate DWARFv2 debug information (same as -gw2)'#010+
   '*g2gw_Generate DWARFv2 debug information (same as -gw2)'#010+
   '*g2gw2_Generate DWARFv2 debug information'#010+
   '*g2gw2_Generate DWARFv2 debug information'#010+
-  '*g2gw3_Generate DWARFv3 debug information'#010+
+  '*g','2gw3_Generate DWARFv3 debug information'#010+
   '*g2gw4_Generate DWARFv4 debug information (experimental)'#010+
   '*g2gw4_Generate DWARFv4 debug information (experimental)'#010+
-  '*','*1i_Information'#010+
+  '**1i_Information'#010+
   '**2iD_Return compiler date'#010+
   '**2iD_Return compiler date'#010+
   '**2iSO_Return compiler OS'#010+
   '**2iSO_Return compiler OS'#010+
   '**2iSP_Return compiler host processor'#010+
   '**2iSP_Return compiler host processor'#010+
   '**2iTO_Return target OS'#010+
   '**2iTO_Return target OS'#010+
-  '**2iTP_Return target processor'#010+
+  '**2iTP_Retu','rn target processor'#010+
   '**2iV_Return short compiler version'#010+
   '**2iV_Return short compiler version'#010+
   '**2iW_Return full compiler version'#010+
   '**2iW_Return full compiler version'#010+
-  '**2ia_R','eturn list of supported ABI targets'#010+
+  '**2ia_Return list of supported ABI targets'#010+
   '**2ic_Return list of supported CPU instruction sets'#010+
   '**2ic_Return list of supported CPU instruction sets'#010+
   '**2if_Return list of supported FPU instruction sets'#010+
   '**2if_Return list of supported FPU instruction sets'#010+
-  '**2ii_Return list of supported inline assembler modes'#010+
+  '**','2ii_Return list of supported inline assembler modes'#010+
   '**2io_Return list of supported optimizations'#010+
   '**2io_Return list of supported optimizations'#010+
-  '*','*2ir_Return list of recognized compiler and RTL features'#010+
+  '**2ir_Return list of recognized compiler and RTL features'#010+
   '**2it_Return list of supported targets'#010+
   '**2it_Return list of supported targets'#010+
-  '**2iu_Return list of supported microcontroller types'#010+
+  '**2iu_Return list of supported microcontroller',' types'#010+
   '**2iw_Return list of supported whole program optimizations'#010+
   '**2iw_Return list of supported whole program optimizations'#010+
-  '**1I<x>_Add <x> to include path'#010,
+  '**1I<x>_Add <x> to include path'#010+
   '**1k<x>_Pass <x> to the linker'#010+
   '**1k<x>_Pass <x> to the linker'#010+
   '**1l_Write logo'#010+
   '**1l_Write logo'#010+
   '**1M<x>_Set language mode to <x>'#010+
   '**1M<x>_Set language mode to <x>'#010+
   '**2Mfpc_Free Pascal dialect (default)'#010+
   '**2Mfpc_Free Pascal dialect (default)'#010+
-  '**2Mobjfpc_FPC mode with Object Pascal support'#010+
+  '**2Mobjfpc_FPC mode with',' Object Pascal support'#010+
   '**2Mdelphi_Delphi 7 compatibility mode'#010+
   '**2Mdelphi_Delphi 7 compatibility mode'#010+
-  '**2Mtp_TP/BP 7.0 compatibility mode'#010,
+  '**2Mtp_TP/BP 7.0 compatibility mode'#010+
   '**2Mmacpas_Macintosh Pascal dialects compatibility mode'#010+
   '**2Mmacpas_Macintosh Pascal dialects compatibility mode'#010+
   '**2Miso_ISO 7185 mode'#010+
   '**2Miso_ISO 7185 mode'#010+
   '**2Mextendedpascal_ISO 10206 mode'#010+
   '**2Mextendedpascal_ISO 10206 mode'#010+
-  '**2Mdelphiunicode_Delphi 2009 and later compatibility mode'#010+
+  '**2Mdelphiunicode_Delphi 2009 ','and later compatibility mode'#010+
   '**1n_Do not read the default config files'#010+
   '**1n_Do not read the default config files'#010+
-  '**1o<x>_Change the name of ','the executable produced to <x>'#010+
+  '**1o<x>_Change the name of the executable produced to <x>'#010+
   '**1O<x>_Optimizations:'#010+
   '**1O<x>_Optimizations:'#010+
   '**2O-_Disable optimizations'#010+
   '**2O-_Disable optimizations'#010+
   '**2O1_Level 1 optimizations (quick and debugger friendly)'#010+
   '**2O1_Level 1 optimizations (quick and debugger friendly)'#010+
-  '**2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+
-  '**2O3_Level 3 optimizations (-O2 + slow opti','mizations)'#010+
+  '**','2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+
+  '**2O3_Level 3 optimizations (-O2 + slow optimizations)'#010+
   '**2O4_Level 4 optimizations (-O3 + optimizations which might have unex'+
   '**2O4_Level 4 optimizations (-O3 + optimizations which might have unex'+
   'pected side effects)'#010+
   'pected side effects)'#010+
   '**2Oa<x>=<y>_Set alignment'#010+
   '**2Oa<x>=<y>_Set alignment'#010+
-  '**2Oo[NO]<x>_Enable or disable optimizations; see fpc -i or fpc -io fo'+
-  'r possible values'#010+
-  '**2Op<x>_Set target cpu',' for optimizing; see fpc -i or fpc -ic for po'+
-  'ssible values'#010+
+  '**2Oo[NO]<x>_','Enable or disable optimizations; see fpc -i or fpc -io '+
+  'for possible values'#010+
+  '**2Op<x>_Set target cpu for optimizing; see fpc -i or fpc -ic for poss'+
+  'ible values'#010+
   '**2OW<x>_Generate whole-program optimization feedback for optimization'+
   '**2OW<x>_Generate whole-program optimization feedback for optimization'+
-  ' <x>; see fpc -i or fpc -iw for possible values'#010+
-  '**2Ow<x>_Perform whole-program optimization <x>; see fpc -i or ','fpc -'+
-  'iw for possible values'#010+
+  ' <x>; see fpc',' -i or fpc -iw for possible values'#010+
+  '**2Ow<x>_Perform whole-program optimization <x>; see fpc -i or fpc -iw'+
+  ' for possible values'#010+
   '**2Os_Optimize for size rather than speed'#010+
   '**2Os_Optimize for size rather than speed'#010+
   '**1pg_Generate profile code for gprof (defines FPC_PROFILE)'#010+
   '**1pg_Generate profile code for gprof (defines FPC_PROFILE)'#010+
-  'F*1P<x>_Target CPU / compiler related options:'#010+
+  'F*1P<x>_Targ','et CPU / compiler related options:'#010+
   'F*2PB_Show default compiler binary'#010+
   'F*2PB_Show default compiler binary'#010+
-  'F*2PP_Show default target cp','u'#010+
+  'F*2PP_Show default target cpu'#010+
   'F*2P<x>_Set target CPU (aarch64,arm,avr,i386,i8086,jvm,m68k,mips,mipse'+
   'F*2P<x>_Set target CPU (aarch64,arm,avr,i386,i8086,jvm,m68k,mips,mipse'+
   'l,powerpc,powerpc64,sparc,x86_64)'#010+
   'l,powerpc,powerpc64,sparc,x86_64)'#010+
   '**1R<x>_Assembler reading style:'#010+
   '**1R<x>_Assembler reading style:'#010+
-  '**2Rdefault_Use default assembler for target'#010+
+  '**2','Rdefault_Use default assembler for target'#010+
   '3*2Ratt_Read AT&T style assembler'#010+
   '3*2Ratt_Read AT&T style assembler'#010+
-  '3*2Rintel_Read Intel s','tyle assembler'#010+
+  '3*2Rintel_Read Intel style assembler'#010+
   '4*2Ratt_Read AT&T style assembler'#010+
   '4*2Ratt_Read AT&T style assembler'#010+
   '4*2Rintel_Read Intel style assembler'#010+
   '4*2Rintel_Read Intel style assembler'#010+
   '8*2Ratt_Read AT&T style assembler'#010+
   '8*2Ratt_Read AT&T style assembler'#010+
-  '8*2Rintel_Read Intel style assembler'#010+
+  '8*2Rintel_Read Intel s','tyle assembler'#010+
   '6*2RMOT_Read Motorola style assembler'#010+
   '6*2RMOT_Read Motorola style assembler'#010+
   '**1S<x>_Syntax options:'#010+
   '**1S<x>_Syntax options:'#010+
-  '**2S2_Same as -Mobjfp','c'#010+
+  '**2S2_Same as -Mobjfpc'#010+
   '**2Sc_Support operators like C (*=,+=,/= and -=)'#010+
   '**2Sc_Support operators like C (*=,+=,/= and -=)'#010+
   '**2Sa_Turn on assertions'#010+
   '**2Sa_Turn on assertions'#010+
   '**2Sd_Same as -Mdelphi'#010+
   '**2Sd_Same as -Mdelphi'#010+
-  '**2Se<x>_Error options. <x> is a combination of the following:'#010+
+  '**2Se<x>_Error options. <x> is a combinatio','n of the following:'#010+
   '**3*_<n> : Compiler halts after the <n> errors (default is 1)'#010+
   '**3*_<n> : Compiler halts after the <n> errors (default is 1)'#010+
-  '**3*_w : Compile','r also halts after warnings'#010+
+  '**3*_w : Compiler also halts after warnings'#010+
   '**3*_n : Compiler also halts after notes'#010+
   '**3*_n : Compiler also halts after notes'#010+
   '**3*_h : Compiler also halts after hints'#010+
   '**3*_h : Compiler also halts after hints'#010+
-  '**2Sf_Enable certain features in compiler and RTL; see fpc -i or fpc -'+
-  'ir for possible values)'#010+
-  '**2Sg_Enable LABEL and GOTO (default',' in -Mtp and -Mdelphi)'#010+
+  '**2Sf_Enable certain features in',' compiler and RTL; see fpc -i or fpc'+
+  ' -ir for possible values)'#010+
+  '**2Sg_Enable LABEL and GOTO (default in -Mtp and -Mdelphi)'#010+
   '**2Sh_Use reference counted strings (ansistring by default) instead of'+
   '**2Sh_Use reference counted strings (ansistring by default) instead of'+
   ' shortstrings'#010+
   ' shortstrings'#010+
-  '**2Si_Turn on inlining of procedures/functions declared as "inline"'#010+
-  '**2Sj_Allows typed constants to be writeable (default in all mode','s)'#010+
+  '**2Si_Turn on inlining of procedure','s/functions declared as "inline"'#010+
+  '**2Sj_Allows typed constants to be writeable (default in all modes)'#010+
   '**2Sk_Load fpcylix unit'#010+
   '**2Sk_Load fpcylix unit'#010+
   '**2SI<x>_Set interface style to <x>'#010+
   '**2SI<x>_Set interface style to <x>'#010+
   '**3SIcom_COM compatible interface (default)'#010+
   '**3SIcom_COM compatible interface (default)'#010+
-  '**3SIcorba_CORBA compatible interface'#010+
+  '**3SIcorba_CORBA compatible interfa','ce'#010+
   '**2Sm_Support macros like C (global)'#010+
   '**2Sm_Support macros like C (global)'#010+
   '**2So_Same as -Mtp'#010+
   '**2So_Same as -Mtp'#010+
-  '**2Sr_Transparent file names in ISO mod','e'#010+
+  '**2Sr_Transparent file names in ISO mode'#010+
   '**2Ss_Constructor name must be init (destructor must be done)'#010+
   '**2Ss_Constructor name must be init (destructor must be done)'#010+
   '**2Sv_Support vector processing (use CPU vector extensions if availabl'+
   '**2Sv_Support vector processing (use CPU vector extensions if availabl'+
   'e)'#010+
   'e)'#010+
-  '**2Sx_Enable exception keywords (default in Delphi/ObjFPC modes)'#010+
-  '**2Sy_@<pointer> returns a typed point','er, same as $T+'#010+
+  '**2Sx','_Enable exception keywords (default in Delphi/ObjFPC modes)'#010+
+  '**2Sy_@<pointer> returns a typed pointer, same as $T+'#010+
   '**1s_Do not call assembler and linker'#010+
   '**1s_Do not call assembler and linker'#010+
   '**2sh_Generate script to link on host'#010+
   '**2sh_Generate script to link on host'#010+
   '**2st_Generate script to link on target'#010+
   '**2st_Generate script to link on target'#010+
-  '**2sr_Skip register allocation phase (use with -alr)'#010+
+  '**2sr_Skip',' register allocation phase (use with -alr)'#010+
   '**1T<x>_Target operating system:'#010+
   '**1T<x>_Target operating system:'#010+
   '3*2Tandroid_Android'#010+
   '3*2Tandroid_Android'#010+
-  '3*','2Taros_AROS'#010+
+  '3*2Taros_AROS'#010+
   '3*2Tbeos_BeOS'#010+
   '3*2Tbeos_BeOS'#010+
   '3*2Tdarwin_Darwin/Mac OS X'#010+
   '3*2Tdarwin_Darwin/Mac OS X'#010+
   '3*2Tembedded_Embedded'#010+
   '3*2Tembedded_Embedded'#010+
   '3*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+
   '3*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+
-  '3*2Tfreebsd_FreeBSD'#010+
+  '3*2Tfreebsd_FreeB','SD'#010+
   '3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+
   '3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+
   '3*2Thaiku_Haiku'#010+
   '3*2Thaiku_Haiku'#010+
-  '3*2Tiphonesim_iPhoneSimulator f','rom iOS SDK 3.2+ (older versions: -Td'+
-  'arwin)'#010+
+  '3*2Tiphonesim_iPhoneSimulator from iOS SDK 3.2+ (older versions: -Tdar'+
+  'win)'#010+
   '3*2Tlinux_Linux'#010+
   '3*2Tlinux_Linux'#010+
   '3*2Tnativent_Native NT API (experimental)'#010+
   '3*2Tnativent_Native NT API (experimental)'#010+
   '3*2Tnetbsd_NetBSD'#010+
   '3*2Tnetbsd_NetBSD'#010+
-  '3*2Tnetware_Novell Netware Module (clib)'#010+
+  '3*2Tnetware_Novell Net','ware Module (clib)'#010+
   '3*2Tnetwlibc_Novell Netware Module (libc)'#010+
   '3*2Tnetwlibc_Novell Netware Module (libc)'#010+
   '3*2Topenbsd_OpenBSD'#010+
   '3*2Topenbsd_OpenBSD'#010+
-  '3*2Tos2_OS/2 / eC','omStation'#010+
+  '3*2Tos2_OS/2 / eComStation'#010+
   '3*2Tsymbian_Symbian OS'#010+
   '3*2Tsymbian_Symbian OS'#010+
   '3*2Tsolaris_Solaris'#010+
   '3*2Tsolaris_Solaris'#010+
   '3*2Twatcom_Watcom compatible DOS extender'#010+
   '3*2Twatcom_Watcom compatible DOS extender'#010+
   '3*2Twdosx_WDOSX DOS extender'#010+
   '3*2Twdosx_WDOSX DOS extender'#010+
-  '3*2Twin32_Windows 32 Bit'#010+
+  '3*2Twin32_Windows ','32 Bit'#010+
   '3*2Twince_Windows CE'#010+
   '3*2Twince_Windows CE'#010+
   '4*2Taros_AROS'#010+
   '4*2Taros_AROS'#010+
   '4*2Tdarwin_Darwin/Mac OS X'#010+
   '4*2Tdarwin_Darwin/Mac OS X'#010+
   '4*2Tdragonfly_DragonFly BSD'#010+
   '4*2Tdragonfly_DragonFly BSD'#010+
-  '4','*2Tembedded_Embedded'#010+
+  '4*2Tembedded_Embedded'#010+
   '4*2Tfreebsd_FreeBSD'#010+
   '4*2Tfreebsd_FreeBSD'#010+
   '4*2Tiphonesim_iPhoneSimulator'#010+
   '4*2Tiphonesim_iPhoneSimulator'#010+
   '4*2Tlinux_Linux'#010+
   '4*2Tlinux_Linux'#010+
   '4*2Tnetbsd_NetBSD'#010+
   '4*2Tnetbsd_NetBSD'#010+
   '4*2Topenbsd_OpenBSD'#010+
   '4*2Topenbsd_OpenBSD'#010+
-  '4*2Tsolaris_Solaris'#010+
+  '4*2Tsolaris_Solar','is'#010+
   '4*2Twin64_Win64 (64 bit Windows systems)'#010+
   '4*2Twin64_Win64 (64 bit Windows systems)'#010+
   '6*2Tamiga_Commodore Amiga'#010+
   '6*2Tamiga_Commodore Amiga'#010+
   '6*2Tatari_Atari ST/STe/TT'#010+
   '6*2Tatari_Atari ST/STe/TT'#010+
-  '6*','2Tembedded_Embedded'#010+
+  '6*2Tembedded_Embedded'#010+
   '6*2Tlinux_Linux'#010+
   '6*2Tlinux_Linux'#010+
   '6*2Tnetbsd_NetBSD'#010+
   '6*2Tnetbsd_NetBSD'#010+
   '6*2Tmacos_Mac OS'#010+
   '6*2Tmacos_Mac OS'#010+
   '6*2Tpalmos_PalmOS'#010+
   '6*2Tpalmos_PalmOS'#010+
   '8*2Tembedded_Embedded'#010+
   '8*2Tembedded_Embedded'#010+
-  '8*2Tmsdos_MS-DOS (and compatible)'#010+
+  '8*2Tmsdos_MS-DOS (and compatibl','e)'#010+
   '8*2Twin16_Windows 16 Bit'#010+
   '8*2Twin16_Windows 16 Bit'#010+
   'A*2Tandroid_Android'#010+
   'A*2Tandroid_Android'#010+
   'A*2Taros_AROS'#010+
   'A*2Taros_AROS'#010+
   'A*2Tdarwin_Darwin/iPhoneOS/iOS'#010+
   'A*2Tdarwin_Darwin/iPhoneOS/iOS'#010+
-  'A*2Te','mbedded_Embedded'#010+
+  'A*2Tembedded_Embedded'#010+
   'A*2Tgba_Game Boy Advance'#010+
   'A*2Tgba_Game Boy Advance'#010+
   'A*2Tlinux_Linux'#010+
   'A*2Tlinux_Linux'#010+
   'A*2Tnds_Nintendo DS'#010+
   'A*2Tnds_Nintendo DS'#010+
   'A*2Tnetbsd_NetBSD'#010+
   'A*2Tnetbsd_NetBSD'#010+
   'A*2Tpalmos_PalmOS'#010+
   'A*2Tpalmos_PalmOS'#010+
   'A*2Tsymbian_Symbian'#010+
   'A*2Tsymbian_Symbian'#010+
-  'A*2Twince_Windows CE'#010+
+  'A*2Twinc','e_Windows CE'#010+
   'a*2Tdarwin_Darwin/iOS'#010+
   'a*2Tdarwin_Darwin/iOS'#010+
   'a*2Tlinux_Linux'#010+
   'a*2Tlinux_Linux'#010+
   'J*2Tandroid_Android'#010+
   'J*2Tandroid_Android'#010+
   'J*2Tjava_Java'#010+
   'J*2Tjava_Java'#010+
-  'm*2Tandroid_A','ndroid'#010+
+  'm*2Tandroid_Android'#010+
   'm*2Tembedded_Embedded'#010+
   'm*2Tembedded_Embedded'#010+
   'm*2Tlinux_Linux'#010+
   'm*2Tlinux_Linux'#010+
   'M*2Tembedded_Embedded'#010+
   'M*2Tembedded_Embedded'#010+
@@ -1758,11 +1759,11 @@ const msgtxt : array[0..000346,1..240] of char=(
   'P*2Taix_AIX'#010+
   'P*2Taix_AIX'#010+
   'P*2Tamiga_AmigaOS'#010+
   'P*2Tamiga_AmigaOS'#010+
   'P*2Tdarwin_Darwin/Mac OS X'#010+
   'P*2Tdarwin_Darwin/Mac OS X'#010+
-  'P*2Tembedded_Embedded'#010+
+  'P*','2Tembedded_Embedded'#010+
   'P*2Tlinux_Linux'#010+
   'P*2Tlinux_Linux'#010+
   'P*2Tmacos_Mac OS (classic)'#010+
   'P*2Tmacos_Mac OS (classic)'#010+
   'P*2Tmorphos_MorphOS'#010+
   'P*2Tmorphos_MorphOS'#010+
-  'P*2Tnetbsd_NetB','SD'#010+
+  'P*2Tnetbsd_NetBSD'#010+
   'P*2Twii_Wii'#010+
   'P*2Twii_Wii'#010+
   'p*2Taix_AIX'#010+
   'p*2Taix_AIX'#010+
   'p*2Tdarwin_Darwin/Mac OS X'#010+
   'p*2Tdarwin_Darwin/Mac OS X'#010+
@@ -1770,151 +1771,152 @@ const msgtxt : array[0..000346,1..240] of char=(
   'p*2Tlinux_Linux'#010+
   'p*2Tlinux_Linux'#010+
   'R*2Tlinux_Linux'#010+
   'R*2Tlinux_Linux'#010+
   'R*2Tembedded_Embedded'#010+
   'R*2Tembedded_Embedded'#010+
-  'r*2Tlinux_Linux'#010+
+  'r*2Tlinux_Li','nux'#010+
   'r*2Tembedded_Embedded'#010+
   'r*2Tembedded_Embedded'#010+
   'S*2Tlinux_Linux'#010+
   'S*2Tlinux_Linux'#010+
   'S*2Tsolaris_Solaris'#010+
   'S*2Tsolaris_Solaris'#010+
   's*2Tlinux_Linux'#010+
   's*2Tlinux_Linux'#010+
-  'V*2Tembedded_Embedde','d'#010+
+  'V*2Tembedded_Embedded'#010+
   '**1u<x>_Undefines the symbol <x>'#010+
   '**1u<x>_Undefines the symbol <x>'#010+
   '**1U_Unit options:'#010+
   '**1U_Unit options:'#010+
   '**2Un_Do not check where the unit name matches the file name'#010+
   '**2Un_Do not check where the unit name matches the file name'#010+
-  '**2Ur_Generate release unit files (never automatically recompiled)'#010+
+  '**2Ur_Generate release unit',' files (never automatically recompiled)'#010+
   '**2Us_Compile a system unit'#010+
   '**2Us_Compile a system unit'#010+
-  '**1v<x>_Be verbose. <x> is a c','ombination of the following letters:'#010+
+  '**1v<x>_Be verbose. <x> is a combination of the following letters:'#010+
   '**2*_e : Show errors (default)       0 : Show nothing (except errors)'#010+
   '**2*_e : Show errors (default)       0 : Show nothing (except errors)'#010+
-  '**2*_w : Show warnings               u : Show unit info'#010+
+  '**2*_w : Show warnings             ','  u : Show unit info'#010+
   '**2*_n : Show notes                  t : Show tried/used files'#010+
   '**2*_n : Show notes                  t : Show tried/used files'#010+
-  '**2*_h : Show ','hints                  c : Show conditionals'#010+
+  '**2*_h : Show hints                  c : Show conditionals'#010+
   '**2*_i : Show general info           d : Show debug info'#010+
   '**2*_i : Show general info           d : Show debug info'#010+
-  '**2*_l : Show linenumbers            r : Rhide/GCC compatibility mode'#010+
+  '**2*_l : Show linenumbers            r :',' Rhide/GCC compatibility mod'+
+  'e'#010+
   '**2*_s : Show time stamps            q : Show message numbers'#010+
   '**2*_s : Show time stamps            q : Show message numbers'#010+
-  '**2*_a',' : Show everything             x : Show info about invoked too'+
-  'ls'#010+
+  '**2*_a : Show everything             x : Show info about invoked tools'+
+  #010+
   '**2*_b : Write file names messages   p : Write tree.log with parse tre'+
   '**2*_b : Write file names messages   p : Write tree.log with parse tre'+
   'e'#010+
   'e'#010+
-  '**2*_    with full path              v : Write fpcdebug.txt with'#010+
-  '**2*_z : Write output to stderr       ','   lots of debugging info'#010+
+  '**2*_','    with full path              v : Write fpcdebug.txt with'#010+
+  '**2*_z : Write output to stderr          lots of debugging info'#010+
   '**2*_m<x>,<y> : Do not show messages numbered <x> and <y>'#010+
   '**2*_m<x>,<y> : Do not show messages numbered <x> and <y>'#010+
-  'F*1V<x>_Append '#039'-<x>'#039' to the used compiler binary name (e.g. f'+
-  'or version)'#010+
+  'F*1V<x>_Append '#039'-<x>'#039' to the used compiler binary name (e.','g.'+
+  ' for version)'#010+
   '**1W<x>_Target-specific options (targets)'#010+
   '**1W<x>_Target-specific options (targets)'#010+
-  '3*2WA_Specify native type application (W','indows)'#010+
+  '3*2WA_Specify native type application (Windows)'#010+
   '4*2WA_Specify native type application (Windows)'#010+
   '4*2WA_Specify native type application (Windows)'#010+
   'A*2WA_Specify native type application (Windows)'#010+
   'A*2WA_Specify native type application (Windows)'#010+
-  '3*2Wb_Create a bundle instead of a library (Darwin)'#010+
+  '3*2Wb_Create a bundle instead of a lib','rary (Darwin)'#010+
   'P*2Wb_Create a bundle instead of a library (Darwin)'#010+
   'P*2Wb_Create a bundle instead of a library (Darwin)'#010+
-  'p*2Wb_Create a bundle instead of',' a library (Darwin)'#010+
+  'p*2Wb_Create a bundle instead of a library (Darwin)'#010+
   'a*2Wb_Create a bundle instead of a library (Darwin)'#010+
   'a*2Wb_Create a bundle instead of a library (Darwin)'#010+
   'A*2Wb_Create a bundle instead of a library (Darwin)'#010+
   'A*2Wb_Create a bundle instead of a library (Darwin)'#010+
-  '4*2Wb_Create a bundle instead of a library (Darwin)'#010+
+  '4*2Wb_Create a bun','dle instead of a library (Darwin)'#010+
   '3*2WB_Create a relocatable image (Windows, Symbian)'#010+
   '3*2WB_Create a relocatable image (Windows, Symbian)'#010+
-  '3*2WB<x>_Set',' image base to <x> (Windows, Symbian)'#010+
+  '3*2WB<x>_Set image base to <x> (Windows, Symbian)'#010+
   '4*2WB_Create a relocatable image (Windows)'#010+
   '4*2WB_Create a relocatable image (Windows)'#010+
   '4*2WB<x>_Set image base to <x> (Windows)'#010+
   '4*2WB<x>_Set image base to <x> (Windows)'#010+
-  'A*2WB_Create a relocatable image (Windows, Symbian)'#010+
+  'A*2WB_Create a reloc','atable image (Windows, Symbian)'#010+
   'A*2WB<x>_Set image base to <x> (Windows, Symbian)'#010+
   'A*2WB<x>_Set image base to <x> (Windows, Symbian)'#010+
-  '3*2WC_Specify co','nsole type application (EMX, OS/2, Windows)'#010+
+  '3*2WC_Specify console type application (EMX, OS/2, Windows)'#010+
   '4*2WC_Specify console type application (Windows)'#010+
   '4*2WC_Specify console type application (Windows)'#010+
-  'A*2WC_Specify console type application (Windows)'#010+
+  'A*2WC_Specify console type application (Windows)'#010,
   'P*2WC_Specify console type application (Classic Mac OS)'#010+
   'P*2WC_Specify console type application (Classic Mac OS)'#010+
-  '3*2WD_Use DEFFILE to export functions of D','LL or EXE (Windows)'#010+
+  '3*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
   '4*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
   '4*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
-  'A*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
+  'A*2WD_Use DEFFILE to export functions of DLL or EXE (Windows',')'#010+
   '3*2We_Use external resources (Darwin)'#010+
   '3*2We_Use external resources (Darwin)'#010+
   '4*2We_Use external resources (Darwin)'#010+
   '4*2We_Use external resources (Darwin)'#010+
-  'a*2We_Use external r','esources (Darwin)'#010+
+  'a*2We_Use external resources (Darwin)'#010+
   'A*2We_Use external resources (Darwin)'#010+
   'A*2We_Use external resources (Darwin)'#010+
   'P*2We_Use external resources (Darwin)'#010+
   'P*2We_Use external resources (Darwin)'#010+
   'p*2We_Use external resources (Darwin)'#010+
   'p*2We_Use external resources (Darwin)'#010+
-  '3*2WF_Specify full-screen type application (EMX, OS/2)'#010+
-  '3*2WG_Specify graphic type application (EMX, OS/2, Wi','ndows)'#010+
+  '3*2WF_Spec','ify full-screen type application (EMX, OS/2)'#010+
+  '3*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+
   '4*2WG_Specify graphic type application (Windows)'#010+
   '4*2WG_Specify graphic type application (Windows)'#010+
   'A*2WG_Specify graphic type application (Windows)'#010+
   'A*2WG_Specify graphic type application (Windows)'#010+
-  'P*2WG_Specify graphic type application (Classic Mac OS)'#010+
+  'P*2WG_Specify graphic type applicatio','n (Classic Mac OS)'#010+
   '3*2Wi_Use internal resources (Darwin)'#010+
   '3*2Wi_Use internal resources (Darwin)'#010+
   '4*2Wi_Use internal resources (Darwin)'#010+
   '4*2Wi_Use internal resources (Darwin)'#010+
-  'a*2','Wi_Use internal resources (Darwin)'#010+
+  'a*2Wi_Use internal resources (Darwin)'#010+
   'A*2Wi_Use internal resources (Darwin)'#010+
   'A*2Wi_Use internal resources (Darwin)'#010+
   'P*2Wi_Use internal resources (Darwin)'#010+
   'P*2Wi_Use internal resources (Darwin)'#010+
-  'p*2Wi_Use internal resources (Darwin)'#010+
+  'p*2Wi_Use internal resources (D','arwin)'#010+
   '3*2WI_Turn on/off the usage of import sections (Windows)'#010+
   '3*2WI_Turn on/off the usage of import sections (Windows)'#010+
-  '4*2WI_Turn on/off the usage of imp','ort sections (Windows)'#010+
+  '4*2WI_Turn on/off the usage of import sections (Windows)'#010+
   'A*2WI_Turn on/off the usage of import sections (Windows)'#010+
   'A*2WI_Turn on/off the usage of import sections (Windows)'#010+
-  '8*2Wh_Use huge code for units (ignored for models with CODE in a uniqu'+
-  'e segment)'#010+
+  '8*2Wh_Use huge code for units (ignored for models with CODE in',' a uni'+
+  'que segment)'#010+
   '8*2Wm<x>_Set memory model'#010+
   '8*2Wm<x>_Set memory model'#010+
   '8*3WmTiny_Tiny memory model'#010+
   '8*3WmTiny_Tiny memory model'#010+
-  '8*3WmSmall_Small memory m','odel (default)'#010+
+  '8*3WmSmall_Small memory model (default)'#010+
   '8*3WmMedium_Medium memory model'#010+
   '8*3WmMedium_Medium memory model'#010+
   '8*3WmCompact_Compact memory model'#010+
   '8*3WmCompact_Compact memory model'#010+
   '8*3WmLarge_Large memory model'#010+
   '8*3WmLarge_Large memory model'#010+
   '8*3WmHuge_Huge memory model'#010+
   '8*3WmHuge_Huge memory model'#010+
-  '3*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
-  'n)'#010+
-  '4*2WM<x>_Minimum Mac OS X de','ployment version: 10.4, 10.5.1, ... (Dar'+
+  '3*2','WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Dar'+
   'win)'#010+
   'win)'#010+
-  'p*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
+  '4*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
   'n)'#010+
   'n)'#010+
-  'P*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
+  'p*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
   'n)'#010+
   'n)'#010+
-  '3*2WN_Do not generate relocation code, needed for',' debugging (Windows'+
-  ')'#010+
+  'P*2WM<x>_Minimum Mac OS ','X deployment version: 10.4, 10.5.1, ... (Dar'+
+  'win)'#010+
+  '3*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
   '4*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
   '4*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
-  'A*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
+  'A*2WN_Do not generate relocation code, needed for d','ebugging (Windows'+
+  ')'#010+
   'A*2Wp<x>_Specify the controller type; see fpc -i or fpc -iu for possib'+
   'A*2Wp<x>_Specify the controller type; see fpc -i or fpc -iu for possib'+
-  'le values',#010+
-  'm*2Wp<x>_Specify the controller type; see fpc -i or fpc -iu for possib'+
   'le values'#010+
   'le values'#010+
-  'V*2Wp<x>_Specify the controller type; see fpc -i or fpc -iu for possib'+
+  'm*2Wp<x>_Specify the controller type; see fpc -i or fpc -iu for possib'+
   'le values'#010+
   'le values'#010+
+  'V*2Wp<x>_Specify the controller type; see fpc -i or fpc -iu f','or poss'+
+  'ible values'#010+
   '3*2WP<x>_Minimum iOS deployment version: 3.0, 5.0.1, ... (iphonesim)'#010+
   '3*2WP<x>_Minimum iOS deployment version: 3.0, 5.0.1, ... (iphonesim)'#010+
-  '4*2WP<x>_M','inimum iOS deployment version: 8.0, 8.0.2, ... (iphonesim)'+
-  #010+
+  '4*2WP<x>_Minimum iOS deployment version: 8.0, 8.0.2, ... (iphonesim)'#010+
   'a*2WP<x>_Minimum iOS deployment version: 7.0, 7.1.2, ... (Darwin)'#010+
   'a*2WP<x>_Minimum iOS deployment version: 7.0, 7.1.2, ... (Darwin)'#010+
-  'A*2WP<x>_Minimum iOS deployment version: 3.0, 5.0.1, ... (Darwin)'#010+
+  'A*2WP<x>_Minimum ','iOS deployment version: 3.0, 5.0.1, ... (Darwin)'#010+
   '3*2WR_Generate relocation code (Windows)'#010+
   '3*2WR_Generate relocation code (Windows)'#010+
-  '4*2WR_Ge','nerate relocation code (Windows)'#010+
+  '4*2WR_Generate relocation code (Windows)'#010+
   'A*2WR_Generate relocation code (Windows)'#010+
   'A*2WR_Generate relocation code (Windows)'#010+
   '8*2Wt<x>_Set the target executable format'#010+
   '8*2Wt<x>_Set the target executable format'#010+
-  '8*3Wtexe_Create a DOS .EXE file (default)'#010+
+  '8*3Wtexe_Create a DOS .EXE',' file (default)'#010+
   '8*3Wtcom_Create a DOS .COM file (requires tiny memory model)'#010+
   '8*3Wtcom_Create a DOS .COM file (requires tiny memory model)'#010+
-  'P*2WT_Specify MPW too','l type application (Classic Mac OS)'#010+
+  'P*2WT_Specify MPW tool type application (Classic Mac OS)'#010+
   '**2WX_Enable executable stack (Linux)'#010+
   '**2WX_Enable executable stack (Linux)'#010+
   '**1X_Executable options:'#010+
   '**1X_Executable options:'#010+
-  '**2X9_Generate linkerscript for GNU Binutils ld older than version 2.1'+
-  '9.1 (Linux)'#010+
-  '**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, F','reeBSD, L'+
-  'inux)'#010+
+  '**2X9_Generate linkerscript for GNU Binutil','s ld older than version 2'+
+  '.19.1 (Linux)'#010+
+  '**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, Lin'+
+  'ux)'#010+
   '**2Xd_Do not search default library path (sometimes required for cross'+
   '**2Xd_Do not search default library path (sometimes required for cross'+
   '-compiling when not using -XR)'#010+
   '-compiling when not using -XR)'#010+
-  '**2Xe_Use external linker'#010+
+  '**2Xe_Use external linker'#010,
   '**2Xf_Substitute pthread library name for linking (BSD)'#010+
   '**2Xf_Substitute pthread library name for linking (BSD)'#010+
-  '**2Xg_Create debuginfo in a separate file ','and add a debuglink sectio'+
-  'n to executable'#010+
+  '**2Xg_Create debuginfo in a separate file and add a debuglink section '+
+  'to executable'#010+
   '**2XD_Try to link units dynamically      (defines FPC_LINK_DYNAMIC)'#010+
   '**2XD_Try to link units dynamically      (defines FPC_LINK_DYNAMIC)'#010+
   '**2Xi_Use internal linker'#010+
   '**2Xi_Use internal linker'#010+
-  '**2XLA_Define library substitutions for linking'#010+
+  '**2XLA','_Define library substitutions for linking'#010+
   '**2XLO_Define order of library linking'#010+
   '**2XLO_Define order of library linking'#010+
-  '**2XLD_Exclude de','fault order of standard libraries'#010+
+  '**2XLD_Exclude default order of standard libraries'#010+
   '**2Xm_Generate link map'#010+
   '**2Xm_Generate link map'#010+
   '**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
   '**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
   's '#039'main'#039')'#010+
   's '#039'main'#039')'#010+
-  '**2Xn_Use target system native linker instead of GNU ld (Solaris, AIX)'+
-  #010+
-  'F*2Xp<x>_First search for the compiler ','binary in the directory <x>'#010+
+  '**2Xn_Use ta','rget system native linker instead of GNU ld (Solaris, AI'+
+  'X)'#010+
+  'F*2Xp<x>_First search for the compiler binary in the directory <x>'#010+
   '**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
   '**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
-  '**2Xr<x>_Set the linker'#039's rlink-path to <x> (needed for cross comp'+
-  'ile, see the ld manual for more information) (BeOS, Linux)'#010+
-  '**2XR<x>_Prepend <x> to all lin','ker search paths (BeOS, Darwin, FreeB'+
-  'SD, Linux, Mac OS, Solaris)'#010+
+  '**2Xr<x>_Set the linker'#039's rlink-path to <x> (needed for cr','oss co'+
+  'mpile, see the ld manual for more information) (BeOS, Linux)'#010+
+  '**2XR<x>_Prepend <x> to all linker search paths (BeOS, Darwin, FreeBSD'+
+  ', Linux, Mac OS, Solaris)'#010+
   '**2Xs_Strip all symbols from executable'#010+
   '**2Xs_Strip all symbols from executable'#010+
-  '**2XS_Try to link units statically (default, defines FPC_LINK_STATIC)'#010+
+  '**2XS_Try to link units statically (d','efault, defines FPC_LINK_STATIC'+
+  ')'#010+
   '**2Xt_Link with static libraries (-static is passed to linker)'#010+
   '**2Xt_Link with static libraries (-static is passed to linker)'#010+
-  '**','2Xv_Generate table for Virtual Entry calls'#010+
+  '**2Xv_Generate table for Virtual Entry calls'#010+
   '**2XV_Use VLink as external linker       (default on Amiga, MorphOS)'#010+
   '**2XV_Use VLink as external linker       (default on Amiga, MorphOS)'#010+
-  '**2XX_Try to smartlink units             (defines FPC_LINK_SMART)'#010+
+  '**2XX_Try to smartlink units  ','           (defines FPC_LINK_SMART)'#010+
   '**1*_'#010+
   '**1*_'#010+
   '**1?_Show this help'#010+
   '**1?_Show this help'#010+
-  '**1h_Shows this help without waiting',''
+  '**1h_Shows this help without waiting'
 );
 );

+ 25 - 0
compiler/options.pas

@@ -1050,6 +1050,9 @@ var
   d,s   : TCmdStr;
   d,s   : TCmdStr;
   hs    : TCmdStr;
   hs    : TCmdStr;
   unicodemapping : punicodemap;
   unicodemapping : punicodemap;
+{$ifdef llvm}
+  disable: boolean;
+{$endif}
 begin
 begin
   if opt='' then
   if opt='' then
    exit;
    exit;
@@ -1300,6 +1303,28 @@ begin
                         while l<=length(More) do
                         while l<=length(More) do
                           begin
                           begin
                             case More[l] of
                             case More[l] of
+                              'f':
+                                begin
+                                  More:=copy(More,l+1,length(More));
+                                  disable:=Unsetbool(More,length(More)-1,opt,false);
+                                  case More of
+                                    'lto':
+                                       begin
+                                         if not disable then
+                                           begin
+                                             include(init_settings.moduleswitches,cs_lto);
+                                             LTOExt:='.bc';
+                                           end
+                                         else
+                                           exclude(init_settings.moduleswitches,cs_lto);
+                                       end;
+                                    else
+                                      begin
+                                        IllegalPara(opt);
+                                      end;
+                                  end;
+                                  l:=length(more)+1;
+                                end;
                               'v':
                               'v':
                                 begin
                                 begin
                                   init_settings.llvmversion:=llvmversion2enum(copy(More,l+1,length(More)));
                                   init_settings.llvmversion:=llvmversion2enum(copy(More,l+1,length(More)));

+ 5 - 0
compiler/pmodules.pas

@@ -130,6 +130,11 @@ implementation
            current_module.linkunitstaticlibs.add(current_module.staticlibfilename ,link_smart);
            current_module.linkunitstaticlibs.add(current_module.staticlibfilename ,link_smart);
            current_module.headerflags:=current_module.headerflags or uf_smart_linked;
            current_module.headerflags:=current_module.headerflags or uf_smart_linked;
          end;
          end;
+        if cs_lto in current_settings.moduleswitches then
+          begin
+            current_module.linkunitofiles.add(ChangeFileExt(current_module.objfilename,LTOExt),link_lto);
+            current_module.headerflags:=current_module.headerflags or uf_lto_linked;
+          end;
       end;
       end;
 
 
 
 

+ 1 - 0
compiler/ppu.pas

@@ -58,6 +58,7 @@ const
   uf_smart_linked        = $000040; { the ppu can be smartlinked }
   uf_smart_linked        = $000040; { the ppu can be smartlinked }
   uf_static_linked       = $000080; { the ppu can be linked static }
   uf_static_linked       = $000080; { the ppu can be linked static }
   uf_shared_linked       = $000100; { the ppu can be linked shared }
   uf_shared_linked       = $000100; { the ppu can be linked shared }
+  uf_lto_linked          = $000200; { the ppu can be used with LTO }
   uf_no_link             = $000400; { unit has no .o generated, but can still have external linking! }
   uf_no_link             = $000400; { unit has no .o generated, but can still have external linking! }
   uf_little_endian       = $001000;
   uf_little_endian       = $001000;
   uf_fpu_emulation       = $008000; { this unit was compiled with fpu emulation on }
   uf_fpu_emulation       = $008000; { this unit was compiled with fpu emulation on }

+ 33 - 8
compiler/systems/t_bsd.pas

@@ -174,8 +174,8 @@ begin
        begin
        begin
          if not(target_info.system in systems_darwin) then
          if not(target_info.system in systems_darwin) then
            begin
            begin
-             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -L. -o $EXE $CATRES $FILELIST';
-             DllCmd[1]:='ld $TARGET $EMUL $OPT $MAP $ORDERSYMS -shared -L. -o $EXE $CATRES $FILELIST'
+             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS -L. -o $EXE $CATRES $FILELIST';
+             DllCmd[1]:='ld $TARGET $EMUL $OPT $MAP $LTO $ORDERSYMS -shared -L. -o $EXE $CATRES $FILELIST'
            end
            end
          else
          else
            begin
            begin
@@ -194,22 +194,22 @@ begin
                programs with problems that require Valgrind will have more
                programs with problems that require Valgrind will have more
                than 60KB of data (first 4KB of address space is always invalid)
                than 60KB of data (first 4KB of address space is always invalid)
              }
              }
-               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
+               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
              if not(cs_gdb_valgrind in current_settings.globalswitches) then
              if not(cs_gdb_valgrind in current_settings.globalswitches) then
                ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
                ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
 {$else ndef cpu64bitaddr}
 {$else ndef cpu64bitaddr}
-             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
+             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
 {$endif ndef cpu64bitaddr}
 {$endif ndef cpu64bitaddr}
              if (apptype<>app_bundle) then
              if (apptype<>app_bundle) then
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $ORDERSYMS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $LTO $ORDERSYMS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
              else
              else
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $ORDERSYMS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $LTO $ORDERSYMS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
            end
            end
        end
        end
      else
      else
        begin
        begin
-         ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -L. -o $EXE $RES';
-         DllCmd[1]:='ld $TARGET $EMUL $OPT $INIT $FINI $SONAME $MAP $ORDERSYMS -shared -L. -o $EXE $RES';
+         ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS -L. -o $EXE $RES';
+         DllCmd[1]:='ld $TARGET $EMUL $OPT $INIT $FINI $SONAME $MAP $LTO $ORDERSYMS -shared -L. -o $EXE $RES';
        end;
        end;
      if not(target_info.system in systems_darwin) then
      if not(target_info.system in systems_darwin) then
        DllCmd[2]:='strip --strip-unneeded $EXE'
        DllCmd[2]:='strip --strip-unneeded $EXE'
@@ -803,6 +803,7 @@ var
   emulstr,
   emulstr,
   extdbgbinstr,
   extdbgbinstr,
   extdbgcmdstr,
   extdbgcmdstr,
+  ltostr,
   ordersymfile: TCmdStr;
   ordersymfile: TCmdStr;
   linkscript: TAsmScript;
   linkscript: TAsmScript;
   DynLinkStr : string[60];
   DynLinkStr : string[60];
@@ -822,6 +823,7 @@ begin
   GCSectionsStr:='';
   GCSectionsStr:='';
   linkscript:=nil;
   linkscript:=nil;
   mapstr:='';
   mapstr:='';
+  ltostr:='';
   if (cs_link_map in current_settings.globalswitches) then
   if (cs_link_map in current_settings.globalswitches) then
     mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
     mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
   { i386_freebsd needs -b elf32-i386-freebsd and -m elf_i386_fbsd
   { i386_freebsd needs -b elf32-i386-freebsd and -m elf_i386_fbsd
@@ -875,6 +877,16 @@ begin
      DynLinKStr:=DynLinkStr+' -dynamic'; // one dash!
      DynLinKStr:=DynLinkStr+' -dynamic'; // one dash!
    end;
    end;
 
 
+  { add custom LTO library if using custom clang }
+  if (target_info.system in systems_darwin) and
+     (cs_lto in current_settings.moduleswitches) and
+     not(cs_link_on_target in current_settings.globalswitches) and
+     (utilsdirectory<>'') and
+     FileExists(utilsdirectory+'/../lib/libLTO.dylib',true) then
+    begin
+      ltostr:='-lto_library '+maybequoted(utilsdirectory+'/../lib/libLTO.dylib');
+    end;
+
 { Use -nopie on OpenBSD if PIC support is turned off }
 { Use -nopie on OpenBSD if PIC support is turned off }
   if (target_info.system in systems_openbsd) and
   if (target_info.system in systems_openbsd) and
      not(cs_create_pic in current_settings.moduleswitches) then
      not(cs_create_pic in current_settings.moduleswitches) then
@@ -899,6 +911,7 @@ begin
   Replace(cmdstr,'$MAP',mapstr);
   Replace(cmdstr,'$MAP',mapstr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+  Replace(cmdstr,'$LTO',ltostr);
   if ordersymfile<>'' then
   if ordersymfile<>'' then
     begin
     begin
       if target_info.system in systems_darwin then
       if target_info.system in systems_darwin then
@@ -987,6 +1000,7 @@ var
   binstr,
   binstr,
   cmdstr,
   cmdstr,
   mapstr,
   mapstr,
+  ltostr,
   ordersymfile,
   ordersymfile,
   targetstr,
   targetstr,
   emulstr,
   emulstr,
@@ -1020,6 +1034,16 @@ begin
   if (cs_link_map in current_settings.globalswitches) then
   if (cs_link_map in current_settings.globalswitches) then
     mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.sharedlibfilename,'.map'));
     mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.sharedlibfilename,'.map'));
 
 
+  { add custom LTO library if using custom clang }
+  if (target_info.system in systems_darwin) and
+     (cs_lto in current_settings.moduleswitches) and
+     not(cs_link_on_target in current_settings.globalswitches) and
+     (utilsdirectory<>'') and
+     FileExists(utilsdirectory+'/../lib/libLTO.dylib',true) then
+    begin
+      ltostr:='-lto_library '+maybequoted(utilsdirectory+'/../lib/libLTO.dylib');
+    end;
+
   { i386_freebsd needs -b elf32-i386-freebsd and -m elf_i386_fbsd
   { i386_freebsd needs -b elf32-i386-freebsd and -m elf_i386_fbsd
     to avoid creation of a i386:x86_64 arch binary }
     to avoid creation of a i386:x86_64 arch binary }
 
 
@@ -1059,6 +1083,7 @@ begin
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   Replace(cmdstr,'$SONAME',SoNameStr);
   Replace(cmdstr,'$SONAME',SoNameStr);
   Replace(cmdstr,'$MAP',mapstr);
   Replace(cmdstr,'$MAP',mapstr);
+  Replace(cmdstr,'$LTO',ltostr);
   if ordersymfile<>'' then
   if ordersymfile<>'' then
     begin
     begin
       if target_info.system in systems_darwin then
       if target_info.system in systems_darwin then

+ 27 - 4
compiler/systems/t_linux.pas

@@ -373,8 +373,8 @@ begin
 {$endif powerpc64}
 {$endif powerpc64}
   with Info do
   with Info do
    begin
    begin
-     ExeCmd[1]:='ld '+platform_select+platformopt+' $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP -L. -o $EXE';
-     DllCmd[1]:='ld '+platform_select+' $OPT $INIT $FINI $SONAME $MAP -shared $GCSECTIONS -L. -o $EXE';
+     ExeCmd[1]:='ld '+platform_select+platformopt+' $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $LTO -L. -o $EXE';
+     DllCmd[1]:='ld '+platform_select+' $OPT $INIT $FINI $SONAME $MAP $LTO -shared $GCSECTIONS -L. -o $EXE';
      { when we want to cross-link we need to override default library paths;
      { when we want to cross-link we need to override default library paths;
        when targeting binutils 2.19 or later, we use the "INSERT" command to
        when targeting binutils 2.19 or later, we use the "INSERT" command to
        augment the default linkerscript, which also requires -T (normally that
        augment the default linkerscript, which also requires -T (normally that
@@ -1384,7 +1384,8 @@ var
   i : longint;
   i : longint;
   binstr,
   binstr,
   cmdstr,
   cmdstr,
-  mapstr : TCmdStr;
+  mapstr,
+  ltostr  : TCmdStr;
   success : boolean;
   success : boolean;
   DynLinkStr : string;
   DynLinkStr : string;
   GCSectionsStr,
   GCSectionsStr,
@@ -1400,6 +1401,7 @@ begin
   GCSectionsStr:='';
   GCSectionsStr:='';
   DynLinkStr:='';
   DynLinkStr:='';
   mapstr:='';
   mapstr:='';
+  ltostr:='';
   if (cs_link_staticflag in current_settings.globalswitches) then
   if (cs_link_staticflag in current_settings.globalswitches) then
    StaticStr:='-static';
    StaticStr:='-static';
   if (cs_link_strip in current_settings.globalswitches) and
   if (cs_link_strip in current_settings.globalswitches) and
@@ -1420,6 +1422,15 @@ begin
        DynLinkStr:=DynLinkStr+' --rpath-link '+rlinkpath;
        DynLinkStr:=DynLinkStr+' --rpath-link '+rlinkpath;
    End;
    End;
 
 
+  { add custom LTO library if using custom clang }
+  if (cs_lto in current_settings.moduleswitches) and
+     not(cs_link_on_target in current_settings.globalswitches) and
+     (utilsdirectory<>'') and
+     FileExists(utilsdirectory+'/../lib/LLVMgold.so',true) then
+    begin
+      ltostr:='-plugin '+maybequoted(utilsdirectory+'/../lib/LLVMgold.so ');
+    end;
+
 { Write used files and libraries }
 { Write used files and libraries }
   WriteResponseFile(false);
   WriteResponseFile(false);
 
 
@@ -1433,6 +1444,7 @@ begin
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   Replace(cmdstr,'$DYNLINK',DynLinkStr);
   Replace(cmdstr,'$DYNLINK',DynLinkStr);
   Replace(cmdstr,'$MAP',mapstr);
   Replace(cmdstr,'$MAP',mapstr);
+  Replace(cmdstr,'$LTO',ltostr);
 
 
   { create dynamic symbol table? }
   { create dynamic symbol table? }
   if HasExports then
   if HasExports then
@@ -1475,7 +1487,8 @@ var
   SoNameStr : string[80];
   SoNameStr : string[80];
   binstr,
   binstr,
   cmdstr,
   cmdstr,
-  mapstr : TCmdStr;
+  mapstr,
+  ltostr : TCmdStr;
   success : boolean;
   success : boolean;
 begin
 begin
   MakeSharedLibrary:=false;
   MakeSharedLibrary:=false;
@@ -1499,6 +1512,15 @@ begin
   if (cs_link_map in current_settings.globalswitches) then
   if (cs_link_map in current_settings.globalswitches) then
      mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.sharedlibfilename,'.map'));
      mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.sharedlibfilename,'.map'));
 
 
+  { add custom LTO library if using custom clang }
+  if (cs_lto in current_settings.moduleswitches) and
+     not(cs_link_on_target in current_settings.globalswitches) and
+     (utilsdirectory<>'') and
+     FileExists(utilsdirectory+'/../lib/LLVMgold.so',true) then
+    begin
+      ltostr:='-plugin '+maybequoted(utilsdirectory+'/../lib/LLVMgold.so ');
+    end;
+
 { Call linker }
 { Call linker }
   SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
   SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
   Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
   Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
@@ -1508,6 +1530,7 @@ begin
   Replace(cmdstr,'$FINI',FiniStr);
   Replace(cmdstr,'$FINI',FiniStr);
   Replace(cmdstr,'$SONAME',SoNameStr);
   Replace(cmdstr,'$SONAME',SoNameStr);
   Replace(cmdstr,'$MAP',mapstr);
   Replace(cmdstr,'$MAP',mapstr);
+  Replace(cmdstr,'$LTO',ltostr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
   success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
 
 

+ 18 - 5
compiler/utils/ppumove.pp

@@ -66,6 +66,7 @@ const
   link_static  = $2;
   link_static  = $2;
   link_smart   = $4;
   link_smart   = $4;
   link_shared  = $8;
   link_shared  = $8;
+  link_lto     = $10;
 
 
 Type
 Type
   PLinkOEnt = ^TLinkOEnt;
   PLinkOEnt = ^TLinkOEnt;
@@ -249,8 +250,10 @@ Var
   s      : string;
   s      : string;
   ppuversion,
   ppuversion,
   ppulongversion: dword;
   ppulongversion: dword;
+  gotltofiles: boolean;
 begin
 begin
   DoPPU:=false;
   DoPPU:=false;
+  gotltofiles:=false;
   If Not Quiet then
   If Not Quiet then
    Write ('Processing ',PPUFn,'...');
    Write ('Processing ',PPUFn,'...');
   inppu:=tppufile.create(PPUFn);
   inppu:=tppufile.create(PPUFn);
@@ -354,19 +357,23 @@ begin
     iblinkunitofiles :
     iblinkunitofiles :
       begin
       begin
         { add all o files, and save the entry when not creating a static
         { add all o files, and save the entry when not creating a static
-          library to keep staticlinking possible }
+          library to keep staticlinking possible (also keep possibility
+          to link lto) }
         while not inppu.endofentry do
         while not inppu.endofentry do
          begin
          begin
            s:=inppu.getstring;
            s:=inppu.getstring;
            m:=inppu.getlongint;
            m:=inppu.getlongint;
-           if not MakeStatic then
+           if (not MakeStatic) or
+              ((m and link_lto)<>0) then
             begin
             begin
+              gotltofiles:=gotltofiles or ((m and link_lto)<>0);
               outppu.putstring(s);
               outppu.putstring(s);
               outppu.putlongint(m);
               outppu.putlongint(m);
             end;
             end;
            AddToLinkFiles(s);
            AddToLinkFiles(s);
          end;
          end;
-        if not MakeStatic then
+        if not MakeStatic or
+           gotltofiles then
          outppu.writeentry(b);
          outppu.writeentry(b);
       end;
       end;
 {    iblinkunitstaticlibs :
 {    iblinkunitstaticlibs :
@@ -386,13 +393,19 @@ begin
   if MakeStatic then
   if MakeStatic then
    begin
    begin
      outppu.putstring(OutputfileForPPU);
      outppu.putstring(OutputfileForPPU);
-     outppu.putlongint(link_static);
+     if not gotltofiles then
+       outppu.putlongint(link_static)
+     else
+       outppu.putlongint(link_static or link_lto);
      outppu.writeentry(iblinkunitstaticlibs)
      outppu.writeentry(iblinkunitstaticlibs)
    end
    end
   else
   else
    begin
    begin
      outppu.putstring(OutputfileForPPU);
      outppu.putstring(OutputfileForPPU);
-     outppu.putlongint(link_shared);
+     if not gotltofiles then
+       outppu.putlongint(link_shared)
+     else
+       outppu.putlongint(link_shared or link_lto);
      outppu.writeentry(iblinkunitsharedlibs);
      outppu.writeentry(iblinkunitsharedlibs);
    end;
    end;
 { read all entries until the end and write them also to the new ppu }
 { read all entries until the end and write them also to the new ppu }