Sfoglia il codice sorgente

+ LLVM 3.7 support in the LLVM IR writer

git-svn-id: trunk@34550 -
Jonas Maebe 8 anni fa
parent
commit
999cb7de6d
3 ha cambiato i file con 98 aggiunte e 9 eliminazioni
  1. 32 3
      compiler/llvm/aasmllvm.pas
  2. 59 4
      compiler/llvm/agllvm.pas
  3. 7 2
      compiler/llvm/llvminfo.pas

+ 32 - 3
compiler/llvm/aasmllvm.pas

@@ -200,7 +200,7 @@ implementation
 uses
 uses
   cutils, strings,
   cutils, strings,
   symconst,
   symconst,
-  aasmcpu;
+  aasmcnst,aasmcpu;
 
 
     { taillvmprocdecl }
     { taillvmprocdecl }
 
 
@@ -553,8 +553,7 @@ uses
                   internalerror(2013110104);
                   internalerror(2013110104);
               end;
               end;
             end;
             end;
-          la_load,
-          la_getelementptr:
+          la_load:
             begin
             begin
               { dst = load ptrdef srcref }
               { dst = load ptrdef srcref }
               case opnr of
               case opnr of
@@ -564,6 +563,36 @@ uses
                   internalerror(2013110105);
                   internalerror(2013110105);
               end;
               end;
             end;
             end;
+          la_getelementptr:
+            begin
+              { dst = getelementptr ref ... }
+              case opnr of
+                0:
+                  begin
+                    case oper[1]^.typ of
+                      top_def:
+                        result:=oper[1]^.def;
+                      top_tai:
+                        begin
+                          case oper[1]^.ai.typ of
+                            ait_llvmins:
+                              result:=taillvm(oper[1]^.ai).spilling_get_reg_type(0);
+                            ait_typedconst:
+                              result:=tai_abstracttypedconst(oper[1]^.ai).def
+                            else
+                              internalerror(2016071202);
+                          end
+                        end
+                      else
+                        internalerror(2016071201);
+                    end
+                  end;
+                2:
+                  result:=oper[1]^.def;
+                else
+                  internalerror(2013110105);
+              end;
+            end;
           la_fence,
           la_fence,
           la_cmpxchg,
           la_cmpxchg,
           la_atomicrmw:
           la_atomicrmw:

+ 59 - 4
compiler/llvm/agllvm.pas

@@ -390,9 +390,11 @@ implementation
   procedure TLLVMInstrWriter.WriteInstruction(hp: tai);
   procedure TLLVMInstrWriter.WriteInstruction(hp: tai);
     var
     var
       op: tllvmop;
       op: tllvmop;
+      tmpstr,
       sep: TSymStr;
       sep: TSymStr;
       i, opstart: byte;
       i, opstart: byte;
       nested: boolean;
       nested: boolean;
+      opdone,
       done: boolean;
       done: boolean;
     begin
     begin
       op:=taillvm(hp).llvmopcode;
       op:=taillvm(hp).llvmopcode;
