mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 07:29:25 +02:00
+ 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 -
This commit is contained in:
parent
7db9d4c7e9
commit
d245228ba6
@ -28,11 +28,13 @@ interface
|
|||||||
uses
|
uses
|
||||||
globtype,parabase,
|
globtype,parabase,
|
||||||
cgbase,cgutils,cgobj,cghlcpu,
|
cgbase,cgutils,cgobj,cghlcpu,
|
||||||
llvmbase,llvminfo,aasmtai,aasmdata,aasmllvm;
|
llvmbase,llvminfo,aasmbase,aasmtai,aasmdata,aasmllvm;
|
||||||
|
|
||||||
type
|
type
|
||||||
tcgllvm=class(thlbasecgcpu)
|
tcgllvm=class(thlbasecgcpu)
|
||||||
public
|
public
|
||||||
|
procedure a_label(list : TAsmList;l : tasmlabel);override;
|
||||||
|
procedure a_jmp_always(list: TAsmList; l: tasmlabel); override;
|
||||||
procedure init_register_allocators;override;
|
procedure init_register_allocators;override;
|
||||||
procedure done_register_allocators;override;
|
procedure done_register_allocators;override;
|
||||||
function getintregister(list:TAsmList;size:Tcgsize):Tregister;override;
|
function getintregister(list:TAsmList;size:Tcgsize):Tregister;override;
|
||||||
@ -54,6 +56,26 @@ implementation
|
|||||||
Assembler code
|
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;
|
procedure tcgllvm.init_register_allocators;
|
||||||
begin
|
begin
|
||||||
inherited init_register_allocators;
|
inherited init_register_allocators;
|
||||||
|
@ -69,6 +69,11 @@ interface
|
|||||||
la_type { type definition }
|
la_type { type definition }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const
|
||||||
|
llvmterminatoropcodes = [la_ret, la_br, la_switch, la_indirectbr,
|
||||||
|
la_invoke, la_resume,
|
||||||
|
la_unreachable];
|
||||||
|
|
||||||
type
|
type
|
||||||
tllvmfpcmp = (
|
tllvmfpcmp = (
|
||||||
lfc_false,
|
lfc_false,
|
||||||
|
Loading…
Reference in New Issue
Block a user