diff options
-rw-r--r-- | lib/hipe/llvm/Makefile | 8 | ||||
-rw-r--r-- | lib/hipe/llvm/elf32_format.hrl | 6 | ||||
-rw-r--r-- | lib/hipe/llvm/elf64_format.hrl | 6 | ||||
-rw-r--r-- | lib/hipe/llvm/elf_format.erl | 70 | ||||
-rw-r--r-- | lib/hipe/llvm/elf_format.hrl | 66 | ||||
-rw-r--r-- | lib/hipe/llvm/hipe_llvm.erl | 23 | ||||
-rw-r--r-- | lib/hipe/llvm/hipe_rtl_to_llvm.erl | 23 |
7 files changed, 106 insertions, 96 deletions
diff --git a/lib/hipe/llvm/Makefile b/lib/hipe/llvm/Makefile index d172e37b02..25b47a580f 100644 --- a/lib/hipe/llvm/Makefile +++ b/lib/hipe/llvm/Makefile @@ -40,12 +40,12 @@ RELSYSDIR = $(RELEASE_PATH)/lib/hipe-$(VSN) # Target Specs # ---------------------------------------------------- ifdef HIPE_ENABLED -HIPE_MODULES = hipe_rtl_to_llvm \ +HIPE_MODULES = elf_format \ hipe_llvm \ - elf_format \ + hipe_llvm_liveness \ hipe_llvm_main \ hipe_llvm_merge \ - hipe_llvm_liveness + hipe_rtl_to_llvm else HIPE_MODULES = endif @@ -71,7 +71,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) include ../native.mk -ERL_COMPILE_FLAGS += +inline #+warn_missing_spec +ERL_COMPILE_FLAGS += +inline +warn_export_vars #+warn_missing_spec # if in 32 bit backend define BIT32 symbol ARCH = $(shell echo $(TARGET) | sed 's/^\(x86_64\)-.*/64bit/') diff --git a/lib/hipe/llvm/elf32_format.hrl b/lib/hipe/llvm/elf32_format.hrl index 1158cb6434..af1d95bf5b 100644 --- a/lib/hipe/llvm/elf32_format.hrl +++ b/lib/hipe/llvm/elf32_format.hrl @@ -57,9 +57,3 @@ -define(P_MEMSZ_OFFSET, (?P_FILESZ_OFFSET + ?P_FILESZ_SIZE) ). -define(P_FLAGS_OFFSET, (?P_TYPE_OFFSET + ?P_TYPE_SIZE) ). -define(P_ALIGN_OFFSET, (?P_MEMSZ_OFFSET + ?P_MEMSZ_SIZE) ). - -%%------------------------------------------------------------------------------ -%% Exported record and type declarations for 'elf_format' module -%%------------------------------------------------------------------------------ - --type reloc_type() :: '32' | 'pc32'. diff --git a/lib/hipe/llvm/elf64_format.hrl b/lib/hipe/llvm/elf64_format.hrl index 0136e7f381..794746ffdc 100644 --- a/lib/hipe/llvm/elf64_format.hrl +++ b/lib/hipe/llvm/elf64_format.hrl @@ -56,9 +56,3 @@ -define(P_FILESZ_OFFSET, (?P_PVADDR_OFFSET + ?P_PVADDR_SIZE) ). -define(P_MEMSZ_OFFSET, (?P_FILESZ_OFFSET + ?P_FILESZ_SIZE) ). -define(P_ALIGN_OFFSET, (?P_MEMSZ_OFFSET + ?P_MEMSZ_SIZE) ). - -%%------------------------------------------------------------------------------ -%% Exported record and type declarations for 'elf_format' module -%%------------------------------------------------------------------------------ - --type reloc_type() :: '64' | 'pc32' | '32'. diff --git a/lib/hipe/llvm/elf_format.erl b/lib/hipe/llvm/elf_format.erl index b3c5ecddab..8cf6ea6250 100644 --- a/lib/hipe/llvm/elf_format.erl +++ b/lib/hipe/llvm/elf_format.erl @@ -35,25 +35,55 @@ %% Types %%------------------------------------------------------------------------------ --export_type([elf/0]). - --type lp() :: non_neg_integer(). % landing pad --type num() :: non_neg_integer(). --type index() :: non_neg_integer(). --type start() :: non_neg_integer(). - --type tuple(X) :: {} | {X} | {X, X} | tuple(). +-export_type([elf/0 + ,addend/0 + ,bitflags/0 + ,name/0 + ,offset/0 + ,reloc_type/0 + ,shdr_type/0 + ,size/0 + ,sym_bind/0 + ,sym_type/0 + ,valueoff/0 + ]). + +-type bitflags() :: non_neg_integer(). +-type index() :: non_neg_integer(). +-type lp() :: non_neg_integer(). % landing pad +-type num() :: non_neg_integer(). +-type offset() :: non_neg_integer(). +-type size() :: non_neg_integer(). +-type start() :: non_neg_integer(). + +-type addend() :: integer() | undefined. +-type name() :: string(). +-type shdr_type() :: 'null' | 'progbits' | 'symtab' | 'strtab' | 'rela' + | 'hash' | 'dynamic' | 'note' | 'nobits' | 'rel' | 'shlib' + | 'dynsym' | {os, ?SHT_LOOS..?SHT_HIOS} + | {proc, ?SHT_LOPROC..?SHT_HIPROC}. +-type sym_bind() :: 'local' | 'global' | 'weak' | {os, ?STB_LOOS..?STB_HIOS} + | {proc, ?STB_LOPROC..?STB_HIPROC}. +-type sym_type() :: 'notype' | 'object' | 'func' | 'section' | 'file' + | {os, ?STT_LOOS..?STT_HIOS} + | {proc, ?STT_LOPROC..?STT_HIPROC}. +-type valueoff() :: offset(). + +-ifdef(BIT32). % 386 +-type reloc_type() :: '32' | 'pc32'. +-else. % X86_64 +-type reloc_type() :: '64' | 'pc32' | '32'. +-endif. %%------------------------------------------------------------------------------ %% Abstract Data Types and Accessors for ELF Structures. %%------------------------------------------------------------------------------ -record(elf, {file :: binary() - ,sec_idx :: tuple(elf_shdr()) + ,sections :: [elf_shdr()] ,sec_nam :: #{string() => elf_shdr()} - ,sym_idx :: undefined | tuple(elf_sym()) + ,symbols :: undefined | [elf_sym()] }). - -opaque elf() :: #elf{}. %% File header @@ -211,9 +241,9 @@ read(ElfBin) -> [_UndefinedSec|Sections] = extract_shdrtab(ElfBin, Header), SecNam = maps:from_list( [{Name, Sec} || Sec = #elf_shdr{name=Name} <- Sections]), - Elf0 = #elf{file=ElfBin, sec_idx=list_to_tuple(Sections), sec_nam=SecNam}, + Elf0 = #elf{file=ElfBin, sections=Sections, sec_nam=SecNam}, [_UndefinedSym|Symbols] = extract_symtab(Elf0, extract_strtab(Elf0)), - Elf0#elf{sym_idx=list_to_tuple(Symbols)}. + Elf0#elf{symbols=Symbols}. %%------------------------------------------------------------------------------ %% Functions to manipulate the ELF File Header @@ -311,8 +341,8 @@ decode_shdr_type(Proc) when ?SHT_LOPROC =< Proc, Proc =< ?SHT_HIPROC -> -spec elf_section(non_neg_integer(), elf()) -> undefined | abs | elf_shdr(). elf_section(0, #elf{}) -> undefined; elf_section(?SHN_ABS, #elf{}) -> abs; -elf_section(Index, #elf{sec_idx=SecIdx}) when Index =< tuple_size(SecIdx) -> - element(Index, SecIdx). +elf_section(Index, #elf{sections=SecIdx}) -> + lists:nth(Index, SecIdx). %% Reads the contents of a section from an object -spec section_contents(elf_shdr(), elf()) -> binary(). @@ -374,10 +404,10 @@ decode_symbol_type(Proc) when ?STT_LOPROC =< Proc, Proc =< ?STT_HIPROC -> -spec elf_symbol(0, elf()) -> undefined; (pos_integer(), elf()) -> elf_sym(). elf_symbol(0, #elf{}) -> undefined; -elf_symbol(Index, #elf{sym_idx=SymIdx}) -> element(Index, SymIdx). +elf_symbol(Index, #elf{symbols=Symbols}) -> lists:nth(Index, Symbols). -spec elf_symbols(elf()) -> [elf_sym()]. -elf_symbols(#elf{sym_idx=SymIdx}) -> tuple_to_list(SymIdx). +elf_symbols(#elf{symbols=Symbols}) -> Symbols. %%------------------------------------------------------------------------------ %% Functions to manipulate String Table @@ -418,8 +448,8 @@ bin_get_string(<<Char, Rest/binary>>) -> [Char|bin_get_string(Rest)]. extract_rela(Elf, Name) -> SecData = extract_segment_by_name(Elf, Name), [#elf_rel{offset=Offset, symbol=elf_symbol(?ELF_R_SYM(Info), Elf), - type=decode_reloc_type(?ELF_R_TYPE(Info)), - addend=read_implicit_addend(Offset, SecData)} + type=decode_reloc_type(?ELF_R_TYPE(Info)), + addend=read_implicit_addend(Offset, SecData)} || <<Offset:?bits(?R_OFFSET_SIZE)/little, Info:?bits(?R_INFO_SIZE)/little % 386 uses ".rel" >> <= extract_segment_by_name(Elf, ?REL(Name))]. @@ -436,7 +466,7 @@ read_implicit_addend(Offset, Section) -> -else. %% BIT32 extract_rela(Elf, Name) -> [#elf_rel{offset=Offset, symbol=elf_symbol(?ELF_R_SYM(Info), Elf), - type=decode_reloc_type(?ELF_R_TYPE(Info)), addend=Addend} + type=decode_reloc_type(?ELF_R_TYPE(Info)), addend=Addend} || <<Offset:?bits(?R_OFFSET_SIZE)/little, Info:?bits(?R_INFO_SIZE)/little, Addend:?bits(?R_ADDEND_SIZE)/signed-little % X86_64 uses ".rela" diff --git a/lib/hipe/llvm/elf_format.hrl b/lib/hipe/llvm/elf_format.hrl index 5074682ae6..57a36f0c3e 100644 --- a/lib/hipe/llvm/elf_format.hrl +++ b/lib/hipe/llvm/elf_format.hrl @@ -491,50 +491,38 @@ %% Exported record and type declarations for 'elf_format' module %%------------------------------------------------------------------------------ --type offset() :: non_neg_integer(). --type size() :: non_neg_integer(). --type addend() :: integer() | undefined. --type sym_bind() :: 'local' | 'global' | 'weak' | {os, ?STB_LOOS..?STB_HIOS} - | {proc, ?STB_LOPROC..?STB_HIPROC}. --type sym_type() :: 'notype' | 'object' | 'func' | 'section' | 'file' - | {os, ?STT_LOOS..?STT_HIOS} - | {proc, ?STT_LOPROC..?STT_HIPROC}. --type shdr_type() :: 'null' | 'progbits' | 'symtab' | 'strtab' | 'rela' - | 'hash' | 'dynamic' | 'note' | 'nobits' | 'rel' | 'shlib' - | 'dynsym' | {os, ?SHT_LOOS..?SHT_HIOS} - | {proc, ?SHT_LOPROC..?SHT_HIPROC}. - --type valueoff() :: offset(). --type name() :: string(). - %% Section header entries --record(elf_shdr, {name :: name() % Section name - ,type :: shdr_type()% Section type - ,flags % Section attributes - ,addr % Virtual address in memory - ,offset :: offset() % Offset in file - ,size :: size() % Size of section - ,link % Link to other section - ,info % Miscellaneous information - ,addralign % Address align boundary - ,entsize % Size of entries, if section has table - }). +-record(elf_shdr, + {name :: elf_format:name() % Section name + ,type :: elf_format:shdr_type() % Section type + ,flags :: elf_format:bitflags() % Section attributes + ,addr :: elf_format:offset() % Virtual address in memory + ,offset :: elf_format:offset() % Offset in file + ,size :: elf_format:size() % Size of section + ,link :: non_neg_integer() % Link to other section + ,info :: non_neg_integer() % Miscellaneous information + ,addralign :: elf_format:size() % Address align boundary + ,entsize :: elf_format:size() % Size of entries, if section has + % table + }). -type elf_shdr() :: #elf_shdr{}. %% Symbol table entries --record(elf_sym, {name :: name() % Symbol name - ,bind :: sym_bind() % Symbol binding - ,type :: sym_type() % Symbol type - ,value :: valueoff() % Symbol value - ,size :: size() % Size of object - ,section :: undefined | abs | elf_shdr() - }). +-record(elf_sym, + {name :: elf_format:name() % Symbol name + ,bind :: elf_format:sym_bind() % Symbol binding + ,type :: elf_format:sym_type() % Symbol type + ,value :: elf_format:valueoff() % Symbol value + ,size :: elf_format:size() % Size of object + ,section :: undefined | abs | elf_shdr() + }). -type elf_sym() :: #elf_sym{}. %% Relocations --record(elf_rel, {offset :: offset() - ,type :: reloc_type() - ,addend :: addend() - ,symbol :: elf_sym() - }). +-record(elf_rel, + {offset :: elf_format:offset() + ,type :: elf_format:reloc_type() + ,addend :: elf_format:addend() + ,symbol :: elf_sym() + }). -type elf_rel() :: #elf_rel{}. diff --git a/lib/hipe/llvm/hipe_llvm.erl b/lib/hipe/llvm/hipe_llvm.erl index b2997f2d92..c2547dd89e 100644 --- a/lib/hipe/llvm/hipe_llvm.erl +++ b/lib/hipe/llvm/hipe_llvm.erl @@ -865,11 +865,7 @@ pp_ins(Dev, Ver, I) -> true -> write(Dev, "volatile "); false -> ok end, - case Ver >= {3,7} of false -> ok; true -> - pp_type(Dev, pointer_type(load_p_type(I))), - write(Dev, ", ") - end, - pp_type(Dev, load_p_type(I)), + pp_dereference_type(Dev, Ver, load_p_type(I)), write(Dev, [" ", load_pointer(I), " "]), case load_alignment(I) of [] -> ok; @@ -905,11 +901,7 @@ pp_ins(Dev, Ver, I) -> true -> write(Dev, "inbounds "); false -> ok end, - case Ver >= {3,7} of false -> ok; true -> - pp_type(Dev, pointer_type(getelementptr_p_type(I))), - write(Dev, ", ") - end, - pp_type(Dev, getelementptr_p_type(I)), + pp_dereference_type(Dev, Ver, getelementptr_p_type(I)), write(Dev, [" ", getelementptr_value(I)]), pp_typed_idxs(Dev, getelementptr_typed_idxs(I)), write(Dev, "\n"); @@ -1032,6 +1024,17 @@ pp_ins(Dev, Ver, I) -> exit({?MODULE, pp_ins, {"Unknown LLVM instruction", Other}}) end. +%% @doc Print the type of a dereference in an LLVM instruction using syntax +%% parsable by the specified LLVM version. +pp_dereference_type(Dev, Ver, Type) -> + case Ver >= {3,7} of + false -> ok; + true -> + pp_type(Dev, pointer_type(Type)), + write(Dev, ", ") + end, + pp_type(Dev, Type). + %% @doc Pretty-print a list of types pp_type_list(_Dev, []) -> ok; pp_type_list(Dev, [T]) -> diff --git a/lib/hipe/llvm/hipe_rtl_to_llvm.erl b/lib/hipe/llvm/hipe_rtl_to_llvm.erl index d7d8d1b049..b23d756d6c 100644 --- a/lib/hipe/llvm/hipe_rtl_to_llvm.erl +++ b/lib/hipe/llvm/hipe_rtl_to_llvm.erl @@ -266,17 +266,18 @@ trans_alub_overflow(I, Sign, Relocs) -> T2 = mk_temp(), %% T1{1}: Boolean variable indicating overflow I6 = hipe_llvm:mk_extractvalue(T2, ReturnType, T1, "1", []), - case hipe_rtl:alub_cond(I) of - Op when Op =:= overflow orelse Op =:= ltu -> - True_label = mk_jump_label(hipe_rtl:alub_true_label(I)), - False_label = mk_jump_label(hipe_rtl:alub_false_label(I)), - MetaData = branch_metadata(hipe_rtl:alub_pred(I)); - not_overflow -> - True_label = mk_jump_label(hipe_rtl:alub_false_label(I)), - False_label = mk_jump_label(hipe_rtl:alub_true_label(I)), - MetaData = branch_metadata(1 - hipe_rtl:alub_pred(I)) - end, - I7 = hipe_llvm:mk_br_cond(T2, True_label, False_label, MetaData), + {TrueLabel, FalseLabel, MetaData} = + case hipe_rtl:alub_cond(I) of + Op when Op =:= overflow orelse Op =:= ltu -> + {mk_jump_label(hipe_rtl:alub_true_label(I)), + mk_jump_label(hipe_rtl:alub_false_label(I)), + branch_metadata(hipe_rtl:alub_pred(I))}; + not_overflow -> + {mk_jump_label(hipe_rtl:alub_false_label(I)), + mk_jump_label(hipe_rtl:alub_true_label(I)), + branch_metadata(1 - hipe_rtl:alub_pred(I))} + end, + I7 = hipe_llvm:mk_br_cond(T2, TrueLabel, FalseLabel, MetaData), {[I7, I6, I5, I4, I3, I2, I1], NewRelocs}. trans_alub_op(I, Sign) -> |