@@ -403,6 +405,7 @@ implementation
       if owner.fdecllevel=0 then
       if owner.fdecllevel=0 then
         owner.writer.AsmWrite(#9);
         owner.writer.AsmWrite(#9);
       sep:=' ';
       sep:=' ';
+      opdone:=false;
       done:=false;
       done:=false;
       opstart:=0;
       opstart:=0;
       nested:=false;
       nested:=false;
@@ -414,6 +417,41 @@ implementation
              owner.writer.AsmWrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
              owner.writer.AsmWrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
              done:=true;
              done:=true;
            end;
            end;
+        la_load,
+        la_getelementptr:
+          begin
+            if (taillvm(hp).oper[0]^.typ<>top_reg) or
+               (taillvm(hp).oper[0]^.reg<>NR_NO) then
+              owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)+' = ')
+            else
+              nested:=true;
+            opstart:=1;
+            if llvmflag_load_getelptr_type in llvmversion_properties[current_settings.llvmversion] then
+              begin
+                owner.writer.AsmWrite(llvm_op2str[op]);
+                opdone:=true;
+                if nested then
+                  owner.writer.AsmWrite(' (')
+                else
+                  owner.writer.AsmWrite(' ');
+                { can't just dereference the type, because it may be an
+                  implicit pointer type such as a class -> resort to string
+                  manipulation... Not very clean :( }
+                tmpstr:=llvmencodetypename(taillvm(hp).spilling_get_reg_type(0));
+                if op=la_getelementptr then
+                  begin
+                    if tmpstr[length(tmpstr)]<>'*' then
+                      begin
+                        writeln(tmpstr);
+                        internalerror(2016071101);
+                      end
+                    else
+                      setlength(tmpstr,length(tmpstr)-1);
+                  end;
+                owner.writer.AsmWrite(tmpstr);
+                owner.writer.AsmWrite(',');
+              end
+          end;
         la_ret, la_br, la_switch, la_indirectbr,
         la_ret, la_br, la_switch, la_indirectbr,
         la_invoke, la_resume,
         la_invoke, la_resume,
         la_unreachable,
         la_unreachable,
@@ -428,8 +466,22 @@ implementation
           begin
           begin
             if taillvm(hp).oper[1]^.reg<>NR_NO then
             if taillvm(hp).oper[1]^.reg<>NR_NO then
               owner.writer.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
               owner.writer.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
-            sep:=' ';
             opstart:=2;
             opstart:=2;
+            if llvmflag_call_no_ptr in llvmversion_properties[current_settings.llvmversion] then
+              begin
+                owner.writer.AsmWrite(llvm_op2str[op]);
+                opdone:=true;
+                tmpstr:=llvmencodetypename(taillvm(hp).oper[2]^.def);
+                if tmpstr[length(tmpstr)]<>'*' then
+                  begin
+                    writeln(tmpstr);
+                    internalerror(2016071102);
+                  end
+                else
+                  setlength(tmpstr,length(tmpstr)-1);
+                owner.writer.AsmWrite(tmpstr);
+                opstart:=3;
+              end;
           end;
           end;
         la_blockaddress:
         la_blockaddress:
           begin
           begin
@@ -495,9 +547,12 @@ implementation
       { process operands }
       { process operands }
       if not done then
       if not done then
         begin
         begin
-          owner.writer.AsmWrite(llvm_op2str[op]);
-          if nested then
-            owner.writer.AsmWrite(' (');
+          if not opdone then
+            begin
+              owner.writer.AsmWrite(llvm_op2str[op]);
+              if nested then
+                owner.writer.AsmWrite(' (');
+            end;
           if taillvm(hp).ops<>0 then
           if taillvm(hp).ops<>0 then
             begin
             begin
               for i:=opstart to taillvm(hp).ops-1 do
               for i:=opstart to taillvm(hp).ops-1 do

+ 7 - 2
compiler/llvm/llvminfo.pas

@@ -33,6 +33,7 @@ Type
        llvmver_3_6_0,
        llvmver_3_6_0,
        llvmver_3_6_1,
        llvmver_3_6_1,
        llvmver_3_6_2,
        llvmver_3_6_2,
+       llvmver_3_7_0,
        { Xcode versions use snapshots of LLVM and don't correspond to released
        { Xcode versions use snapshots of LLVM and don't correspond to released
          versions of llvm (they don't ship with the llvm utilities either, but
          versions of llvm (they don't ship with the llvm utilities either, but
          they do come with Clang, which can also be used to some extent instead
          they do come with Clang, which can also be used to some extent instead
@@ -43,7 +44,9 @@ Type
 type
 type
    tllvmversionflag = (
    tllvmversionflag = (
      llvmflag_metadata_keyword,    { use "metadata" keyword (others leave it away, except when metadata is an argument to call instructions) }
      llvmflag_metadata_keyword,    { use "metadata" keyword (others leave it away, except when metadata is an argument to call instructions) }
-     llvmflag_linker_private       { have linker_private linkage type (later versions use global in combination with hidden visibility) }
+     llvmflag_linker_private,      { have linker_private linkage type (later versions use global in combination with hidden visibility) }
+     llvmflag_load_getelptr_type,  { the return type of loads and the base type of getelementptr must be specified }
+     llvmflag_call_no_ptr          { with direct calls, the function type is not a function pointer }
    );
    );
    tllvmversionflags = set of tllvmversionflag;
    tllvmversionflags = set of tllvmversionflag;
 
 
@@ -59,7 +62,8 @@ Const
      'LLVM-3.6.0',
      'LLVM-3.6.0',
      'LLVM-3.6.1',
      'LLVM-3.6.1',
      'LLVM-3.6.2',
      'LLVM-3.6.2',
-     'LLVM-Xcode-6.4'
+     'LLVM-3.7.0',
+     'LLVM-Xcode-6.4' { somewhere around LLVM 3.6.0 }
    );
    );
 
 
    llvmversion_properties: array[tllvmversion] of tllvmversionflags =
    llvmversion_properties: array[tllvmversion] of tllvmversionflags =
@@ -74,6 +78,7 @@ Const
        { llvmver_3_6_0  } [],
        { llvmver_3_6_0  } [],
        { llvmver_3_6_1  } [],
        { llvmver_3_6_1  } [],
        { llvmver_3_6_2  } [],
        { llvmver_3_6_2  } [],
+       { llvmver_3_7_0  } [llvmflag_load_getelptr_type,llvmflag_call_no_ptr],
        { llvmver_xc_6_4 } [llvmflag_metadata_keyword]
        { llvmver_xc_6_4 } [llvmflag_metadata_keyword]
      );
      );