瀏覽代碼

+ LLVM 3.7 support in the LLVM IR writer

git-svn-id: trunk@34550 -
Jonas Maebe 8 年之前
父節點
當前提交
999cb7de6d
共有 3 個文件被更改,包括 98 次插入9 次删除
  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
   cutils, strings,
   symconst,
-  aasmcpu;
+  aasmcnst,aasmcpu;
 
     { taillvmprocdecl }
 
@@ -553,8 +553,7 @@ uses
                   internalerror(2013110104);
               end;
             end;
-          la_load,
-          la_getelementptr:
+          la_load:
             begin
               { dst = load ptrdef srcref }
               case opnr of
@@ -564,6 +563,36 @@ uses
                   internalerror(2013110105);
               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_cmpxchg,
           la_atomicrmw:

+ 59 - 4
compiler/llvm/agllvm.pas

@@ -390,9 +390,11 @@ implementation
   procedure TLLVMInstrWriter.WriteInstruction(hp: tai);
     var
       op: tllvmop;
+      tmpstr,
       sep: TSymStr;
       i, opstart: byte;
       nested: boolean;
+      opdone,
       done: boolean;
     begin
       op:=taillvm(hp).llvmopcode;
@@ -403,6 +405,7 @@ implementation
       if owner.fdecllevel=0 then
         owner.writer.AsmWrite(#9);
       sep:=' ';
+      opdone:=false;
       done:=false;
       opstart:=0;
       nested:=false;
@@ -414,6 +417,41 @@ implementation
              owner.writer.AsmWrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
              done:=true;
            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_invoke, la_resume,
         la_unreachable,
@@ -428,8 +466,22 @@ implementation
           begin
             if taillvm(hp).oper[1]^.reg<>NR_NO then
               owner.writer.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
-            sep:=' ';
             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;
         la_blockaddress:
           begin
@@ -495,9 +547,12 @@ implementation
       { process operands }
       if not done then
         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
             begin
               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_1,
        llvmver_3_6_2,
+       llvmver_3_7_0,
        { 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
          they do come with Clang, which can also be used to some extent instead
@@ -43,7 +44,9 @@ Type
 type
    tllvmversionflag = (
      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;
 
@@ -59,7 +62,8 @@ Const
      'LLVM-3.6.0',
      'LLVM-3.6.1',
      '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 =
@@ -74,6 +78,7 @@ Const
        { llvmver_3_6_0  } [],
        { llvmver_3_6_1  } [],
        { llvmver_3_6_2  } [],
+       { llvmver_3_7_0  } [llvmflag_load_getelptr_type,llvmflag_call_no_ptr],
        { llvmver_xc_6_4 } [llvmflag_metadata_keyword]
      );