浏览代码

* don't discard typeconversion nodes that only change the result type when
compiling for llvm, because this type change also needs to be modelled in
llvm IR

git-svn-id: branches/hlcgllvm@26999 -

Jonas Maebe 11 年之前
父节点
当前提交
8cc9b64ad7
共有 4 个文件被更改,包括 96 次插入1 次删除
  1. 1 0
      .gitattributes
  2. 1 1
      compiler/llvm/llvmnode.pas
  3. 86 0
      compiler/llvm/nllvmcnv.pas
  4. 8 0
      compiler/ncnv.pas

+ 1 - 0
.gitattributes

@@ -328,6 +328,7 @@ compiler/llvm/llvmpara.pas svneol=native#text/plain
 compiler/llvm/llvmsym.pas svneol=native#text/plain
 compiler/llvm/llvmtarg.pas svneol=native#text/plain
 compiler/llvm/nllvmadd.pas svneol=native#text/plain
+compiler/llvm/nllvmcnv.pas svneol=native#text/plain
 compiler/llvm/nllvmcon.pas svneol=native#text/plain
 compiler/llvm/nllvmld.pas svneol=native#text/plain
 compiler/llvm/nllvmmem.pas svneol=native#text/plain

+ 1 - 1
compiler/llvm/llvmnode.pas

@@ -37,7 +37,7 @@ implementation
     ncgbas,ncgflw,ncgcnv,ncgld,ncgmem,ncgcon,ncgset,
     ncgadd, ncgcal,ncgmat,ncginl,
     tgllvm,hlcgllvm,
-    nllvmadd,nllvmcon,nllvmld,nllvmmem,
+    nllvmadd,nllvmcnv,nllvmcon,nllvmld,nllvmmem,
     nllvmutil,
     llvmpara;
 

+ 86 - 0
compiler/llvm/nllvmcnv.pas

@@ -0,0 +1,86 @@
+{
+    Copyright (c) 2014 by Jonas Maebe
+
+    Generate LLVM IR for type converting nodes
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit nllvmcnv;
+
+{$i fpcdefs.inc}
+
+interface
+
+    uses
+      node,ncnv,ncgcnv,defcmp;
+
+    type
+       tllvmtypeconvnode = class(tcgtypeconvnode)
+         protected
+         { procedure second_int_to_int;override; }
+         { procedure second_string_to_string;override; }
+         { procedure second_cstring_to_pchar;override; }
+         { procedure second_string_to_chararray;override; }
+         { procedure second_array_to_pointer;override; }
+         { procedure second_pointer_to_array;override; }
+         { procedure second_chararray_to_string;override; }
+         { procedure second_char_to_string;override; }
+         { procedure second_int_to_real;override; }
+         { procedure second_real_to_real;override; }
+         { procedure second_cord_to_pointer;override; }
+         { procedure second_proc_to_procvar;override; }
+         { procedure second_bool_to_int;override; }
+         {  procedure second_int_to_bool;override; }
+         { procedure second_load_smallset;override;  }
+         { procedure second_ansistring_to_pchar;override; }
+         { procedure second_pchar_to_string;override; }
+         { procedure second_class_to_intf;override; }
+         { procedure second_char_to_char;override; }
+          procedure second_nothing; override;
+       end;
+
+implementation
+
+uses
+  verbose,
+  aasmdata,
+  symdef,
+  cgbase,cgutils,hlcgobj;
+
+{ tllvmtypeconvnode }
+
+procedure tllvmtypeconvnode.second_nothing;
+  var
+    hreg: tregister;
+  begin
+    if left.resultdef<>resultdef then
+      begin
+        if left.resultdef.size<>resultdef.size then
+          internalerror(2014012213);
+        hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
+        hreg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,getpointerdef(resultdef));
+        hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,getpointerdef(resultdef),left.location.reference,hreg);
+        location_reset_ref(location,left.location.loc,left.location.size,left.location.reference.alignment);
+        reference_reset_base(location.reference,hreg,0,location.reference.alignment);
+      end
+    else
+      location_copy(location,left.location);
+  end;
+
+begin
+  ctypeconvnode:=tllvmtypeconvnode;
+end.

+ 8 - 0
compiler/ncnv.pas

@@ -2168,11 +2168,19 @@ implementation
                        to different kinds of refcounting helpers }
                       (resultdef=left.resultdef)) then
                    begin
+{$ifndef llvm}
                      left.resultdef:=resultdef;
                      if (nf_explicit in flags) and (left.nodetype = addrn) then
                        include(left.flags, nf_typedaddr);
                      result:=left;
                      left:=nil;
+{$else llvm}
+                     { we still may have to insert a type conversion at the
+                       llvm level }
+                     if (nf_explicit in flags) and (left.nodetype = addrn) then
+                       include(flags, nf_typedaddr);
+                     result:=nil;
+{$endif llvm}
                      exit;
                    end;
                 end;