aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/llvm')
-rw-r--r--lib/hipe/llvm/Makefile8
-rw-r--r--lib/hipe/llvm/elf32_format.hrl6
-rw-r--r--lib/hipe/llvm/elf64_format.hrl6
-rw-r--r--lib/hipe/llvm/elf_format.erl70
-rw-r--r--lib/hipe/llvm/elf_format.hrl66
-rw-r--r--lib/hipe/llvm/hipe_llvm.erl23
-rw-r--r--lib/hipe/llvm/hipe_rtl_to_llvm.erl23
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) ->