From d245228ba69f50d2d2b3e3e42a5f9a112fd966f7 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Mon, 11 Nov 2013 11:15:20 +0000 Subject: [PATCH] + 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 - --- compiler/llvm/cgllvm.pas | 24 +++++++++++++++++++++++- compiler/llvm/llvmbase.pas | 5 +++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/compiler/llvm/cgllvm.pas b/compiler/llvm/cgllvm.pas index 5f40b1c4ea..4ac40f55f4 100644 --- a/compiler/llvm/cgllvm.pas +++ b/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; diff --git a/compiler/llvm/llvmbase.pas b/compiler/llvm/llvmbase.pas index 0792c341e9..5fd652b1ef 100644 --- a/compiler/llvm/llvmbase.pas +++ b/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,