Procházet zdrojové kódy

+ tcgllvm.a_label() and tcgllvm.a_jmp_always(). Special for llvm: every
basic block must end with a terminator instruciton (such as a branch) ->
when emitting a label, check whether the previous instruction is a
terminator instruction and if not, add an unconditional branch to the
label we are adding.
o Implemented at the tcg instead of at the thlcgobj level because
a) these methods don't need any high level type information
b) implementing them in thlcgobj would require making thlcg.a_label()
virtual and ensuring that no-one ever calls cg.a_label() in any
generic code

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

Jonas Maebe před 11 roky
rodič
revize
d245228ba6
2 změnil soubory, kde provedl 28 přidání a 1 odebrání
  1. 23 1
      compiler/llvm/cgllvm.pas
  2. 5 0
      compiler/llvm/llvmbase.pas

+ 23 - 1
compiler/llvm/cgllvm.pas

@@ -28,11 +28,13 @@ interface
     uses
        globtype,parabase,
        cgbase,cgutils,cgobj,cghlcpu,
-       llvmbase,llvminfo,aasmtai,aasmdata,aasmllvm;
+       llvmbase,llvminfo,aasmbase,aasmtai,aasmdata,aasmllvm;
 
     type
       tcgllvm=class(thlbasecgcpu)
      public
+        procedure a_label(list : TAsmList;l : tasmlabel);override;
+        procedure a_jmp_always(list: TAsmList; l: tasmlabel); override;
         procedure init_register_allocators;override;
         procedure done_register_allocators;override;
         function  getintregister(list:TAsmList;size:Tcgsize):Tregister;override;
@@ -54,6 +56,26 @@ implementation
                               Assembler code
 ****************************************************************************}
 
+    procedure tcgllvm.a_label(list: TAsmList; l: tasmlabel);
+      begin
+        { in llvm, every block must end with a terminator instruction, such as
+          a branch -> if the previous instruction is not a terminator instruction,
+          add an unconditional branch to the next block (= the one starting with
+          this label) }
+        if not assigned(list.last) or
+           (tai(list.Last).typ<>ait_llvmins) or
+           not(taillvm(list.Last).llvmopcode in llvmterminatoropcodes) then
+          a_jmp_always(list,l);
+        inherited;
+      end;
+
+
+    procedure tcgllvm.a_jmp_always(list: TAsmList; l: tasmlabel);
+      begin
+        list.concat(taillvm.op_lab(la_br,l));
+      end;
+
+
     procedure tcgllvm.init_register_allocators;
       begin
         inherited init_register_allocators;

+ 5 - 0
compiler/llvm/llvmbase.pas

@@ -69,6 +69,11 @@ interface
       la_type { type definition }
     );
 
+  const
+    llvmterminatoropcodes = [la_ret, la_br, la_switch, la_indirectbr,
+      la_invoke, la_resume,
+      la_unreachable];
+
   type
     tllvmfpcmp = (
       lfc_false,