Update LLVM to r98164.

This commit is contained in:
Roman Divacky 2010-03-10 17:45:15 +00:00
parent f5a3459adf
commit ea5b2dd11c
206 changed files with 3945 additions and 2392 deletions

View file

@ -66,35 +66,64 @@ Archive.CMA := $(strip $(OCAMLC) -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
Compile.CMX := $(strip $(OCAMLOPT) -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
Archive.CMXA := $(strip $(OCAMLOPT) -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o)
ifdef OCAMLOPT
Archive.EXE := $(strip $(OCAMLOPT) -cc $(CXX) $(OCAMLCFLAGS) $(UsedOcamLibs:%=%.cmxa) $(OCAMLDEBUGFLAG) -o)
else
Archive.EXE := $(strip $(OCAMLC) -cc $(CXX) $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG:%=%.cma) -o)
endif
# Source files
OcamlSources1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.ml))
OcamlHeaders1 := $(OcamlSources1:.ml=.mli)
OcamlHeaders1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.mli))
OcamlSources := $(OcamlSources1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
OcamlHeaders := $(OcamlHeaders1:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
OcamlSources2 := $(filter-out $(ExcludeSources),$(OcamlSources1))
OcamlHeaders2 := $(filter-out $(ExcludeHeaders),$(OcamlHeaders1))
OcamlSources := $(OcamlSources2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
OcamlHeaders := $(OcamlHeaders2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
# Intermediate files
LibraryCMA := $(ObjDir)/$(LIBRARYNAME).cma
LibraryCMXA := $(ObjDir)/$(LIBRARYNAME).cmxa
ObjectsCMI := $(OcamlSources:%.ml=%.cmi)
ObjectsCMO := $(OcamlSources:%.ml=%.cmo)
ObjectsCMX := $(OcamlSources:%.ml=%.cmx)
ifdef LIBRARYNAME
LibraryCMA := $(ObjDir)/$(LIBRARYNAME).cma
LibraryCMXA := $(ObjDir)/$(LIBRARYNAME).cmxa
endif
ifdef TOOLNAME
ToolEXE := $(ObjDir)/$(TOOLNAME)$(EXEEXT)
endif
# Output files
# The .cmo files are the only intermediates; all others are to be installed.
LibraryA := $(OcamlDir)/lib$(LIBRARYNAME).a
OutputCMA := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
OutputsCMI := $(ObjectsCMI:$(ObjDir)/%.cmi=$(OcamlDir)/%.cmi)
OutputsCMX := $(ObjectsCMX:$(ObjDir)/%.cmx=$(OcamlDir)/%.cmx)
OutputLibs := $(UsedLibNames:%=$(OcamlDir)/%)
ifdef LIBRARYNAME
LibraryA := $(OcamlDir)/lib$(LIBRARYNAME).a
OutputCMA := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
endif
ifdef TOOLNAME
ifdef EXAMPLE_TOOL
OutputEXE := $(ExmplDir)/$(strip $(TOOLNAME))$(EXEEXT)
else
OutputEXE := $(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT)
endif
endif
# Installation targets
DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%)
ifdef LIBRARYNAME
DestA := $(PROJ_libocamldir)/lib$(LIBRARYNAME).a
DestCMA := $(PROJ_libocamldir)/$(LIBRARYNAME).cma
DestCMXA := $(PROJ_libocamldir)/$(LIBRARYNAME).cmxa
DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%)
endif
##===- Dependencies -------------------------------------------------------===##
# Copy the sources into the intermediate directory because older ocamlc doesn't
@ -106,18 +135,27 @@ $(ObjDir)/%.mli: $(PROJ_SRC_DIR)/%.mli $(ObjDir)/.dir
$(ObjDir)/%.ml: $(PROJ_SRC_DIR)/%.ml $(ObjDir)/.dir
$(Verb) $(CP) -f $< $@
$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
ifdef LIBRARYNAME
$(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
$(OcamlDir)/.dir $(ObjDir)/.dir
$(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
-include $(ObjDir)/$(LIBRARYNAME).ocamldep
endif
ifdef TOOLNAME
$(ObjDir)/$(TOOLNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
$(OcamlDir)/.dir $(ObjDir)/.dir
$(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
-include $(ObjDir)/$(TOOLNAME).ocamldep
endif
##===- Build static library from C sources --------------------------------===##
ifneq ($(ObjectsO),)
ifdef LibraryA
all-local:: $(LibraryA)
clean-local:: clean-a
install-local:: install-a
@ -160,7 +198,7 @@ $(OcamlDir)/%.o: $(LibDir)/%.o
$(Verb) ln -sf $< $@
clean-deplibs:
$(Verb) rm -f $(OutputLibs)
$(Verb) $(RM) -f $(OutputLibs)
install-deplibs:
$(Verb) $(MKDIR) $(PROJ_libocamldir)
@ -169,11 +207,12 @@ install-deplibs:
done
uninstall-deplibs:
$(Verb) rm -f $(DestLibs)
$(Verb) $(RM) -f $(DestLibs)
##===- Build ocaml interfaces (.mli's -> .cmi's) --------------------------===##
ifneq ($(OcamlHeaders),)
all-local:: build-cmis
clean-local:: clean-cmis
install-local:: install-cmis
@ -212,10 +251,16 @@ uninstall-cmis::
$(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
$(RM) -f "$(PROJ_libocamldir)/$$i"; \
done
endif
##===- Build ocaml bytecode archive (.ml's -> .cmo's -> .cma) -------------===##
$(ObjDir)/%.cmo: $(ObjDir)/%.ml
$(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
$(Verb) $(Compile.CMO) $@ $<
ifdef LIBRARYNAME
all-local:: $(OutputCMA)
clean-local:: clean-cma
install-local:: install-cma
@ -228,10 +273,6 @@ $(LibraryCMA): $(ObjectsCMO) $(OcamlDir)/.dir
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.CMA) $@ $(ObjectsCMO)
$(ObjDir)/%.cmo: $(ObjDir)/%.ml
$(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
$(Verb) $(Compile.CMO) $@ $<
clean-cma::
$(Verb) $(RM) -f $(OutputCMA) $(UsedLibNames:%=$(OcamlDir)/%)
@ -243,7 +284,7 @@ install-cma:: $(OutputCMA)
uninstall-cma::
$(Echo) "Uninstalling $(DestCMA)"
-$(Verb) $(RM) -f $(DestCMA)
endif
##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===##
@ -251,6 +292,14 @@ uninstall-cma::
# If unavailable, 'configure' will not define OCAMLOPT in Makefile.config.
ifdef OCAMLOPT
$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
$(Verb) $(CP) -f $< $@
$(ObjDir)/%.cmx: $(ObjDir)/%.ml
$(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build"
$(Verb) $(Compile.CMX) $@ $<
ifdef LIBRARYNAME
all-local:: $(OutputCMXA) $(OutputsCMX)
clean-local:: clean-cmxa
install-local:: install-cmxa
@ -260,18 +309,11 @@ $(OutputCMXA): $(LibraryCMXA)
$(Verb) $(CP) -f $< $@
$(Verb) $(CP) -f $(<:.cmxa=.a) $(@:.cmxa=.a)
$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
$(Verb) $(CP) -f $< $@
$(LibraryCMXA): $(ObjectsCMX)
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.CMXA) $@ $(ObjectsCMX)
$(Verb) $(RM) -f $(@:.cmxa=.o)
$(ObjDir)/%.cmx: $(ObjDir)/%.ml
$(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build"
$(Verb) $(Compile.CMX) $@ $<
clean-cmxa::
$(Verb) $(RM) -f $(OutputCMXA) $(OutputCMXA:.cmxa=.a) $(OutputsCMX)
@ -295,7 +337,27 @@ uninstall-cmxa::
$(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
$(RM) -f $(PROJ_libocamldir)/$$i; \
done
endif
endif
##===- Build executables --------------------------------------------------===##
ifdef TOOLNAME
all-local:: $(OutputEXE)
clean-local:: clean-exe
$(OutputEXE): $(ToolEXE) $(OcamlDir)/.dir
$(Verb) $(CP) -f $< $@
ifndef OCAMLOPT
$(ToolEXE): $(ObjectsCMO) $(OcamlDir)/.dir
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.EXE) $@ $<
else
$(ToolEXE): $(ObjectsCMX) $(OcamlDir)/.dir
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.EXE) $@ $<
endif
endif
##===- Generate documentation ---------------------------------------------===##
@ -325,7 +387,10 @@ printcamlvars::
$(Echo) "LibraryCMA : " '$(LibraryCMA)'
$(Echo) "LibraryCMXA : " '$(LibraryCMXA)'
$(Echo) "OcamlSources1: " '$(OcamlSources1)'
$(Echo) "OcamlSources2: " '$(OcamlSources2)'
$(Echo) "OcamlSources : " '$(OcamlSources)'
$(Echo) "OcamlHeaders1: " '$(OcamlHeaders1)'
$(Echo) "OcamlHeaders2: " '$(OcamlHeaders2)'
$(Echo) "OcamlHeaders : " '$(OcamlHeaders)'
$(Echo) "ObjectsCMI : " '$(ObjectsCMI)'
$(Echo) "ObjectsCMO : " '$(ObjectsCMO)'
@ -340,4 +405,6 @@ printcamlvars::
.PHONY: printcamlvars build-cmis \
clean-a clean-cmis clean-cma clean-cmxa \
install-a install-cmis install-cma install-cmxa \
uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa
install-exe \
uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa \
uninstall-exe

View file

@ -86,6 +86,7 @@
<li><a href="#targetimpls">Target-specific Implementation Notes</a>
<ul>
<li><a href="#tailcallopt">Tail call optimization</a></li>
<li><a href="#sibcallopt">Sibling call optimization</a></li>
<li><a href="#x86">The X86 backend</a></li>
<li><a href="#ppc">The PowerPC backend</a>
<ul>
@ -1731,6 +1732,50 @@ define fastcc i32 @tailcaller(i32 %in1, i32 %in2) {
(because one or more of above constraints are not met) to be followed by a
readjustment of the stack. So performance might be worse in such cases.</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="sibcallopt">Sibling call optimization</a>
</div>
<div class="doc_text">
<p>Sibling call optimization is a restricted form of tail call optimization.
Unlike tail call optimization described in the previous section, it can be
performed automatically on any tail calls when <tt>-tailcallopt</tt> option
is not specified.</p>
<p>Sibling call optimization is currently performed on x86/x86-64 when the
following constraints are met:</p>
<ul>
<li>Caller and callee have the same calling convention. It can be either
<tt>c</tt> or <tt>fastcc</tt>.
<li>The call is a tail call - in tail position (ret immediately follows call
and ret uses value of call or is void).</li>
<li>Caller and callee have matching return type or the callee result is not
used.
<li>If any of the callee arguments are being passed in stack, they must be
available in caller's own incoming argument stack and the frame offsets
must be the same.
</ul>
<p>Example:</p>
<div class="doc_code">
<pre>
declare i32 @bar(i32, i32)
define i32 @foo(i32 %a, i32 %b, i32 %c) {
entry:
%0 = tail call i32 @bar(i32 %a, i32 %b)
ret i32 %0
}
</pre>
</div>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
@ -2116,7 +2161,7 @@ MOVSX32rm16 -&gt; movsx, 32-bit register, 16-bit memory
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
Last modified: $Date: 2010-03-08 22:05:02 +0100 (Mon, 08 Mar 2010) $
</address>
</body>

View file

@ -5149,8 +5149,11 @@ Loop: ; Infinite loop that counts from 0 on up...
a <a href="#i_ret"><tt>ret</tt></a> instruction. If the "tail" marker is
present, the function call is eligible for tail call optimization,
but <a href="CodeGenerator.html#tailcallopt">might not in fact be
optimized into a jump</a>. As of this writing, the extra requirements for
a call to actually be optimized are:
optimized into a jump</a>. The code generator may optimize calls marked
"tail" with either 1) automatic <a href="CodeGenerator.html#sibcallopt">
sibling call optimization</a> when the caller and callee have
matching signatures, or 2) forced tail call optimization when the
following extra requirements are met:
<ul>
<li>Caller and callee both have the calling
convention <tt>fastcc</tt>.</li>
@ -7470,7 +7473,7 @@ LLVM</a>.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-03-05 00:44:48 +0100 (Fri, 05 Mar 2010) $
Last modified: $Date: 2010-03-08 22:05:02 +0100 (Mon, 08 Mar 2010) $
</address>
</body>

View file

@ -25,6 +25,7 @@
<li><a href="#debug_info_descriptors">Debug information descriptors</a>
<ul>
<li><a href="#format_compile_units">Compile unit descriptors</a></li>
<li><a href="#format_files">File descriptors</a></li>
<li><a href="#format_global_variables">Global variable descriptors</a></li>
<li><a href="#format_subprograms">Subprogram descriptors</a></li>
<li><a href="#format_blocks">Block descriptors</a></li>
@ -255,7 +256,7 @@ height="369">
<p>To provide basic functionality, the LLVM debugger does have to make some
assumptions about the source-level language being debugged, though it keeps
these to a minimum. The only common features that the LLVM debugger assumes
exist are <a href="#format_compile_units">source files</a>,
exist are <a href="#format_files">source files</a>,
and <a href="#format_global_variables">program objects</a>. These abstract
objects are used by a debugger to form stack traces, show information about
local variables, etc.</p>
@ -307,8 +308,8 @@ height="369">
of tags are loosely bound to the tag values of DWARF information entries.
However, that does not restrict the use of the information supplied to DWARF
targets. To facilitate versioning of debug information, the tag is augmented
with the current debug version (LLVMDebugVersion = 7 << 16 or 0x70000 or
458752.)</a></p>
with the current debug version (LLVMDebugVersion = 8 << 16 or 0x80000 or
524288.)</a></p>
<p>The details of the various descriptors follow.</p>
@ -346,18 +347,36 @@ height="369">
that produced it.</p>
<p>Compile unit descriptors provide the root context for objects declared in a
specific source file. Global variables and top level functions would be
defined using this context. Compile unit descriptors also provide context
for source line correspondence.</p>
specific compilation unit. File descriptors are defined using this context.</p>
<p>Each input file is encoded as a separate compile unit in LLVM debugging
information output. However, many target specific tool chains prefer to
encode only one compile unit in an object file. In this situation, the LLVM
code generator will include debugging information entities in the compile
unit that is marked as main compile unit. The code generator accepts maximum
one main compile unit per module. If a module does not contain any main
compile unit then the code generator will emit multiple compile units in the
output object file.</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsubsection">
<a name="format_files">File descriptors</a>
</div>
<div class="doc_text">
<div class="doc_code">
<pre>
!0 = metadata !{
i32, ;; Tag = 41 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a>
;; (DW_TAG_file_type)
metadata, ;; Source file name
metadata, ;; Source file directory (includes trailing slash)
metadata ;; Reference to compile unit where defined
}
</pre>
</div>
<p>These descriptors contain informations for a file. Global variables and top
level functions would be defined using this context.k File descriptors also
provide context for source line correspondence. </p>
<p>Each input file is encoded as a separate file descriptor in LLVM debugging
information output. Each file descriptor would be defined using a
compile unit. </p>
</div>
@ -378,7 +397,7 @@ height="369">
metadata, ;; Name
metadata, ;; Display name (fully qualified C++ name)
metadata, ;; MIPS linkage name (for C++)
metadata, ;; Reference to compile unit where defined
metadata, ;; Reference to file where defined
i32, ;; Line number where defined
metadata, ;; Reference to type descriptor
i1, ;; True if the global is local to compile unit (static)
@ -410,7 +429,7 @@ provide details such as name, type and where the variable is defined.</p>
metadata, ;; Name
metadata, ;; Display name (fully qualified C++ name)
metadata, ;; MIPS linkage name (for C++)
metadata, ;; Reference to compile unit where defined
metadata, ;; Reference to file where defined
i32, ;; Line number where defined
metadata, ;; Reference to type descriptor
i1, ;; True if the global is local to compile unit (static)
@ -461,7 +480,7 @@ provide details such as name, type and where the variable is defined.</p>
;; (DW_TAG_base_type)
metadata, ;; Reference to context (typically a compile unit)
metadata, ;; Name (may be "" for anonymous types)
metadata, ;; Reference to compile unit where defined (may be NULL)
metadata, ;; Reference to file where defined (may be NULL)
i32, ;; Line number where defined (may be 0)
i64, ;; Size in bits
i64, ;; Alignment in bits
@ -512,7 +531,7 @@ DW_ATE_unsigned_char = 8
i32, ;; Tag (see below)
metadata, ;; Reference to context
metadata, ;; Name (may be "" for anonymous types)
metadata, ;; Reference to compile unit where defined (may be NULL)
metadata, ;; Reference to file where defined (may be NULL)
i32, ;; Line number where defined (may be 0)
i32, ;; Size in bits
i32, ;; Alignment in bits
@ -580,7 +599,7 @@ DW_TAG_restrict_type = 55
i32, ;; Tag (see below)
metadata, ;; Reference to context
metadata, ;; Name (may be "" for anonymous types)
metadata, ;; Reference to compile unit where defined (may be NULL)
metadata, ;; Reference to file where defined (may be NULL)
i32, ;; Line number where defined (may be 0)
i64, ;; Size in bits
i64, ;; Alignment in bits
@ -715,7 +734,7 @@ DW_TAG_inheritance = 28
i32, ;; Tag (see below)
metadata, ;; Context
metadata, ;; Name
metadata, ;; Reference to compile unit where defined
metadata, ;; Reference to file where defined
i32, ;; Line number where defined
metadata ;; Type descriptor
}
@ -1012,10 +1031,10 @@ int main(int argc, char *argv[]) {
<pre>
...
;;
;; Define the compile unit for the source file "/Users/mine/sources/MySource.cpp".
;; Define the compile unit for the main source file "/Users/mine/sources/MySource.cpp".
;;
!3 = metadata !{
i32 458769, ;; Tag
!2 = metadata !{
i32 524305, ;; Tag
i32 0, ;; Unused
i32 4, ;; Language Id
metadata !"MySource.cpp",
@ -1027,19 +1046,24 @@ int main(int argc, char *argv[]) {
i32 0} ;; Runtime version
;;
;; Define the compile unit for the header file "/Users/mine/sources/MyHeader.h".
;; Define the file for the file "/Users/mine/sources/MySource.cpp".
;;
!1 = metadata !{
i32 458769, ;; Tag
i32 0, ;; Unused
i32 4, ;; Language Id
metadata !"MyHeader.h",
i32 524329, ;; Tag
metadata !"MySource.cpp",
metadata !"/Users/mine/sources",
metadata !"4.2.1 (Based on Apple Inc. build 5649) (LLVM build 00)",
i1 false, ;; Main Compile Unit
i1 false, ;; Optimized compile unit
metadata !"", ;; Compiler flags
i32 0} ;; Runtime version
metadata !3 ;; Compile unit
}
;;
;; Define the file for the file "/Users/mine/sources/Myheader.h"
;;
!3 = metadata !{
i32 524329, ;; Tag
metadata !"Myheader.h"
metadata !"/Users/mine/sources",
metadata !3 ;; Compile unit
}
...
</pre>
@ -1081,15 +1105,15 @@ int MyGlobal = 100;
;; variable anchor and the global variable itself.
;;
!0 = metadata !{
i32 458804, ;; Tag
i32 524340, ;; Tag
i32 0, ;; Unused
metadata !1, ;; Context
metadata !"MyGlobal", ;; Name
metadata !"MyGlobal", ;; Display Name
metadata !"MyGlobal", ;; Linkage Name
metadata !1, ;; Compile Unit
metadata !3, ;; Compile Unit
i32 1, ;; Line Number
metadata !2, ;; Type
metadata !4, ;; Type
i1 false, ;; Is a local variable
i1 true, ;; Is this a definition
i32* @MyGlobal ;; The global variable
@ -1099,11 +1123,11 @@ int MyGlobal = 100;
;; Define the basic type of 32 bit signed integer. Note that since int is an
;; intrinsic type the source file is NULL and line 0.
;;
!2 = metadata !{
i32 458788, ;; Tag
!4 = metadata !{
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"int", ;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@ -1143,16 +1167,16 @@ int main(int argc, char *argv[]) {
;; anchor is 46, which is the same as the tag for subprograms
;; (46 = DW_TAG_subprogram.)
;;
!0 = metadata !{
i32 458798, ;; Tag
!6 = metadata !{
i32 524334, ;; Tag
i32 0, ;; Unused
metadata !1, ;; Context
metadata !"main", ;; Name
metadata !"main", ;; Display name
metadata !"main", ;; Linkage name
metadata !1, ;; Compile unit
metadata !1, ;; File
i32 1, ;; Line number
metadata !2, ;; Type
metadata !4, ;; Type
i1 false, ;; Is local
i1 true ;; Is definition
}
@ -1188,10 +1212,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"bool", ;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 8, ;; Size in Bits
i64 8, ;; Align in Bits
@ -1214,10 +1238,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"char", ;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 8, ;; Size in Bits
i64 8, ;; Align in Bits
@ -1240,10 +1264,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"unsigned char",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 8, ;; Size in Bits
i64 8, ;; Align in Bits
@ -1266,10 +1290,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"short int",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 16, ;; Size in Bits
i64 16, ;; Align in Bits
@ -1292,10 +1316,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"short unsigned int",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 16, ;; Size in Bits
i64 16, ;; Align in Bits
@ -1318,10 +1342,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"int", ;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@ -1343,10 +1367,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"unsigned int",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@ -1369,10 +1393,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"long long int",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in Bits
i64 64, ;; Align in Bits
@ -1395,10 +1419,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"long long unsigned int",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in Bits
i64 64, ;; Align in Bits
@ -1421,10 +1445,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"float",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@ -1447,10 +1471,10 @@ define i32 @main(i32 %argc, i8** %argv) {
<div class="doc_code">
<pre>
!2 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"double",;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in Bits
i64 64, ;; Align in Bits
@ -1486,10 +1510,10 @@ typedef const int *IntPtr;
;; Define the typedef "IntPtr".
;;
!2 = metadata !{
i32 458774, ;; Tag
i32 524310, ;; Tag
metadata !1, ;; Context
metadata !"IntPtr", ;; Name
metadata !3, ;; Compile unit
metadata !3, ;; File
i32 0, ;; Line number
i64 0, ;; Size in bits
i64 0, ;; Align in bits
@ -1502,10 +1526,10 @@ typedef const int *IntPtr;
;; Define the pointer type.
;;
!4 = metadata !{
i32 458767, ;; Tag
i32 524303, ;; Tag
metadata !1, ;; Context
metadata !"", ;; Name
metadata !1, ;; Compile unit
metadata !1, ;; File
i32 0, ;; Line number
i64 64, ;; Size in bits
i64 64, ;; Align in bits
@ -1517,10 +1541,10 @@ typedef const int *IntPtr;
;; Define the const type.
;;
!5 = metadata !{
i32 458790, ;; Tag
i32 524326, ;; Tag
metadata !1, ;; Context
metadata !"", ;; Name
metadata !1, ;; Compile unit
metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@ -1532,10 +1556,10 @@ typedef const int *IntPtr;
;; Define the int type.
;;
!6 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"int", ;; Name
metadata !1, ;; Compile unit
metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@ -1575,10 +1599,10 @@ struct Color {
;; Define basic type for unsigned int.
;;
!5 = metadata !{
i32 458788, ;; Tag
i32 524324, ;; Tag
metadata !1, ;; Context
metadata !"unsigned int",
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 0, ;; Line number
i64 32, ;; Size in Bits
i64 32, ;; Align in Bits
@ -1590,7 +1614,7 @@ struct Color {
;; Define composite type for struct Color.
;;
!2 = metadata !{
i32 458771, ;; Tag
i32 524307, ;; Tag
metadata !1, ;; Context
metadata !"Color", ;; Name
metadata !1, ;; Compile unit
@ -1608,10 +1632,10 @@ struct Color {
;; Define the Red field.
;;
!4 = metadata !{
i32 458765, ;; Tag
i32 524301, ;; Tag
metadata !1, ;; Context
metadata !"Red", ;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 2, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@ -1624,10 +1648,10 @@ struct Color {
;; Define the Green field.
;;
!6 = metadata !{
i32 458765, ;; Tag
i32 524301, ;; Tag
metadata !1, ;; Context
metadata !"Green", ;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 3, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@ -1640,10 +1664,10 @@ struct Color {
;; Define the Blue field.
;;
!7 = metadata !{
i32 458765, ;; Tag
i32 524301, ;; Tag
metadata !1, ;; Context
metadata !"Blue", ;; Name
metadata !1, ;; Compile Unit
metadata !1, ;; File
i32 4, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@ -1688,10 +1712,10 @@ enum Trees {
;; Define composite type for enum Trees
;;
!2 = metadata !{
i32 458756, ;; Tag
i32 524292, ;; Tag
metadata !1, ;; Context
metadata !"Trees", ;; Name
metadata !1, ;; Compile unit
metadata !1, ;; File
i32 1, ;; Line number
i64 32, ;; Size in bits
i64 32, ;; Align in bits
@ -1710,17 +1734,17 @@ enum Trees {
;;
;; Define Spruce enumerator.
;;
!4 = metadata !{i32 458792, metadata !"Spruce", i64 100}
!4 = metadata !{i32 524328, metadata !"Spruce", i64 100}
;;
;; Define Oak enumerator.
;;
!5 = metadata !{i32 458792, metadata !"Oak", i64 200}
!5 = metadata !{i32 524328, metadata !"Oak", i64 200}
;;
;; Define Maple enumerator.
;;
!6 = metadata !{i32 458792, metadata !"Maple", i64 300}
!6 = metadata !{i32 524328, metadata !"Maple", i64 300}
</pre>
</div>
@ -1738,7 +1762,7 @@ enum Trees {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-01-11 23:53:48 +0100 (Mon, 11 Jan 2010) $
Last modified: $Date: 2010-03-09 01:44:10 +0100 (Tue, 09 Mar 2010) $
</address>
</body>

View file

@ -909,16 +909,22 @@ finalization.</p>
<p>A <tt>MachineFunctionPass</tt> is a part of the LLVM code generator that
executes on the machine-dependent representation of each LLVM function in the
program. A <tt>MachineFunctionPass</tt> is also a <tt>FunctionPass</tt>, so all
program.</p>
<p>Code generator passes are registered and initialized specially by
<tt>TargetMachine::addPassesToEmitFile</tt> and similar routines, so they
cannot generally be run from the <tt>opt</tt> or <tt>bugpoint</tt>
commands.</p>
<p>A <tt>MachineFunctionPass</tt> is also a <tt>FunctionPass</tt>, so all
the restrictions that apply to a <tt>FunctionPass</tt> also apply to it.
<tt>MachineFunctionPass</tt>es also have additional restrictions. In particular,
<tt>MachineFunctionPass</tt>es are not allowed to do any of the following:</p>
<ol>
<li>Modify any LLVM Instructions, BasicBlocks or Functions.</li>
<li>Modify or create any LLVM IR Instructions, BasicBlocks, Arguments,
Functions, GlobalVariables, GlobalAliases, or Modules.</li>
<li>Modify a MachineFunction other than the one currently being processed.</li>
<li>Add or remove MachineFunctions from the current Module.</li>
<li>Add or remove global variables from the current Module.</li>
<li>Maintain state across invocations of <a
href="#runOnMachineFunction"><tt>runOnMachineFunction</tt></a> (including global
data)</li>
@ -1829,7 +1835,7 @@ Despite that, we have kept the LLVM passes SMP ready, and you should too.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-02-18 15:37:52 +0100 (Thu, 18 Feb 2010) $
Last modified: $Date: 2010-03-10 02:29:39 +0100 (Wed, 10 Mar 2010) $
</address>
</body>

View file

@ -98,6 +98,7 @@ exception Error of string
let the_module = create_module (global_context ()) "my cool jit"
let builder = builder (global_context ())
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
let double_type = double_type context
</pre>
</div>
@ -389,7 +390,7 @@ that there is an LLVM Function object that is ready to go for us.</p>
<div class="doc_code">
<pre>
(* Create a new basic block to start insertion into. *)
let bb = append_block "entry" the_function in
let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@ -903,6 +904,7 @@ let context = global_context ()
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
let double_type = double_type context
let rec codegen_expr = function
| Ast.Number n -&gt; const_float double_type n
@ -974,7 +976,7 @@ let codegen_func = function
let the_function = codegen_proto proto in
(* Create a new basic block to start insertion into. *)
let bb = append_block "entry" the_function in
let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@ -1085,7 +1087,7 @@ main ()
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
Last modified: $Date: 2010-03-08 20:32:18 +0100 (Mon, 08 Mar 2010) $
</address>
</body>
</html>

View file

@ -186,9 +186,8 @@ add a set of optimizations to run. The code looks like this:</p>
<div class="doc_code">
<pre>
(* Create the JIT. *)
let the_module_provider = ModuleProvider.create Codegen.the_module in
let the_execution_engine = ExecutionEngine.create the_module_provider in
let the_fpm = PassManager.create_function the_module_provider in
let the_execution_engine = ExecutionEngine.create Codegen.the_module in
let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
@ -213,18 +212,11 @@ add a set of optimizations to run. The code looks like this:</p>
</pre>
</div>
<p>This code defines two values, an <tt>Llvm.llmoduleprovider</tt> and a
<tt>Llvm.PassManager.t</tt>. The former is basically a wrapper around our
<tt>Llvm.llmodule</tt> that the <tt>Llvm.PassManager.t</tt> requires. It
provides certain flexibility that we're not going to take advantage of here,
so I won't dive into any details about it.</p>
<p>The meat of the matter here, is the definition of "<tt>the_fpm</tt>". It
requires a pointer to the <tt>the_module</tt> (through the
<tt>the_module_provider</tt>) to construct itself. Once it is set up, we use a
series of "add" calls to add a bunch of LLVM passes. The first pass is
basically boilerplate, it adds a pass so that later optimizations know how the
data structures in the program are laid out. The
requires a pointer to the <tt>the_module</tt> to construct itself. Once it is
set up, we use a series of "add" calls to add a bunch of LLVM passes. The
first pass is basically boilerplate, it adds a pass so that later optimizations
know how the data structures in the program are laid out. The
"<tt>the_execution_engine</tt>" variable is related to the JIT, which we will
get to in the next section.</p>
@ -320,8 +312,7 @@ by adding a global variable and a call in <tt>main</tt>:</p>
let main () =
...
<b>(* Create the JIT. *)
let the_module_provider = ModuleProvider.create Codegen.the_module in
let the_execution_engine = ExecutionEngine.create the_module_provider in</b>
let the_execution_engine = ExecutionEngine.create Codegen.the_module in</b>
...
</pre>
</div>
@ -351,7 +342,7 @@ can change the code that parses a top-level expression to look like this:</p>
the_execution_engine in
print_string "Evaluated to ";
print_float (GenericValue.as_float double_type result);
print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
</pre>
</div>
@ -796,6 +787,7 @@ let context = global_context ()
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
let double_type = double_type context
let rec codegen_expr = function
| Ast.Number n -&gt; const_float double_type n
@ -867,7 +859,7 @@ let codegen_func the_fpm = function
let the_function = codegen_proto proto in
(* Create a new basic block to start insertion into. *)
let bb = append_block "entry" the_function in
let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@ -932,7 +924,7 @@ let rec main_loop the_fpm the_execution_engine stream =
the_execution_engine in
print_string "Evaluated to ";
print_float (GenericValue.as_float double_type result);
print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s -&gt;
(* Skip token for error recovery. *)
@ -971,16 +963,15 @@ let main () =
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
let the_module_provider = ModuleProvider.create Codegen.the_module in
let the_execution_engine = ExecutionEngine.create the_module_provider in
let the_fpm = PassManager.create_function the_module_provider in
let the_execution_engine = ExecutionEngine.create Codegen.the_module in
let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combining the_fpm;
add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation the_fpm;
@ -1032,7 +1023,7 @@ extern double putchard(double X) {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
Last modified: $Date: 2010-03-08 20:32:18 +0100 (Mon, 08 Mar 2010) $
</address>
</body>
</html>

View file

@ -364,7 +364,7 @@ value as a 1-bit (bool) value.</p>
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
let then_bb = append_block "then" the_function in
let then_bb = append_block context "then" the_function in
position_at_end then_bb builder;
</pre>
</div>
@ -417,7 +417,7 @@ up-to-date value for code that will set up the Phi node.</p>
<div class="doc_code">
<pre>
(* Emit 'else' value. *)
let else_bb = append_block "else" the_function in
let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@ -433,7 +433,7 @@ the 'then' block.</p>
<div class="doc_code">
<pre>
(* Emit merge block. *)
let merge_bb = append_block "ifcont" the_function in
let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@ -704,7 +704,7 @@ block, but remember that the body code itself could consist of multiple blocks
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
let loop_bb = append_block "loop" the_function in
let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@ -804,7 +804,7 @@ statement.</p>
<pre>
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
let after_bb = append_block "afterloop" the_function in
let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@ -1204,6 +1204,7 @@ let context = global_context ()
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
let double_type = double_type context
let rec codegen_expr = function
| Ast.Number n -&gt; const_float double_type n
@ -1250,7 +1251,7 @@ let rec codegen_expr = function
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
let then_bb = append_block "then" the_function in
let then_bb = append_block context "then" the_function in
(* Emit 'then' value. *)
position_at_end then_bb builder;
@ -1262,7 +1263,7 @@ let rec codegen_expr = function
let new_then_bb = insertion_block builder in
(* Emit 'else' value. *)
let else_bb = append_block "else" the_function in
let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@ -1271,7 +1272,7 @@ let rec codegen_expr = function
let new_else_bb = insertion_block builder in
(* Emit merge block. *)
let merge_bb = append_block "ifcont" the_function in
let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@ -1297,7 +1298,7 @@ let rec codegen_expr = function
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
let loop_bb = append_block "loop" the_function in
let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@ -1341,7 +1342,7 @@ let rec codegen_expr = function
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
let after_bb = append_block "afterloop" the_function in
let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@ -1397,7 +1398,7 @@ let codegen_func the_fpm = function
let the_function = codegen_proto proto in
(* Create a new basic block to start insertion into. *)
let bb = append_block "entry" the_function in
let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@ -1462,7 +1463,7 @@ let rec main_loop the_fpm the_execution_engine stream =
the_execution_engine in
print_string "Evaluated to ";
print_float (GenericValue.as_float double_type result);
print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s -&gt;
(* Skip token for error recovery. *)
@ -1501,16 +1502,15 @@ let main () =
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
let the_module_provider = ModuleProvider.create Codegen.the_module in
let the_execution_engine = ExecutionEngine.create the_module_provider in
let the_fpm = PassManager.create_function the_module_provider in
let the_execution_engine = ExecutionEngine.create Codegen.the_module in
let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combining the_fpm;
add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation the_fpm;
@ -1563,7 +1563,7 @@ operators</a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
Last modified: $Date: 2010-03-08 20:32:18 +0100 (Mon, 08 Mar 2010) $
</address>
</body>
</html>

View file

@ -300,7 +300,7 @@ let codegen_func the_fpm = function
end;</b>
(* Create a new basic block to start insertion into. *)
let bb = append_block "entry" the_function in
let bb = append_block context "entry" the_function in
position_at_end bb builder;
...
</pre>
@ -1177,6 +1177,7 @@ let context = global_context ()
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
let double_type = double_type context
let rec codegen_expr = function
| Ast.Number n -&gt; const_float double_type n
@ -1241,7 +1242,7 @@ let rec codegen_expr = function
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
let then_bb = append_block "then" the_function in
let then_bb = append_block context "then" the_function in
(* Emit 'then' value. *)
position_at_end then_bb builder;
@ -1253,7 +1254,7 @@ let rec codegen_expr = function
let new_then_bb = insertion_block builder in
(* Emit 'else' value. *)
let else_bb = append_block "else" the_function in
let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@ -1262,7 +1263,7 @@ let rec codegen_expr = function
let new_else_bb = insertion_block builder in
(* Emit merge block. *)
let merge_bb = append_block "ifcont" the_function in
let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@ -1288,7 +1289,7 @@ let rec codegen_expr = function
* block. *)
let preheader_bb = insertion_block builder in
let the_function = block_parent preheader_bb in
let loop_bb = append_block "loop" the_function in
let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@ -1332,7 +1333,7 @@ let rec codegen_expr = function
(* Create the "after loop" block and insert it. *)
let loop_end_bb = insertion_block builder in
let after_bb = append_block "afterloop" the_function in
let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@ -1396,7 +1397,7 @@ let codegen_func the_fpm = function
end;
(* Create a new basic block to start insertion into. *)
let bb = append_block "entry" the_function in
let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@ -1461,7 +1462,7 @@ let rec main_loop the_fpm the_execution_engine stream =
the_execution_engine in
print_string "Evaluated to ";
print_float (GenericValue.as_float double_type result);
print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s -&gt;
(* Skip token for error recovery. *)
@ -1500,16 +1501,15 @@ let main () =
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
let the_module_provider = ModuleProvider.create Codegen.the_module in
let the_execution_engine = ExecutionEngine.create the_module_provider in
let the_fpm = PassManager.create_function the_module_provider in
let the_execution_engine = ExecutionEngine.create Codegen.the_module in
let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combining the_fpm;
add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation the_fpm;
@ -1568,7 +1568,7 @@ SSA construction</a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
Last modified: $Date: 2010-03-08 20:32:18 +0100 (Mon, 08 Mar 2010) $
</address>
</body>
</html>

View file

@ -543,7 +543,7 @@ good codegen once again:</p>
<pre>
let main () =
...
let the_fpm = PassManager.create_function the_module_provider in
let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
@ -1388,6 +1388,7 @@ let context = global_context ()
let the_module = create_module context "my cool jit"
let builder = builder context
let named_values:(string, llvalue) Hashtbl.t = Hashtbl.create 10
let double_type = double_type context
(* Create an alloca instruction in the entry block of the function. This
* is used for mutable variables etc. *)
@ -1482,7 +1483,7 @@ let rec codegen_expr = function
let start_bb = insertion_block builder in
let the_function = block_parent start_bb in
let then_bb = append_block "then" the_function in
let then_bb = append_block context "then" the_function in
(* Emit 'then' value. *)
position_at_end then_bb builder;
@ -1494,7 +1495,7 @@ let rec codegen_expr = function
let new_then_bb = insertion_block builder in
(* Emit 'else' value. *)
let else_bb = append_block "else" the_function in
let else_bb = append_block context "else" the_function in
position_at_end else_bb builder;
let else_val = codegen_expr else_ in
@ -1503,7 +1504,7 @@ let rec codegen_expr = function
let new_else_bb = insertion_block builder in
(* Emit merge block. *)
let merge_bb = append_block "ifcont" the_function in
let merge_bb = append_block context "ifcont" the_function in
position_at_end merge_bb builder;
let incoming = [(then_val, new_then_bb); (else_val, new_else_bb)] in
let phi = build_phi incoming "iftmp" builder in
@ -1555,7 +1556,7 @@ let rec codegen_expr = function
(* Make the new basic block for the loop header, inserting after current
* block. *)
let loop_bb = append_block "loop" the_function in
let loop_bb = append_block context "loop" the_function in
(* Insert an explicit fall through from the current block to the
* loop_bb. *)
@ -1599,7 +1600,7 @@ let rec codegen_expr = function
let end_cond = build_fcmp Fcmp.One end_cond zero "loopcond" builder in
(* Create the "after loop" block and insert it. *)
let after_bb = append_block "afterloop" the_function in
let after_bb = append_block context "afterloop" the_function in
(* Insert the conditional branch into the end of loop_end_bb. *)
ignore (build_cond_br end_cond loop_bb after_bb builder);
@ -1723,7 +1724,7 @@ let codegen_func the_fpm = function
end;
(* Create a new basic block to start insertion into. *)
let bb = append_block "entry" the_function in
let bb = append_block context "entry" the_function in
position_at_end bb builder;
try
@ -1791,7 +1792,7 @@ let rec main_loop the_fpm the_execution_engine stream =
the_execution_engine in
print_string "Evaluated to ";
print_float (GenericValue.as_float double_type result);
print_float (GenericValue.as_float Codegen.double_type result);
print_newline ();
with Stream.Error s | Codegen.Error s -&gt;
(* Skip token for error recovery. *)
@ -1831,9 +1832,8 @@ let main () =
let stream = Lexer.lex (Stream.of_channel stdin) in
(* Create the JIT. *)
let the_module_provider = ModuleProvider.create Codegen.the_module in
let the_execution_engine = ExecutionEngine.create the_module_provider in
let the_fpm = PassManager.create_function the_module_provider in
let the_execution_engine = ExecutionEngine.create Codegen.the_module in
let the_fpm = PassManager.create_function Codegen.the_module in
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
@ -1843,7 +1843,7 @@ let main () =
add_memory_to_register_promotion the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combining the_fpm;
add_instruction_combination the_fpm;
(* reassociate expressions. *)
add_reassociation the_fpm;
@ -1901,7 +1901,7 @@ extern double printd(double X) {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
Last modified: $Date: 2010-03-08 20:32:18 +0100 (Mon, 08 Mar 2010) $
</address>
</body>
</html>

View file

@ -25,4 +25,8 @@ ifeq ($(LLVM_ON_UNIX),1)
endif
endif
ifeq ($(filter $(BINDINGS_TO_BUILD),ocaml),ocaml)
PARALLEL_DIRS += OCaml-Kaleidoscope
endif
include $(LEVEL)/Makefile.common

View file

@ -344,7 +344,7 @@ namespace llvm {
/// 1.01E-2 4 1 1.01E-2
void toString(SmallVectorImpl<char> &Str,
unsigned FormatPrecision = 0,
unsigned FormatMaxPadding = 3);
unsigned FormatMaxPadding = 3) const;
private:

View file

@ -192,6 +192,13 @@ public:
return true;
}
void swap(DenseMap& RHS) {
std::swap(NumBuckets, RHS.NumBuckets);
std::swap(Buckets, RHS.Buckets);
std::swap(NumEntries, RHS.NumEntries);
std::swap(NumTombstones, RHS.NumTombstones);
}
value_type& FindAndConstruct(const KeyT &Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))

View file

@ -45,6 +45,10 @@ public:
return TheMap.erase(V);
}
void swap(DenseSet& RHS) {
TheMap.swap(RHS.TheMap);
}
DenseSet &operator=(const DenseSet &RHS) {
TheMap = RHS.TheMap;
return *this;
@ -55,6 +59,12 @@ public:
class Iterator {
typename MapTy::iterator I;
public:
typedef typename MapTy::iterator::difference_type difference_type;
typedef ValueT value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef std::forward_iterator_tag iterator_category;
Iterator(const typename MapTy::iterator &i) : I(i) {}
ValueT& operator*() { return I->first; }
@ -68,6 +78,12 @@ public:
class ConstIterator {
typename MapTy::const_iterator I;
public:
typedef typename MapTy::const_iterator::difference_type difference_type;
typedef ValueT value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef std::forward_iterator_tag iterator_category;
ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
const ValueT& operator*() { return I->first; }

View file

@ -44,11 +44,6 @@ namespace llvm {
protected:
MDNode *DbgNode;
/// DIDescriptor constructor. If the specified node is non-null, check
/// to make sure that the tag in the descriptor matches 'RequiredTag'. If
/// not, the debug info is corrupt and we ignore it.
DIDescriptor(MDNode *N, unsigned RequiredTag);
StringRef getStringField(unsigned Elt) const;
unsigned getUnsignedField(unsigned Elt) const {
return (unsigned)getUInt64Field(Elt);
@ -67,7 +62,7 @@ namespace llvm {
explicit DIDescriptor() : DbgNode(0) {}
explicit DIDescriptor(MDNode *N) : DbgNode(N) {}
bool isNull() const { return DbgNode == 0; }
bool Verify() const { return DbgNode != 0; }
MDNode *getNode() const { return DbgNode; }
@ -92,6 +87,7 @@ namespace llvm {
bool isSubprogram() const;
bool isGlobalVariable() const;
bool isScope() const;
bool isFile() const;
bool isCompileUnit() const;
bool isNameSpace() const;
bool isLexicalBlock() const;
@ -104,8 +100,7 @@ namespace llvm {
/// DISubrange - This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
public:
explicit DISubrange(MDNode *N = 0)
: DIDescriptor(N, dwarf::DW_TAG_subrange_type) {}
explicit DISubrange(MDNode *N = 0) : DIDescriptor(N) {}
int64_t getLo() const { return (int64_t)getUInt64Field(1); }
int64_t getHi() const { return (int64_t)getUInt64Field(2); }
@ -126,10 +121,7 @@ namespace llvm {
/// DIScope - A base class for various scopes.
class DIScope : public DIDescriptor {
public:
explicit DIScope(MDNode *N = 0) : DIDescriptor (N) {
if (DbgNode && !isScope())
DbgNode = 0;
}
explicit DIScope(MDNode *N = 0) : DIDescriptor (N) {}
virtual ~DIScope() {}
StringRef getFilename() const;
@ -139,10 +131,7 @@ namespace llvm {
/// DICompileUnit - A wrapper for a compile unit.
class DICompileUnit : public DIScope {
public:
explicit DICompileUnit(MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isCompileUnit())
DbgNode = 0;
}
explicit DICompileUnit(MDNode *N = 0) : DIScope(N) {}
unsigned getLanguage() const { return getUnsignedField(2); }
StringRef getFilename() const { return getStringField(3); }
@ -170,13 +159,24 @@ namespace llvm {
void dump() const;
};
/// DIFile - This is a wrapper for a file.
class DIFile : public DIScope {
public:
explicit DIFile(MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isFile())
DbgNode = 0;
}
StringRef getFilename() const { return getStringField(1); }
StringRef getDirectory() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
};
/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
/// FIXME: it seems strange that this doesn't have either a reference to the
/// type/precision or a file/line pair for location info.
class DIEnumerator : public DIDescriptor {
public:
explicit DIEnumerator(MDNode *N = 0)
: DIDescriptor(N, dwarf::DW_TAG_enumerator) {}
explicit DIEnumerator(MDNode *N = 0) : DIDescriptor(N) {}
StringRef getName() const { return getStringField(1); }
uint64_t getEnumValue() const { return getUInt64Field(2); }
@ -185,7 +185,7 @@ namespace llvm {
/// DIType - This is a wrapper for a type.
/// FIXME: Types should be factored much better so that CV qualifiers and
/// others do not require a huge and empty descriptor full of zeros.
class DIType : public DIDescriptor {
class DIType : public DIScope {
public:
enum {
FlagPrivate = 1 << 0,
@ -199,11 +199,9 @@ namespace llvm {
};
protected:
DIType(MDNode *N, unsigned Tag)
: DIDescriptor(N, Tag) {}
// This ctor is used when the Tag has already been validated by a derived
// ctor.
DIType(MDNode *N, bool, bool) : DIDescriptor(N) {}
DIType(MDNode *N, bool, bool) : DIScope(N) {}
public:
@ -214,9 +212,15 @@ namespace llvm {
explicit DIType() {}
virtual ~DIType() {}
DIDescriptor getContext() const { return getDescriptorField(1); }
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
DICompileUnit getCompileUnit() const{
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
DIFile F = getFieldAs<DIFile>(3);
return F.getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(4); }
uint64_t getSizeInBits() const { return getUInt64Field(5); }
uint64_t getAlignInBits() const { return getUInt64Field(6); }
@ -246,7 +250,11 @@ namespace llvm {
bool isArtificial() const {
return (getFlags() & FlagArtificial) != 0;
}
bool isValid() const {
return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
}
StringRef getFilename() const { return getCompileUnit().getFilename();}
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
/// dump - print type.
void dump() const;
};
@ -254,8 +262,7 @@ namespace llvm {
/// DIBasicType - A basic type, like 'int' or 'float'.
class DIBasicType : public DIType {
public:
explicit DIBasicType(MDNode *N = 0)
: DIType(N, dwarf::DW_TAG_base_type) {}
explicit DIBasicType(MDNode *N = 0) : DIType(N) {}
unsigned getEncoding() const { return getUnsignedField(9); }
@ -271,10 +278,7 @@ namespace llvm {
: DIType(N, true, true) {}
public:
explicit DIDerivedType(MDNode *N = 0)
: DIType(N, true, true) {
if (DbgNode && !isDerivedType())
DbgNode = 0;
}
: DIType(N, true, true) {}
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
@ -317,17 +321,23 @@ namespace llvm {
/// DIGlobal - This is a common class for global variables and subprograms.
class DIGlobal : public DIDescriptor {
protected:
explicit DIGlobal(MDNode *N, unsigned RequiredTag)
: DIDescriptor(N, RequiredTag) {}
explicit DIGlobal(MDNode *N) : DIDescriptor(N) {}
public:
virtual ~DIGlobal() {}
DIDescriptor getContext() const { return getDescriptorField(2); }
DIScope getContext() const { return getFieldAs<DIScope>(2); }
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(6); }
DICompileUnit getCompileUnit() const{
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
DIFile F = getFieldAs<DIFile>(6);
return F.getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(7); }
DIType getType() const { return getFieldAs<DIType>(8); }
@ -343,16 +353,19 @@ namespace llvm {
/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIScope {
public:
explicit DISubprogram(MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isSubprogram())
DbgNode = 0;
}
explicit DISubprogram(MDNode *N = 0) : DIScope(N) {}
DIDescriptor getContext() const { return getDescriptorField(2); }
DIScope getContext() const { return getFieldAs<DIScope>(2); }
StringRef getName() const { return getStringField(3); }
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(6); }
DICompileUnit getCompileUnit() const{
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
DIFile F = getFieldAs<DIFile>(6);
return F.getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(7); }
DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
@ -360,7 +373,7 @@ namespace llvm {
/// DIType or as DICompositeType.
StringRef getReturnTypeName() const {
DICompositeType DCT(getFieldAs<DICompositeType>(8));
if (!DCT.isNull()) {
if (DCT.Verify()) {
DIArray A = DCT.getTypeArray();
DIType T(A.getElement(0).getNode());
return T.getName();
@ -399,8 +412,7 @@ namespace llvm {
/// DIGlobalVariable - This is a wrapper for a global variable.
class DIGlobalVariable : public DIGlobal {
public:
explicit DIGlobalVariable(MDNode *N = 0)
: DIGlobal(N, dwarf::DW_TAG_variable) {}
explicit DIGlobalVariable(MDNode *N = 0) : DIGlobal(N) {}
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
@ -416,14 +428,17 @@ namespace llvm {
class DIVariable : public DIDescriptor {
public:
explicit DIVariable(MDNode *N = 0)
: DIDescriptor(N) {
if (DbgNode && !isVariable())
DbgNode = 0;
}
: DIDescriptor(N) {}
DIDescriptor getContext() const { return getDescriptorField(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
DIFile F = getFieldAs<DIFile>(3);
return F.getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(4); }
DIType getType() const { return getFieldAs<DIType>(5); }
@ -455,10 +470,7 @@ namespace llvm {
/// DILexicalBlock - This is a wrapper for a lexical block.
class DILexicalBlock : public DIScope {
public:
explicit DILexicalBlock(MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isLexicalBlock())
DbgNode = 0;
}
explicit DILexicalBlock(MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getDirectory() const { return getContext().getDirectory(); }
StringRef getFilename() const { return getContext().getFilename(); }
@ -469,16 +481,18 @@ namespace llvm {
/// DINameSpace - A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
public:
explicit DINameSpace(MDNode *N = 0) : DIScope(N) {
if (DbgNode && !isNameSpace())
DbgNode = 0;
}
explicit DINameSpace(MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
StringRef getDirectory() const { return getContext().getDirectory(); }
StringRef getFilename() const { return getContext().getFilename(); }
DICompileUnit getCompileUnit() const { return getFieldAs<DICompileUnit>(3);}
DICompileUnit getCompileUnit() const{
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
DIFile F = getFieldAs<DIFile>(3);
return F.getCompileUnit();
}
unsigned getLineNumber() const { return getUnsignedField(4); }
};
@ -494,6 +508,7 @@ namespace llvm {
DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
StringRef getFilename() const { return getScope().getFilename(); }
StringRef getDirectory() const { return getScope().getDirectory(); }
bool Verify() const;
};
/// DIFactory - This object assists with the construction of the various
@ -531,19 +546,22 @@ namespace llvm {
StringRef Flags = "",
unsigned RunTimeVer = 0);
/// CreateFile - Create a new descriptor for the specified file.
DIFile CreateFile(StringRef Filename, StringRef Directory, DICompileUnit CU);
/// CreateEnumerator - Create a single enumerator value.
DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val);
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name,
DICompileUnit CompileUnit, unsigned LineNumber,
DIFile F, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
unsigned Encoding);
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name,
DICompileUnit CompileUnit, unsigned LineNumber,
DIFile F, unsigned LineNumber,
Constant *SizeInBits, Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
unsigned Encoding);
@ -552,7 +570,7 @@ namespace llvm {
/// pointer, typedef, etc.
DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
uint64_t OffsetInBits, unsigned Flags,
@ -561,17 +579,18 @@ namespace llvm {
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
unsigned LineNumber,
Constant *SizeInBits, Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
DIType DerivedFrom);
StringRef Name,
DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
DIType DerivedFrom);
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@ -586,22 +605,23 @@ namespace llvm {
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
Constant *OffsetInBits, unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
unsigned RunTimeLang = 0);
StringRef Name,
DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
Constant *OffsetInBits,
unsigned Flags,
DIType DerivedFrom,
DIArray Elements,
unsigned RunTimeLang = 0);
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields.
DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit, unsigned LineNo,
DIFile F, unsigned LineNo,
DIType Ty, bool isLocalToUnit,
bool isDefinition,
unsigned VK = 0,
@ -618,21 +638,21 @@ namespace llvm {
CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *GV);
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit, unsigned LineNo,
DIFile F, unsigned LineNo,
DIType Ty);
/// CreateComplexVariable - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit, unsigned LineNo,
DIFile F, unsigned LineNo,
DIType Ty,
SmallVector<Value *, 9> &addr);
@ -644,7 +664,7 @@ namespace llvm {
/// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context.
DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
DICompileUnit CU, unsigned LineNo);
DIFile F, unsigned LineNo);
/// CreateLocation - Creates a debug info location.
DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,

View file

@ -179,6 +179,11 @@ namespace llvm {
void resetCachedCostInfo(Function* Caller) {
CachedFunctionInfo[Caller] = FunctionInfo();
}
/// growCachedCostInfo - update the cached cost info for Caller after Callee
/// has been inlined. If Callee is NULL it means a dead call has been
/// eliminated.
void growCachedCostInfo(Function* Caller, Function* Callee);
};
}

View file

@ -69,6 +69,10 @@ struct PostDominatorTree : public FunctionPass {
return DT->properlyDominates(A, B);
}
inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
virtual void releaseMemory() {
DT->releaseMemory();
}

View file

@ -136,6 +136,7 @@ namespace llvm {
mutable const MachineInstr *LastMI;
mutable const Function *LastFn;
mutable unsigned Counter;
mutable unsigned SetCounter;
// Private state for processDebugLoc()
mutable const MDNode *PrevDLT;
@ -275,6 +276,13 @@ namespace llvm {
/// EmitInt64 - Emit a long long directive and value.
///
void EmitInt64(uint64_t Value) const;
/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
/// in bytes of the directive is specified by Size and Hi/Lo specify the
/// labels. This implicitly uses .set if it is available.
void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) const;
//===------------------------------------------------------------------===//

View file

@ -35,6 +35,7 @@ class Value;
class Module;
class MDNode;
class MCAsmInfo;
class MCSymbol;
class raw_ostream;
class Instruction;
class DICompileUnit;
@ -82,10 +83,10 @@ public:
///
void EndFunction(const MachineFunction *MF);
/// RecordSourceLine - Register a source line with debug info. Returns a
/// unique label ID used to generate a label and provide correspondence to
/// RecordSourceLine - Register a source line with debug info. Returns the
/// unique label that was emitted and which provides correspondence to
/// the source line list.
unsigned RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
MCSymbol *RecordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getRecordSourceLineCount - Count source lines.
unsigned getRecordSourceLineCount();
@ -94,7 +95,7 @@ public:
/// be emitted.
bool ShouldEmitDwarfDebug() const;
void BeginScope(const MachineInstr *MI, unsigned Label);
void BeginScope(const MachineInstr *MI, MCSymbol *Label);
void EndScope(const MachineInstr *MI);
};

View file

@ -217,26 +217,19 @@ public:
/// MachineModuleInfo, for example because the code was deleted.
void InvalidateLabel(unsigned LabelID) {
// Remap to zero to indicate deletion.
RemapLabel(LabelID, 0);
}
/// RemapLabel - Indicate that a label has been merged into another.
///
void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) {
assert(0 < OldLabelID && OldLabelID <= LabelIDList.size() &&
"Old label ID out of range.");
assert(NewLabelID <= LabelIDList.size() &&
"New label ID out of range.");
LabelIDList[OldLabelID - 1] = NewLabelID;
assert(0 < LabelID && LabelID <= LabelIDList.size() &&
"Old label ID out of range.");
LabelIDList[LabelID - 1] = 0;
}
/// MappedLabel - Find out the label's final ID. Zero indicates deletion.
/// ID != Mapped ID indicates that the label was folded into another label.
unsigned MappedLabel(unsigned LabelID) const {
/// isLabelDeleted - Return true if the label was deleted.
/// FIXME: This should eventually be eliminated and use the 'is emitted' bit
/// on MCSymbol.
bool isLabelDeleted(unsigned LabelID) const {
assert(LabelID <= LabelIDList.size() && "Debug label ID out of range.");
return LabelID ? LabelIDList[LabelID - 1] : 0;
return LabelID == 0 || LabelIDList[LabelID - 1] == 0;
}
/// getFrameMoves - Returns a reference to a list of moves done in the current
/// function's prologue. Used to construct frame maps for debug and exception
/// handling comsumers.

View file

@ -247,18 +247,6 @@ namespace llvm {
/// encode inline subroutine information.
bool DwarfUsesInlineInfoSection; // Defaults to false.
/// Is_EHSymbolPrivate - If set, the "_foo.eh" is made private so that it
/// doesn't show up in the symbol table of the object file.
bool Is_EHSymbolPrivate; // Defaults to true.
/// GlobalEHDirective - This is the directive used to make exception frame
/// tables globally visible.
const char *GlobalEHDirective; // Defaults to NULL.
/// SupportsWeakEmptyEHFrame - True if target assembler and linker will
/// handle a weak_definition of constant 0 for an omitted EH frame.
bool SupportsWeakOmittedEHFrame; // Defaults to true.
/// DwarfSectionOffsetDirective - Special section offset directive.
const char* DwarfSectionOffsetDirective; // Defaults to NULL
@ -419,15 +407,6 @@ namespace llvm {
bool doesDwarfUsesInlineInfoSection() const {
return DwarfUsesInlineInfoSection;
}
bool is_EHSymbolPrivate() const {
return Is_EHSymbolPrivate;
}
const char *getGlobalEHDirective() const {
return GlobalEHDirective;
}
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
}
const char *getDwarfSectionOffsetDirective() const {
return DwarfSectionOffsetDirective;
}

View file

@ -46,11 +46,6 @@ namespace llvm {
/// @name Symbol Managment
/// @{
/// CreateSymbol - Create a new symbol with the specified @p Name.
///
/// @param Name - The symbol name, which must be unique across all symbols.
MCSymbol *CreateSymbol(StringRef Name);
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
/// @p Name. If it exists, return it. If not, create a forward
/// reference and return it.
@ -59,13 +54,15 @@ namespace llvm {
MCSymbol *GetOrCreateSymbol(StringRef Name);
MCSymbol *GetOrCreateSymbol(const Twine &Name);
/// CreateTemporarySymbol - Create a new temporary symbol with the specified
/// @p Name.
/// GetOrCreateTemporarySymbol - Create a new assembler temporary symbol
/// with the specified @p Name if it doesn't exist or return the existing
/// one if it does.
///
/// @param Name - The symbol name, for debugging purposes only, temporary
/// symbols do not surive assembly. If non-empty the name must be unique
/// across all symbols.
MCSymbol *CreateTemporarySymbol(StringRef Name = "");
MCSymbol *GetOrCreateTemporarySymbol(StringRef Name = "");
MCSymbol *GetOrCreateTemporarySymbol(const Twine &Name);
/// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const;

View file

@ -127,6 +127,10 @@ public:
static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx);
static const MCSymbolRefExpr *Create(StringRef Name, MCContext &Ctx);
/// CreateTemp - Create a reference to an assembler temporary label with the
/// specified name.
static const MCSymbolRefExpr *CreateTemp(StringRef Name, MCContext &Ctx);
/// @}
/// @name Accessors

View file

@ -191,6 +191,11 @@ namespace llvm {
/// EmitIntValue - Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
virtual void EmitIntValue(uint64_t Value, unsigned Size,unsigned AddrSpace);
/// EmitSymbolValue - Special case of EmitValue that avoids the client
/// having to pass in a MCExpr for MCSymbols.
virtual void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
unsigned AddrSpace);
/// EmitGPRel32Value - Emit the expression @p Value into the output as a
/// gprel32 (32-bit GP relative) value.

View file

@ -43,8 +43,10 @@ protected:
public:
static MDString *get(LLVMContext &Context, StringRef Str);
static MDString *get(LLVMContext &Context, const char *Str);
static MDString *get(LLVMContext &Context, const char *Str) {
return get(Context, Str ? StringRef(Str) : StringRef());
}
StringRef getString() const { return Str; }
unsigned getLength() const { return (unsigned)Str.size(); }

View file

@ -22,7 +22,8 @@ namespace llvm {
// Debug info constants.
enum {
LLVMDebugVersion = (7 << 16), // Current version of debug information.
LLVMDebugVersion = (8 << 16), // Current version of debug information.
LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
LLVMDebugVersion4 = (4 << 16), // Constant for version 4.

View file

@ -664,12 +664,12 @@ public:
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove lowering.
/// It returns EVT::iAny if SelectionDAG should be responsible for
/// It returns EVT::Other if SelectionDAG should be responsible for
/// determining it.
virtual EVT getOptimalMemOpType(uint64_t Size, unsigned Align,
bool isSrcConst, bool isSrcStr,
SelectionDAG &DAG) const {
return MVT::iAny;
return MVT::Other;
}
/// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp

View file

@ -87,11 +87,23 @@ protected:
const MCSection *DwarfRangesSection;
const MCSection *DwarfMacroInfoSection;
/// SupportsWeakEmptyEHFrame - True if target object file supports a
/// weak_definition of constant 0 for an omitted EH frame.
bool SupportsWeakOmittedEHFrame;
/// IsFunctionEHSymbolGlobal - This flag is set to true if the ".eh" symbol
/// for a function should be marked .globl.
bool IsFunctionEHSymbolGlobal;
/// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the
/// "EH_frame" symbol for EH information should be an assembler temporary (aka
/// private linkage, aka an L or .L label) or false if it should be a normal
/// non-.globl label. This defaults to true.
bool IsFunctionEHFrameSymbolPrivate;
public:
MCContext &getContext() const { return *Ctx; }
virtual ~TargetLoweringObjectFile();
/// Initialize - this method must be called before any actual lowering is
@ -101,6 +113,15 @@ public:
Ctx = &ctx;
}
bool isFunctionEHSymbolGlobal() const {
return IsFunctionEHSymbolGlobal;
}
bool isFunctionEHFrameSymbolPrivate() const {
return IsFunctionEHFrameSymbolPrivate;
}
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
}
const MCSection *getTextSection() const { return TextSection; }
const MCSection *getDataSection() const { return DataSection; }

View file

@ -682,8 +682,9 @@ public:
/// When -enable-frame-index-scavenging is enabled, the virtual register
/// allocated for this frame index is returned and its value is stored in
/// *Value.
typedef std::pair<unsigned, int> FrameIndexValue;
virtual unsigned eliminateFrameIndex(MachineBasicBlock::iterator MI,
int SPAdj, int *Value = NULL,
int SPAdj, FrameIndexValue *Value = NULL,
RegScavenger *RS=NULL) const = 0;
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into

View file

@ -75,6 +75,10 @@ struct Inliner : public CallGraphSCCPass {
///
virtual void resetCachedCostInfo(Function* Caller) = 0;
/// growCachedCostInfo - update the cached cost info for Caller after Callee
/// has been inlined.
virtual void growCachedCostInfo(Function* Caller, Function* Callee) = 0;
/// removeDeadFunctions - Remove dead functions that are not included in
/// DNR (Do Not Remove) list.
bool removeDeadFunctions(CallGraph &CG,

View file

@ -41,9 +41,9 @@ bool DIDescriptor::ValidDebugInfo(MDNode *N, unsigned OptLevel) {
DIDescriptor DI(N);
// Check current version. Allow Version6 for now.
// Check current version. Allow Version7 for now.
unsigned Version = DI.getVersion();
if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6)
if (Version != LLVMDebugVersion && Version != LLVMDebugVersion7)
return false;
switch (DI.getTag()) {
@ -69,15 +69,6 @@ bool DIDescriptor::ValidDebugInfo(MDNode *N, unsigned OptLevel) {
return true;
}
DIDescriptor::DIDescriptor(MDNode *N, unsigned RequiredTag) {
DbgNode = N;
// If this is non-null, check to see if the Tag matches. If not, set to null.
if (N && getTag() != RequiredTag) {
DbgNode = 0;
}
}
StringRef
DIDescriptor::getStringField(unsigned Elt) const {
if (DbgNode == 0)
@ -132,13 +123,12 @@ unsigned DIVariable::getNumAddrElements() const {
/// isBasicType - Return true if the specified tag is legal for
/// DIBasicType.
bool DIDescriptor::isBasicType() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_base_type;
return DbgNode && getTag() == dwarf::DW_TAG_base_type;
}
/// isDerivedType - Return true if the specified tag is legal for DIDerivedType.
bool DIDescriptor::isDerivedType() const {
assert(!isNull() && "Invalid descriptor!");
if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_typedef:
case dwarf::DW_TAG_pointer_type:
@ -158,7 +148,7 @@ bool DIDescriptor::isDerivedType() const {
/// isCompositeType - Return true if the specified tag is legal for
/// DICompositeType.
bool DIDescriptor::isCompositeType() const {
assert(!isNull() && "Invalid descriptor!");
if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_array_type:
case dwarf::DW_TAG_structure_type:
@ -175,7 +165,7 @@ bool DIDescriptor::isCompositeType() const {
/// isVariable - Return true if the specified tag is legal for DIVariable.
bool DIDescriptor::isVariable() const {
assert(!isNull() && "Invalid descriptor!");
if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_auto_variable:
case dwarf::DW_TAG_arg_variable:
@ -194,15 +184,13 @@ bool DIDescriptor::isType() const {
/// isSubprogram - Return true if the specified tag is legal for
/// DISubprogram.
bool DIDescriptor::isSubprogram() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_subprogram;
return DbgNode && getTag() == dwarf::DW_TAG_subprogram;
}
/// isGlobalVariable - Return true if the specified tag is legal for
/// DIGlobalVariable.
bool DIDescriptor::isGlobalVariable() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_variable;
return DbgNode && getTag() == dwarf::DW_TAG_variable;
}
/// isGlobal - Return true if the specified tag is legal for DIGlobal.
@ -213,7 +201,7 @@ bool DIDescriptor::isGlobal() const {
/// isScope - Return true if the specified tag is one of the scope
/// related tag.
bool DIDescriptor::isScope() const {
assert(!isNull() && "Invalid descriptor!");
if (!DbgNode) return false;
switch (getTag()) {
case dwarf::DW_TAG_compile_unit:
case dwarf::DW_TAG_lexical_block:
@ -228,39 +216,39 @@ bool DIDescriptor::isScope() const {
/// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit.
bool DIDescriptor::isCompileUnit() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_compile_unit;
return DbgNode && getTag() == dwarf::DW_TAG_compile_unit;
}
/// isFile - Return true if the specified tag is DW_TAG_file_type.
bool DIDescriptor::isFile() const {
return DbgNode && getTag() == dwarf::DW_TAG_file_type;
}
/// isNameSpace - Return true if the specified tag is DW_TAG_namespace.
bool DIDescriptor::isNameSpace() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_namespace;
return DbgNode && getTag() == dwarf::DW_TAG_namespace;
}
/// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
bool DIDescriptor::isLexicalBlock() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_lexical_block;
return DbgNode && getTag() == dwarf::DW_TAG_lexical_block;
}
/// isSubrange - Return true if the specified tag is DW_TAG_subrange_type.
bool DIDescriptor::isSubrange() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_subrange_type;
return DbgNode && getTag() == dwarf::DW_TAG_subrange_type;
}
/// isEnumerator - Return true if the specified tag is DW_TAG_enumerator.
bool DIDescriptor::isEnumerator() const {
assert(!isNull() && "Invalid descriptor!");
return getTag() == dwarf::DW_TAG_enumerator;
return DbgNode && getTag() == dwarf::DW_TAG_enumerator;
}
//===----------------------------------------------------------------------===//
// Simple Descriptor Constructors and other Methods
//===----------------------------------------------------------------------===//
DIType::DIType(MDNode *N) : DIDescriptor(N) {
DIType::DIType(MDNode *N) : DIScope(N) {
if (!N) return;
if (!isBasicType() && !isDerivedType() && !isCompositeType()) {
DbgNode = 0;
@ -268,7 +256,8 @@ DIType::DIType(MDNode *N) : DIDescriptor(N) {
}
unsigned DIArray::getNumElements() const {
assert(DbgNode && "Invalid DIArray");
if (!DbgNode)
return 0;
return DbgNode->getNumOperands();
}
@ -276,11 +265,9 @@ unsigned DIArray::getNumElements() const {
/// this descriptor. After this completes, the current debug info value
/// is erased.
void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) {
if (isNull())
if (!DbgNode)
return;
assert(!D.isNull() && "Can not replace with null");
// Since we use a TrackingVH for the node, its easy for clients to manufacture
// legitimate situations where they want to replaceAllUsesWith() on something
// which, due to uniquing, has merged with the source. We shield clients from
@ -295,7 +282,7 @@ void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) {
/// Verify - Verify that a compile unit is well formed.
bool DICompileUnit::Verify() const {
if (isNull())
if (!DbgNode)
return false;
StringRef N = getFilename();
if (N.empty())
@ -306,36 +293,36 @@ bool DICompileUnit::Verify() const {
/// Verify - Verify that a type descriptor is well formed.
bool DIType::Verify() const {
if (isNull())
if (!DbgNode)
return false;
if (getContext().isNull())
if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
if (!CU.isNull() && !CU.Verify())
if (!CU.Verify())
return false;
return true;
}
/// Verify - Verify that a composite type descriptor is well formed.
bool DICompositeType::Verify() const {
if (isNull())
if (!DbgNode)
return false;
if (getContext().isNull())
if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
if (!CU.isNull() && !CU.Verify())
if (!CU.Verify())
return false;
return true;
}
/// Verify - Verify that a subprogram descriptor is well formed.
bool DISubprogram::Verify() const {
if (isNull())
if (!DbgNode)
return false;
if (getContext().isNull())
if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
@ -343,24 +330,24 @@ bool DISubprogram::Verify() const {
return false;
DICompositeType Ty = getType();
if (!Ty.isNull() && !Ty.Verify())
if (!Ty.Verify())
return false;
return true;
}
/// Verify - Verify that a global variable descriptor is well formed.
bool DIGlobalVariable::Verify() const {
if (isNull())
if (!DbgNode)
return false;
if (getDisplayName().empty())
return false;
if (getContext().isNull())
if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
if (!CU.isNull() && !CU.Verify())
if (!CU.Verify())
return false;
DIType Ty = getType();
@ -375,10 +362,10 @@ bool DIGlobalVariable::Verify() const {
/// Verify - Verify that a variable descriptor is well formed.
bool DIVariable::Verify() const {
if (isNull())
if (!DbgNode)
return false;
if (getContext().isNull())
if (!getContext().Verify())
return false;
DIType Ty = getType();
@ -388,6 +375,14 @@ bool DIVariable::Verify() const {
return true;
}
/// Verify - Verify that a location descriptor is well formed.
bool DILocation::Verify() const {
if (!DbgNode)
return false;
return DbgNode->getNumOperands() == 4;
}
/// getOriginalTypeSize - If this type is derived from a base type then
/// return base type size.
uint64_t DIDerivedType::getOriginalTypeSize() const {
@ -398,7 +393,7 @@ uint64_t DIDerivedType::getOriginalTypeSize() const {
DIType BaseType = getTypeDerivedFrom();
// If this type is not derived from any type then take conservative
// approach.
if (BaseType.isNull())
if (!BaseType.isValid())
return getSizeInBits();
if (BaseType.isDerivedType())
return DIDerivedType(BaseType.getNode()).getOriginalTypeSize();
@ -422,6 +417,8 @@ bool DISubprogram::describes(const Function *F) {
}
StringRef DIScope::getFilename() const {
if (!DbgNode)
return StringRef();
if (isLexicalBlock())
return DILexicalBlock(DbgNode).getFilename();
if (isSubprogram())
@ -430,11 +427,17 @@ StringRef DIScope::getFilename() const {
return DICompileUnit(DbgNode).getFilename();
if (isNameSpace())
return DINameSpace(DbgNode).getFilename();
if (isType())
return DIType(DbgNode).getFilename();
if (isFile())
return DIFile(DbgNode).getFilename();
assert(0 && "Invalid DIScope!");
return StringRef();
}
StringRef DIScope::getDirectory() const {
if (!DbgNode)
return StringRef();
if (isLexicalBlock())
return DILexicalBlock(DbgNode).getDirectory();
if (isSubprogram())
@ -443,6 +446,10 @@ StringRef DIScope::getDirectory() const {
return DICompileUnit(DbgNode).getDirectory();
if (isNameSpace())
return DINameSpace(DbgNode).getDirectory();
if (isType())
return DIType(DbgNode).getDirectory();
if (isFile())
return DIFile(DbgNode).getDirectory();
assert(0 && "Invalid DIScope!");
return StringRef();
}
@ -468,7 +475,7 @@ void DICompileUnit::dump() const {
/// dump - Print type.
void DIType::dump() const {
if (isNull()) return;
if (!DbgNode) return;
StringRef Res = getName();
if (!Res.empty())
@ -521,8 +528,6 @@ void DIDerivedType::dump() const {
/// dump - Print composite type.
void DICompositeType::dump() const {
DIArray A = getTypeArray();
if (A.isNull())
return;
dbgs() << " [" << A.getNumElements() << " elements]";
}
@ -665,6 +670,20 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
return DICompileUnit(MDNode::get(VMContext, &Elts[0], 10));
}
/// CreateFile - Create a new descriptor for the specified file.
DIFile DIFactory::CreateFile(StringRef Filename,
StringRef Directory,
DICompileUnit CU) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_file_type),
MDString::get(VMContext, Filename),
MDString::get(VMContext, Directory),
CU.getNode()
};
return DIFile(MDNode::get(VMContext, &Elts[0], 4));
}
/// CreateEnumerator - Create a single enumerator value.
DIEnumerator DIFactory::CreateEnumerator(StringRef Name, uint64_t Val){
Value *Elts[] = {
@ -679,7 +698,7 @@ DIEnumerator DIFactory::CreateEnumerator(StringRef Name, uint64_t Val){
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@ -689,7 +708,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
GetTagConstant(dwarf::DW_TAG_base_type),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@ -704,7 +723,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context,
/// CreateBasicType - Create a basic type like int, float, etc.
DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
@ -714,7 +733,7 @@ DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context,
GetTagConstant(dwarf::DW_TAG_base_type),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
SizeInBits,
AlignInBits,
@ -754,7 +773,7 @@ DIType DIFactory::CreateArtificialType(DIType Ty) {
DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@ -765,7 +784,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@ -782,7 +801,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
DIDerivedType DIFactory::CreateDerivedTypeEx(unsigned Tag,
DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
@ -793,7 +812,7 @@ DIDerivedType DIFactory::CreateDerivedTypeEx(unsigned Tag,
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
SizeInBits,
AlignInBits,
@ -809,7 +828,7 @@ DIDerivedType DIFactory::CreateDerivedTypeEx(unsigned Tag,
DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
@ -824,7 +843,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@ -843,7 +862,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag,
DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag,
DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNumber,
Constant *SizeInBits,
Constant *AlignInBits,
@ -857,7 +876,7 @@ DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag,
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
SizeInBits,
AlignInBits,
@ -878,7 +897,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNo, DIType Ty,
bool isLocalToUnit,
bool isDefinition,
@ -893,7 +912,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
MDString::get(VMContext, Name),
MDString::get(VMContext, DisplayName),
MDString::get(VMContext, LinkageName),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Ty.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
@ -938,7 +957,7 @@ DIGlobalVariable
DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNo, DIType Ty,bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *Val) {
Value *Elts[] = {
@ -948,7 +967,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
MDString::get(VMContext, Name),
MDString::get(VMContext, DisplayName),
MDString::get(VMContext, LinkageName),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Ty.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
@ -970,13 +989,14 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit, unsigned LineNo,
DIFile F,
unsigned LineNo,
DIType Ty) {
Value *Elts[] = {
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
Ty.getNode(),
};
@ -988,7 +1008,7 @@ DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
/// which has a complex address expression for its address.
DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNo,
DIType Ty,
SmallVector<Value *, 9> &addr) {
@ -996,7 +1016,7 @@ DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context,
Elts.push_back(GetTagConstant(Tag));
Elts.push_back(Context.getNode());
Elts.push_back(MDString::get(VMContext, Name));
Elts.push_back(CompileUnit.getNode());
Elts.push_back(F.getNode());
Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo));
Elts.push_back(Ty.getNode());
Elts.insert(Elts.end(), addr.begin(), addr.end());
@ -1021,13 +1041,13 @@ DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context,
/// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context.
DINameSpace DIFactory::CreateNameSpace(DIDescriptor Context, StringRef Name,
DICompileUnit CompileUnit,
DIFile F,
unsigned LineNo) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_namespace),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
F.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)
};
return DINameSpace(MDNode::get(VMContext, &Elts[0], 5));
@ -1155,9 +1175,8 @@ void DebugInfoFinder::processModule(Module &M) {
/// processLocation - Process DILocation.
void DebugInfoFinder::processLocation(DILocation Loc) {
if (Loc.isNull()) return;
DIScope S(Loc.getScope().getNode());
if (S.isNull()) return;
if (!Loc.Verify()) return;
DIDescriptor S(Loc.getScope().getNode());
if (S.isCompileUnit())
addCompileUnit(DICompileUnit(S.getNode()));
else if (S.isSubprogram())
@ -1177,26 +1196,21 @@ void DebugInfoFinder::processType(DIType DT) {
DICompositeType DCT(DT.getNode());
processType(DCT.getTypeDerivedFrom());
DIArray DA = DCT.getTypeArray();
if (!DA.isNull())
for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
DIDescriptor D = DA.getElement(i);
DIType TyE = DIType(D.getNode());
if (!TyE.isNull())
processType(TyE);
else
processSubprogram(DISubprogram(D.getNode()));
}
for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
DIDescriptor D = DA.getElement(i);
if (D.isType())
processType(DIType(D.getNode()));
else if (D.isSubprogram())
processSubprogram(DISubprogram(D.getNode()));
}
} else if (DT.isDerivedType()) {
DIDerivedType DDT(DT.getNode());
if (!DDT.isNull())
processType(DDT.getTypeDerivedFrom());
processType(DDT.getTypeDerivedFrom());
}
}
/// processLexicalBlock
void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) {
if (LB.isNull())
return;
DIScope Context = LB.getContext();
if (Context.isLexicalBlock())
return processLexicalBlock(DILexicalBlock(Context.getNode()));
@ -1206,8 +1220,6 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) {
/// processSubprogram - Process DISubprogram.
void DebugInfoFinder::processSubprogram(DISubprogram SP) {
if (SP.isNull())
return;
if (!addSubprogram(SP))
return;
addCompileUnit(SP.getCompileUnit());
@ -1216,20 +1228,23 @@ void DebugInfoFinder::processSubprogram(DISubprogram SP) {
/// processDeclare - Process DbgDeclareInst.
void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) {
DIVariable DV(cast<MDNode>(DDI->getVariable()));
if (DV.isNull())
MDNode *N = dyn_cast<MDNode>(DDI->getVariable());
if (!N) return;
DIDescriptor DV(N);
if (!DV.isVariable())
return;
if (!NodesSeen.insert(DV.getNode()))
return;
addCompileUnit(DV.getCompileUnit());
processType(DV.getType());
addCompileUnit(DIVariable(N).getCompileUnit());
processType(DIVariable(N).getType());
}
/// addType - Add type into Tys.
bool DebugInfoFinder::addType(DIType DT) {
if (DT.isNull())
if (!DT.isValid())
return false;
if (!NodesSeen.insert(DT.getNode()))
@ -1241,7 +1256,7 @@ bool DebugInfoFinder::addType(DIType DT) {
/// addCompileUnit - Add compile unit into CUs.
bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) {
if (CU.isNull())
if (!CU.Verify())
return false;
if (!NodesSeen.insert(CU.getNode()))
@ -1253,7 +1268,7 @@ bool DebugInfoFinder::addCompileUnit(DICompileUnit CU) {
/// addGlobalVariable - Add global variable into GVs.
bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) {
if (DIG.isNull())
if (!DIDescriptor(DIG.getNode()).isGlobalVariable())
return false;
if (!NodesSeen.insert(DIG.getNode()))
@ -1265,7 +1280,7 @@ bool DebugInfoFinder::addGlobalVariable(DIGlobalVariable DIG) {
// addSubprogram - Add subprgoram into SPs.
bool DebugInfoFinder::addSubprogram(DISubprogram SP) {
if (SP.isNull())
if (!DIDescriptor(SP.getNode()).isSubprogram())
return false;
if (!NodesSeen.insert(SP.getNode()))
@ -1283,10 +1298,10 @@ static Value *findDbgGlobalDeclare(GlobalVariable *V) {
return 0;
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
DIGlobalVariable DIG(cast_or_null<MDNode>(NMD->getOperand(i)));
if (DIG.isNull())
DIDescriptor DIG(cast_or_null<MDNode>(NMD->getOperand(i)));
if (!DIG.isGlobalVariable())
continue;
if (DIG.getGlobal() == V)
if (DIGlobalVariable(DIG.getNode()).getGlobal() == V)
return DIG.getNode();
}
return 0;
@ -1378,12 +1393,6 @@ DebugLoc llvm::ExtractDebugLocation(DILocation &Loc,
/// getDISubprogram - Find subprogram that is enclosing this scope.
DISubprogram llvm::getDISubprogram(MDNode *Scope) {
DIDescriptor D(Scope);
if (D.isNull())
return DISubprogram();
if (D.isCompileUnit())
return DISubprogram();
if (D.isSubprogram())
return DISubprogram(Scope);
@ -1395,9 +1404,6 @@ DISubprogram llvm::getDISubprogram(MDNode *Scope) {
/// getDICompositeType - Find underlying composite type.
DICompositeType llvm::getDICompositeType(DIType T) {
if (T.isNull())
return DICompositeType();
if (T.isCompositeType())
return DICompositeType(T.getNode());

View file

@ -352,11 +352,6 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
// Calls usually take a long time, so they make the inlining gain smaller.
InlineCost += CalleeFI.Metrics.NumCalls * InlineConstants::CallPenalty;
// Don't inline into something too big, which would make it bigger.
// "size" here is the number of basic blocks, not instructions.
//
InlineCost += Caller->size()/15;
// Look at the size of the callee. Each instruction counts as 5.
InlineCost += CalleeFI.Metrics.NumInsts*InlineConstants::InstrCost;
@ -388,3 +383,45 @@ float InlineCostAnalyzer::getInlineFudgeFactor(CallSite CS) {
Factor += 1.5f;
return Factor;
}
/// growCachedCostInfo - update the cached cost info for Caller after Callee has
/// been inlined.
void
InlineCostAnalyzer::growCachedCostInfo(Function* Caller, Function* Callee) {
FunctionInfo &CallerFI = CachedFunctionInfo[Caller];
// For small functions we prefer to recalculate the cost for better accuracy.
if (CallerFI.Metrics.NumBlocks < 10 || CallerFI.Metrics.NumInsts < 1000) {
resetCachedCostInfo(Caller);
return;
}
// For large functions, we can save a lot of computation time by skipping
// recalculations.
if (CallerFI.Metrics.NumCalls > 0)
--CallerFI.Metrics.NumCalls;
if (Callee) {
FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
if (!CalleeFI.Metrics.NumBlocks) {
resetCachedCostInfo(Caller);
return;
}
CallerFI.Metrics.NeverInline |= CalleeFI.Metrics.NeverInline;
CallerFI.Metrics.usesDynamicAlloca |= CalleeFI.Metrics.usesDynamicAlloca;
CallerFI.Metrics.NumInsts += CalleeFI.Metrics.NumInsts;
CallerFI.Metrics.NumBlocks += CalleeFI.Metrics.NumBlocks;
CallerFI.Metrics.NumCalls += CalleeFI.Metrics.NumCalls;
CallerFI.Metrics.NumVectorInsts += CalleeFI.Metrics.NumVectorInsts;
CallerFI.Metrics.NumRets += CalleeFI.Metrics.NumRets;
// analyzeBasicBlock counts each function argument as an inst.
if (CallerFI.Metrics.NumInsts >= Callee->arg_size())
CallerFI.Metrics.NumInsts -= Callee->arg_size();
else
CallerFI.Metrics.NumInsts = 0;
}
// We are not updating the argumentweights. We have already determined that
// Caller is a fairly large function, so we accept the loss of precision.
}

View file

@ -264,6 +264,13 @@ unsigned Loop::getSmallConstantTripMultiple() const {
/// isLCSSAForm - Return true if the Loop is in LCSSA form
bool Loop::isLCSSAForm() const {
// Collect all the reachable blocks in the function, for fast lookups.
SmallPtrSet<BasicBlock *, 32> ReachableBBs;
BasicBlock *EntryBB = getHeader()->getParent()->begin();
for (df_iterator<BasicBlock *> NI = df_begin(EntryBB),
NE = df_end(EntryBB); NI != NE; ++NI)
ReachableBBs.insert(*NI);
// Sort the blocks vector so that we can use binary search to do quick
// lookups.
SmallPtrSet<BasicBlock *, 16> LoopBBs(block_begin(), block_end());
@ -277,9 +284,13 @@ bool Loop::isLCSSAForm() const {
if (PHINode *P = dyn_cast<PHINode>(*UI))
UserBB = P->getIncomingBlock(UI);
// Check the current block, as a fast-path. Most values are used in
// the same block they are defined in.
if (UserBB != BB && !LoopBBs.count(UserBB))
// Check the current block, as a fast-path, before checking whether
// the use is anywhere in the loop. Most values are used in the same
// block they are defined in. Also, blocks not reachable from the
// entry are special; uses in them don't need to go through PHIs.
if (UserBB != BB &&
!LoopBBs.count(UserBB) &&
ReachableBBs.count(UserBB))
return false;
}
}

View file

@ -3101,9 +3101,16 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
return getUnknown(V);
unsigned Opcode = Instruction::UserOp1;
if (Instruction *I = dyn_cast<Instruction>(V))
if (Instruction *I = dyn_cast<Instruction>(V)) {
Opcode = I->getOpcode();
else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
// Don't attempt to analyze instructions in blocks that aren't
// reachable. Such instructions don't matter, and they aren't required
// to obey basic rules for definitions dominating uses which this
// analysis depends on.
if (!DT->isReachableFromEntry(I->getParent()))
return getUnknown(V);
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
Opcode = CE->getOpcode();
else if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
return getConstant(CI);

View file

@ -1286,6 +1286,8 @@ Value *SCEVExpander::expand(const SCEV *S) {
// there) so that it is guaranteed to dominate any user inside the loop.
if (L && S->hasComputableLoopEvolution(L) && L != PostIncLoop)
InsertPt = L->getHeader()->getFirstNonPHI();
while (isa<DbgInfoIntrinsic>(InsertPt))
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
while (isInsertedInstruction(InsertPt))
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
break;

View file

@ -61,7 +61,7 @@ AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
: MachineFunctionPass(&ID), O(o),
TM(tm), MAI(T), TRI(tm.getRegisterInfo()),
OutContext(Ctx), OutStreamer(Streamer),
LastMI(0), LastFn(0), Counter(~0U), PrevDLT(NULL) {
LastMI(0), LastFn(0), Counter(~0U), SetCounter(0), PrevDLT(NULL) {
DW = 0; MMI = 0;
VerboseAsm = Streamer.isVerboseAsm();
}
@ -335,7 +335,7 @@ static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
// Print source line info.
DIScope Scope = DLT.getScope();
// Omit the directory, because it's likely to be long and uninteresting.
if (!Scope.isNull())
if (Scope.Verify())
CommentOS << Scope.getFilename();
else
CommentOS << "<unknown>";
@ -893,6 +893,31 @@ void AsmPrinter::EmitInt64(uint64_t Value) const {
OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/);
}
/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
/// in bytes of the directive is specified by Size and Hi/Lo specify the
/// labels. This implicitly uses .set if it is available.
void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) const {
// Get the Hi-Lo expression.
const MCExpr *Diff =
MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext),
MCSymbolRefExpr::Create(Lo, OutContext),
OutContext);
if (!MAI->hasSetDirective()) {
OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/);
return;
}
// Otherwise, emit with .set (aka assignment).
MCSymbol *SetLabel =
OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) +
"set" + Twine(SetCounter++));
OutStreamer.EmitAssignment(SetLabel, Diff);
OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
}
//===----------------------------------------------------------------------===//
// EmitAlignment - Emit an alignment directive to the specified power of
@ -1287,18 +1312,16 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI,
if (DL.isUnknown())
return;
DILocation CurDLT = MF->getDILocation(DL);
if (CurDLT.getScope().isNull())
if (!CurDLT.getScope().Verify())
return;
if (!BeforePrintingInsn) {
// After printing instruction
DW->EndScope(MI);
} else if (CurDLT.getNode() != PrevDLT) {
unsigned L = DW->RecordSourceLine(CurDLT.getLineNumber(),
CurDLT.getColumnNumber(),
CurDLT.getScope().getNode());
printLabel(L);
O << '\n';
MCSymbol *L = DW->RecordSourceLine(CurDLT.getLineNumber(),
CurDLT.getColumnNumber(),
CurDLT.getScope().getNode());
DW->BeginScope(MI, L);
PrevDLT = CurDLT.getNode();
}
@ -1529,12 +1552,17 @@ void AsmPrinter::printKill(const MachineInstr *MI) const {
/// printLabel - This method prints a local label used by debug and
/// exception handling tables.
void AsmPrinter::printLabelInst(const MachineInstr *MI) const {
printLabel(MI->getOperand(0).getImm());
OutStreamer.AddBlankLine();
MCSymbol *Sym =
OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) +
"label" + Twine(MI->getOperand(0).getImm()));
OutStreamer.EmitLabel(Sym);
}
void AsmPrinter::printLabel(unsigned Id) const {
O << MAI->getPrivateGlobalPrefix() << "label" << Id << ':';
MCSymbol *Sym =
OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) +
"label" + Twine(Id));
OutStreamer.EmitLabel(Sym);
}
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
@ -1575,15 +1603,14 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
"_" + FnName.str() + "_" + BB->getName(),
Mangler::Private);
return OutContext.GetOrCreateSymbol(NameResult.str());
return OutContext.GetOrCreateTemporarySymbol(NameResult.str());
}
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
SmallString<60> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "CPI"
<< getFunctionNumber() << '_' << CPID;
return OutContext.GetOrCreateSymbol(Name.str());
return OutContext.GetOrCreateTemporarySymbol
(Twine(MAI->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber())
+ "_" + Twine(CPID));
}
/// GetJTISymbol - Return the symbol for the specified jump table entry.
@ -1594,10 +1621,9 @@ MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const {
/// GetJTSetSymbol - Return the symbol for the specified jump table .set
/// FIXME: privatize to AsmPrinter.
MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const {
SmallString<60> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
<< getFunctionNumber() << '_' << UID << "_set_" << MBBID;
return OutContext.GetOrCreateSymbol(Name.str());
return OutContext.GetOrCreateTemporarySymbol
(Twine(MAI->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" +
Twine(UID) + "_set_" + Twine(MBBID));
}
/// GetGlobalValueSymbol - Return the MCSymbol for the specified global
@ -1605,7 +1631,10 @@ MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const {
MCSymbol *AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const {
SmallString<60> NameStr;
Mang->getNameWithPrefix(NameStr, GV, false);
return OutContext.GetOrCreateSymbol(NameStr.str());
if (!GV->hasPrivateLinkage())
return OutContext.GetOrCreateSymbol(NameStr.str());
return OutContext.GetOrCreateTemporarySymbol(NameStr.str());
}
/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
@ -1617,7 +1646,9 @@ MCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV,
SmallString<60> NameStr;
Mang->getNameWithPrefix(NameStr, GV, ForcePrivate);
NameStr.append(Suffix.begin(), Suffix.end());
return OutContext.GetOrCreateSymbol(NameStr.str());
if (!GV->hasPrivateLinkage() && !ForcePrivate)
return OutContext.GetOrCreateSymbol(NameStr.str());
return OutContext.GetOrCreateTemporarySymbol(NameStr.str());
}
/// GetExternalSymbolSymbol - Return the MCSymbol for the specified

View file

@ -3,7 +3,6 @@ add_llvm_library(LLVMAsmPrinter
DIE.cpp
DwarfDebug.cpp
DwarfException.cpp
DwarfLabel.cpp
DwarfPrinter.cpp
DwarfWriter.cpp
OcamlGCPrinter.cpp

View file

@ -131,17 +131,15 @@ void DIE::print(raw_ostream &O, unsigned IncIndent) {
<< "Die: "
<< format("0x%lx", (long)(intptr_t)this)
<< ", Offset: " << Offset
<< ", Size: " << Size
<< "\n";
<< ", Size: " << Size << "\n";
O << Indent
<< dwarf::TagString(Abbrev.getTag())
<< " "
<< dwarf::ChildrenString(Abbrev.getChildrenFlag());
<< dwarf::ChildrenString(Abbrev.getChildrenFlag()) << "\n";
} else {
O << "Size: " << Size;
O << "Size: " << Size << "\n";
}
O << "\n";
const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
@ -254,51 +252,27 @@ void DIEString::print(raw_ostream &O) {
#endif
//===----------------------------------------------------------------------===//
// DIEDwarfLabel Implementation
// DIELabel Implementation
//===----------------------------------------------------------------------===//
/// EmitValue - Emit label value.
///
void DIEDwarfLabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
void DIELabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
bool IsSmall = Form == dwarf::DW_FORM_data4;
D->EmitReference(Label, false, IsSmall);
unsigned Size = IsSmall ? 4 : D->getTargetData()->getPointerSize();
D->getAsm()->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/);
}
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
unsigned DIELabel::SizeOf(const TargetData *TD, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
return TD->getPointerSize();
}
#ifndef NDEBUG
void DIEDwarfLabel::print(raw_ostream &O) {
O << "Lbl: ";
Label.print(O);
}
#endif
//===----------------------------------------------------------------------===//
// DIEObjectLabel Implementation
//===----------------------------------------------------------------------===//
/// EmitValue - Emit label value.
///
void DIEObjectLabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
bool IsSmall = Form == dwarf::DW_FORM_data4;
D->EmitReference(Sym, false, IsSmall);
}
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
return TD->getPointerSize();
}
#ifndef NDEBUG
void DIEObjectLabel::print(raw_ostream &O) {
O << "Obj: " << Sym->getName();
void DIELabel::print(raw_ostream &O) {
O << "Lbl: " << Label->getName();
}
#endif
@ -310,10 +284,7 @@ void DIEObjectLabel::print(raw_ostream &O) {
///
void DIESectionOffset::EmitValue(DwarfPrinter *D, unsigned Form) const {
bool IsSmall = Form == dwarf::DW_FORM_data4;
D->EmitSectionOffset(Label.getTag(), Section.getTag(),
Label.getNumber(), Section.getNumber(),
IsSmall, IsEH, UseSet);
D->getAsm()->O << '\n'; // FIXME: Necesssary?
D->EmitSectionOffset(Label, Section, IsSmall, IsEH);
}
/// SizeOf - Determine size of delta value in bytes.
@ -325,11 +296,8 @@ unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
#ifndef NDEBUG
void DIESectionOffset::print(raw_ostream &O) {
O << "Off: ";
Label.print(O);
O << "-";
Section.print(O);
O << "-" << IsEH << "-" << UseSet;
O << "Off: " << Label->getName() << "-" << Section->getName()
<< "-" << IsEH;
}
#endif
@ -353,10 +321,7 @@ unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
#ifndef NDEBUG
void DIEDelta::print(raw_ostream &O) {
O << "Del: ";
LabelHi.print(O);
O << "-";
LabelLo.print(O);
O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName();
}
#endif
@ -400,15 +365,13 @@ void DIEBlock::EmitValue(DwarfPrinter *D, unsigned Form) const {
case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
case dwarf::DW_FORM_block: D->EmitULEB128(Size); break;
default: llvm_unreachable("Improper form for block"); break;
case dwarf::DW_FORM_block: D->EmitULEB128(Size); break;
default: llvm_unreachable("Improper form for block"); break;
}
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
for (unsigned i = 0, N = Values.size(); i < N; ++i) {
Asm->O << '\n';
for (unsigned i = 0, N = Values.size(); i < N; ++i)
Values[i]->EmitValue(D, AbbrevData[i].getForm());
}
}
/// SizeOf - Determine size of block data in bytes.

View file

@ -14,7 +14,6 @@
#ifndef CODEGEN_ASMPRINTER_DIE_H__
#define CODEGEN_ASMPRINTER_DIE_H__
#include "DwarfLabel.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
@ -26,6 +25,7 @@ namespace llvm {
class DwarfPrinter;
class TargetData;
class MCSymbol;
class raw_ostream;
//===--------------------------------------------------------------------===//
/// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
@ -203,7 +203,6 @@ namespace llvm {
isInteger,
isString,
isLabel,
isAsIsLabel,
isSectionOffset,
isDelta,
isEntry,
@ -306,12 +305,12 @@ namespace llvm {
};
//===--------------------------------------------------------------------===//
/// DIEDwarfLabel - A Dwarf internal label expression DIE.
/// DIELabel - A label expression DIE.
//
class DIEDwarfLabel : public DIEValue {
const DWLabel Label;
class DIELabel : public DIEValue {
const MCSymbol *Label;
public:
explicit DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
/// EmitValue - Emit label value.
///
@ -322,37 +321,9 @@ namespace llvm {
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIEDwarfLabel *) { return true; }
static bool classof(const DIELabel *) { return true; }
static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
#ifndef NDEBUG
virtual void print(raw_ostream &O);
#endif
};
//===--------------------------------------------------------------------===//
/// DIEObjectLabel - A label to an object in code or data.
//
class DIEObjectLabel : public DIEValue {
const MCSymbol *Sym;
public:
explicit DIEObjectLabel(const MCSymbol *S)
: DIEValue(isAsIsLabel), Sym(S) {}
/// EmitValue - Emit label value.
///
virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of label value in bytes.
///
virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIEObjectLabel *) { return true; }
static bool classof(const DIEValue *L) {
return L->getType() == isAsIsLabel;
}
#ifndef NDEBUG
virtual void print(raw_ostream &O);
#endif
@ -362,15 +333,14 @@ namespace llvm {
/// DIESectionOffset - A section offset DIE.
///
class DIESectionOffset : public DIEValue {
const DWLabel Label;
const DWLabel Section;
const MCSymbol *Label;
const MCSymbol *Section;
bool IsEH : 1;
bool UseSet : 1;
public:
DIESectionOffset(const DWLabel &Lab, const DWLabel &Sec,
bool isEH = false, bool useSet = true)
DIESectionOffset(const MCSymbol *Lab, const MCSymbol *Sec,
bool isEH = false)
: DIEValue(isSectionOffset), Label(Lab), Section(Sec),
IsEH(isEH), UseSet(useSet) {}
IsEH(isEH) {}
/// EmitValue - Emit section offset.
///
@ -395,10 +365,10 @@ namespace llvm {
/// DIEDelta - A simple label difference DIE.
///
class DIEDelta : public DIEValue {
const DWLabel LabelHi;
const DWLabel LabelLo;
const MCSymbol *LabelHi;
const MCSymbol *LabelLo;
public:
DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
: DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
/// EmitValue - Emit delta value.

File diff suppressed because it is too large Load diff

View file

@ -62,14 +62,6 @@ class DwarfDebug : public DwarfPrinter {
// Attributes used to construct specific Dwarf sections.
//
/// CompileUnitMap - A map of global variables representing compile units to
/// compile units.
DenseMap<Value *, CompileUnit *> CompileUnitMap;
/// CompileUnits - All the compile units in this module.
///
SmallVector<CompileUnit *, 8> CompileUnits;
/// ModuleCU - All DIEs are inserted in ModuleCU.
CompileUnit *ModuleCU;
@ -175,8 +167,8 @@ class DwarfDebug : public DwarfPrinter {
/// InlineInfo - Keep track of inlined functions and their location. This
/// information is used to populate debug_inlined section.
typedef std::pair<unsigned, DIE *> InlineInfoLabels;
DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> > InlineInfo;
typedef std::pair<MCSymbol*, DIE *> InlineInfoLabels;
DenseMap<MDNode*, SmallVector<InlineInfoLabels, 4> > InlineInfo;
SmallVector<MDNode *, 4> InlinedSPNodes;
/// CompileUnitOffsets - A vector of the offsets of the compile units. This is
@ -251,23 +243,18 @@ class DwarfDebug : public DwarfPrinter {
/// addLabel - Add a Dwarf label attribute data and value.
///
void addLabel(DIE *Die, unsigned Attribute, unsigned Form,
const DWLabel &Label);
/// addObjectLabel - Add an non-Dwarf label attribute data and value.
///
void addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Sym);
const MCSymbol *Label);
/// addSectionOffset - Add a section offset label attribute data and value.
///
void addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
const DWLabel &Label, const DWLabel &Section,
bool isEH = false, bool useSet = true);
const MCSymbol *Label, const MCSymbol *Section,
bool isEH = false);
/// addDelta - Add a label delta attribute data and value.
///
void addDelta(DIE *Die, unsigned Attribute, unsigned Form,
const DWLabel &Hi, const DWLabel &Lo);
const MCSymbol *Hi, const MCSymbol *Lo);
/// addDIEEntry - Add a DIE attribute data and value.
///
@ -346,7 +333,7 @@ class DwarfDebug : public DwarfPrinter {
DICompositeType *CTy);
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
DIE *constructEnumTypeDIE(DIEnumerator *ETy);
DIE *constructEnumTypeDIE(DIEnumerator ETy);
/// createGlobalVariableDIE - Create new DIE using GV.
DIE *createGlobalVariableDIE(const DIGlobalVariable &GV);
@ -357,10 +344,6 @@ class DwarfDebug : public DwarfPrinter {
/// createSubprogramDIE - Create new DIE using SP.
DIE *createSubprogramDIE(const DISubprogram &SP, bool MakeDecl = false);
/// findCompileUnit - Get the compile unit for the given descriptor.
///
CompileUnit *findCompileUnit(DICompileUnit Unit);
/// getUpdatedDbgScope - Find or create DbgScope assicated with
/// the instruction. Initialize scope and update scope hierarchy.
DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt);
@ -529,10 +512,10 @@ public:
///
void endFunction(const MachineFunction *MF);
/// recordSourceLine - Records location information and associates it with a
/// label. Returns a unique label ID used to generate a label and provide
/// correspondence to the source line list.
unsigned recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// recordSourceLine - Register a source line with debug info. Returns the
/// unique label that was emitted and which provides correspondence to
/// the source line list.
MCSymbol *recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
/// getSourceLineCount - Return the number of source lines in the debug
/// info.
@ -556,7 +539,7 @@ public:
void collectVariableInfo();
/// beginScope - Process beginning of a scope starting at Label.
void beginScope(const MachineInstr *MI, unsigned Label);
void beginScope(const MachineInstr *MI, MCSymbol *Label);
/// endScope - Prcess end of a scope.
void endScope(const MachineInstr *MI);

View file

@ -39,7 +39,7 @@ using namespace llvm;
DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A,
const MCAsmInfo *T)
: DwarfPrinter(OS, A, T, "eh"), shouldEmitTable(false),shouldEmitMoves(false),
: DwarfPrinter(OS, A, T), shouldEmitTable(false),shouldEmitMoves(false),
shouldEmitTableModule(false), shouldEmitMovesModule(false),
ExceptionTimer(0) {
if (TimePassesIsEnabled)
@ -60,7 +60,7 @@ const MCExpr *DwarfException::CreateLabelDiff(const MCExpr *ExprRef,
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
<< LabelName << Asm->getFunctionNumber()
<< "_" << Index;
MCSymbol *DotSym = Asm->OutContext.GetOrCreateSymbol(Name.str());
MCSymbol *DotSym = Asm->OutContext.GetOrCreateTemporarySymbol(Name.str());
Asm->OutStreamer.EmitLabel(DotSym);
return MCBinaryExpr::CreateSub(ExprRef,
@ -84,25 +84,29 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// Begin eh frame section.
Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection());
if (MAI->is_EHSymbolPrivate())
O << MAI->getPrivateGlobalPrefix();
O << "EH_frame" << Index << ":\n";
MCSymbol *EHFrameSym;
if (TLOF.isFunctionEHFrameSymbolPrivate())
EHFrameSym = getDWLabel("EH_frame", Index);
else
EHFrameSym = Asm->OutContext.GetOrCreateSymbol(Twine("EH_frame") +
Twine(Index));
Asm->OutStreamer.EmitLabel(EHFrameSym);
EmitLabel("section_eh_frame", Index);
Asm->OutStreamer.EmitLabel(getDWLabel("section_eh_frame", Index));
// Define base labels.
EmitLabel("eh_frame_common", Index);
Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common", Index));
// Define the eh frame length.
EmitDifference("eh_frame_common_end", Index,
"eh_frame_common_begin", Index, true);
EOL("Length of Common Information Entry");
Asm->OutStreamer.AddComment("Length of Common Information Entry");
EmitDifference(getDWLabel("eh_frame_common_end", Index),
getDWLabel("eh_frame_common_begin", Index), true);
// EH frame header.
EmitLabel("eh_frame_common_begin", Index);
if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("CIE Identifier Tag");
Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_begin", Index));
Asm->OutStreamer.AddComment("CIE Identifier Tag");
Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DW_CIE_VERSION");
Asm->OutStreamer.AddComment("DW_CIE_VERSION");
Asm->OutStreamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1/*size*/, 0/*addr*/);
// The personality presence indicates that language specific information will
@ -138,14 +142,14 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
if (APtr != Augmentation + 1)
Augmentation[0] = 'z';
Asm->OutStreamer.AddComment("CIE Augmentation");
Asm->OutStreamer.EmitBytes(StringRef(Augmentation, strlen(Augmentation)+1),0);
EOL("CIE Augmentation");
// Round out reader.
EmitULEB128(1, "CIE Code Alignment Factor");
EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->OutStreamer.AddComment("CIE Return Address Column");
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
EOL("CIE Return Address Column");
if (Augmentation[0]) {
EmitULEB128(AugmentationSize, "Augmentation Size");
@ -153,8 +157,8 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// If there is a personality, we need to indicate the function's location.
if (PersonalityFn) {
EmitEncodingByte(PerEncoding, "Personality");
Asm->OutStreamer.AddComment("Personality");
EmitReference(PersonalityFn, PerEncoding);
EOL("Personality");
}
if (UsesLSDA[Index])
EmitEncodingByte(LSDAEncoding, "LSDA");
@ -171,8 +175,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// be 8-byte on 64-bit targets to match what gcc does. Otherwise you get
// holes which confuse readers of eh_frame.
Asm->EmitAlignment(TD->getPointerSize() == 4 ? 2 : 3, 0, 0, false);
EmitLabel("eh_frame_common_end", Index);
Asm->O << '\n';
Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_end", Index));
}
/// EmitFDE - Emit the Frame Description Entry (FDE) for the function.
@ -190,13 +193,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// Externally visible entry into the functions eh frame info. If the
// corresponding function is static, this should not be externally visible.
if (!TheFunc->hasLocalLinkage())
if (const char *GlobalEHDirective = MAI->getGlobalEHDirective())
O << GlobalEHDirective << *EHFrameInfo.FunctionEHSym << '\n';
if (!TheFunc->hasLocalLinkage() && TLOF.isFunctionEHSymbolGlobal())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,MCSA_Global);
// If corresponding function is weak definition, this should be too.
if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective())
O << MAI->getWeakDefDirective() << *EHFrameInfo.FunctionEHSym << '\n';
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_WeakDefinition);
// If corresponding function is hidden, this should be too.
if (TheFunc->hasHiddenVisibility())
@ -211,8 +214,9 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory &&
(!TheFunc->isWeakForLinker() ||
!MAI->getWeakDefDirective() ||
MAI->getSupportsWeakOmittedEHFrame())) {
O << *EHFrameInfo.FunctionEHSym << " = 0\n";
TLOF.getSupportsWeakOmittedEHFrame())) {
Asm->OutStreamer.EmitAssignment(EHFrameInfo.FunctionEHSym,
MCConstantExpr::Create(0, Asm->OutContext));
// This name has no connection to the function, so it might get
// dead-stripped when the function is not, erroneously. Prohibit
// dead-stripping unconditionally.
@ -220,28 +224,29 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_NoDeadStrip);
} else {
O << *EHFrameInfo.FunctionEHSym << ":\n";
Asm->OutStreamer.EmitLabel(EHFrameInfo.FunctionEHSym);
// EH frame header.
EmitDifference("eh_frame_end", EHFrameInfo.Number,
"eh_frame_begin", EHFrameInfo.Number,
Asm->OutStreamer.AddComment("Length of Frame Information Entry");
EmitDifference(getDWLabel("eh_frame_end", EHFrameInfo.Number),
getDWLabel("eh_frame_begin", EHFrameInfo.Number),
true);
EOL("Length of Frame Information Entry");
EmitLabel("eh_frame_begin", EHFrameInfo.Number);
Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_begin",EHFrameInfo.Number));
EmitSectionOffset("eh_frame_begin", "eh_frame_common",
EHFrameInfo.Number, EHFrameInfo.PersonalityIndex,
true, true, false);
Asm->OutStreamer.AddComment("FDE CIE offset");
EmitSectionOffset(getDWLabel("eh_frame_begin", EHFrameInfo.Number),
getDWLabel("eh_frame_common",
EHFrameInfo.PersonalityIndex),
true, true);
EOL("FDE CIE offset");
EmitReference("eh_func_begin", EHFrameInfo.Number, FDEEncoding);
EOL("FDE initial location");
EmitDifference("eh_func_end", EHFrameInfo.Number,
"eh_func_begin", EHFrameInfo.Number,
Asm->OutStreamer.AddComment("FDE initial location");
EmitReference(getDWLabel("eh_func_begin", EHFrameInfo.Number), FDEEncoding);
Asm->OutStreamer.AddComment("FDE address range");
EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number),
getDWLabel("eh_func_begin", EHFrameInfo.Number),
SizeOfEncodedValue(FDEEncoding) == 4);
EOL("FDE address range");
// If there is a personality and landing pads then point to the language
// specific data area in the exception table.
@ -249,12 +254,12 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
unsigned Size = SizeOfEncodedValue(LSDAEncoding);
EmitULEB128(Size, "Augmentation size");
Asm->OutStreamer.AddComment("Language Specific Data Area");
if (EHFrameInfo.hasLandingPads)
EmitReference("exception", EHFrameInfo.Number, LSDAEncoding);
EmitReference(getDWLabel("exception", EHFrameInfo.Number),LSDAEncoding);
else
Asm->OutStreamer.EmitIntValue(0, Size/*size*/, 0/*addrspace*/);
EOL("Language Specific Data Area");
} else {
EmitULEB128(0, "Augmentation size");
}
@ -268,7 +273,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// get holes which confuse readers of eh_frame.
Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3,
0, 0, false);
EmitLabel("eh_frame_end", EHFrameInfo.Number);
Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_end", EHFrameInfo.Number));
// If the function is marked used, this table should be also. We cannot
// make the mark unconditional in this case, since retaining the table also
@ -280,7 +285,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_NoDeadStrip);
}
Asm->O << '\n';
Asm->OutStreamer.AddBlankLine();
}
/// SharedTypeIds - How many leading type ids two landing pads have in common.
@ -699,15 +704,14 @@ void DwarfException::EmitExceptionTable() {
Asm->EmitAlignment(2, 0, 0, false);
// Emit the LSDA.
O << "GCC_except_table" << SubprogramCount << ":\n";
EmitLabel("exception", SubprogramCount);
MCSymbol *GCCETSym =
Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+
Twine(SubprogramCount));
Asm->OutStreamer.EmitLabel(GCCETSym);
Asm->OutStreamer.EmitLabel(getDWLabel("exception", SubprogramCount));
if (IsSJLJ) {
SmallString<16> LSDAName;
raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() <<
"_LSDA_" << Asm->getFunctionNumber();
O << LSDAName.str() << ":\n";
}
if (IsSJLJ)
Asm->OutStreamer.EmitLabel(getDWLabel("_LSDA_", Asm->getFunctionNumber()));
// Emit the LSDA header.
EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
@ -819,27 +823,30 @@ void DwarfException::EmitExceptionTable() {
// Offset of the call site relative to the previous call site, counted in
// number of 16-byte bundles. The first call site is counted relative to
// the start of the procedure fragment.
EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
Asm->OutStreamer.AddComment("Region start");
EmitSectionOffset(getDWLabel(BeginTag, BeginNumber),
getDWLabel("eh_func_begin", SubprogramCount),
true, true);
EOL("Region start");
Asm->OutStreamer.AddComment("Region length");
if (!S.EndLabel)
EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
EmitDifference(getDWLabel("eh_func_end", SubprogramCount),
getDWLabel(BeginTag, BeginNumber),
true);
else
EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
EmitDifference(getDWLabel("label", S.EndLabel),
getDWLabel(BeginTag, BeginNumber), true);
EOL("Region length");
// Offset of the landing pad, counted in 16-byte bundles relative to the
// @LPStart address.
Asm->OutStreamer.AddComment("Landing pad");
if (!S.PadLabel) {
Asm->OutStreamer.AddComment("Landing pad");
Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
} else {
EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
EmitSectionOffset(getDWLabel("label", S.PadLabel),
getDWLabel("eh_func_begin", SubprogramCount),
true, true);
EOL("Landing pad");
}
// Offset of the first associated action record, relative to the start of
@ -850,11 +857,16 @@ void DwarfException::EmitExceptionTable() {
}
// Emit the Action Table.
if (Actions.size() != 0) EOL("-- Action Record Table --");
if (Actions.size() != 0) {
Asm->OutStreamer.AddComment("-- Action Record Table --");
Asm->OutStreamer.AddBlankLine();
}
for (SmallVectorImpl<ActionEntry>::const_iterator
I = Actions.begin(), E = Actions.end(); I != E; ++I) {
const ActionEntry &Action = *I;
EOL("Action Record:");
Asm->OutStreamer.AddComment("Action Record");
Asm->OutStreamer.AddBlankLine();
// Type Filter
//
@ -870,23 +882,26 @@ void DwarfException::EmitExceptionTable() {
}
// Emit the Catch TypeInfos.
if (!TypeInfos.empty()) EOL("-- Catch TypeInfos --");
if (!TypeInfos.empty()) {
Asm->OutStreamer.AddComment("-- Catch TypeInfos --");
Asm->OutStreamer.AddBlankLine();
}
for (std::vector<GlobalVariable *>::const_reverse_iterator
I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
const GlobalVariable *GV = *I;
if (GV) {
Asm->OutStreamer.AddComment("TypeInfo");
if (GV)
EmitReference(GV, TTypeEncoding);
EOL("TypeInfo");
} else {
PrintRelDirective(TTypeEncoding);
O << "0x0";
EOL("");
}
else
Asm->OutStreamer.EmitIntValue(0, SizeOfEncodedValue(TTypeEncoding), 0);
}
// Emit the Exception Specifications.
if (!FilterIds.empty()) EOL("-- Filter IDs --");
if (!FilterIds.empty()) {
Asm->OutStreamer.AddComment("-- Filter IDs --");
Asm->OutStreamer.AddBlankLine();
}
for (std::vector<unsigned>::const_iterator
I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
unsigned TypeID = *I;
@ -945,7 +960,7 @@ void DwarfException::BeginFunction(const MachineFunction *MF) {
if (shouldEmitMoves || shouldEmitTable)
// Assumes in correct section after the entry point.
EmitLabel("eh_func_begin", ++SubprogramCount);
Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_begin", ++SubprogramCount));
shouldEmitTableModule |= shouldEmitTable;
shouldEmitMovesModule |= shouldEmitMoves;
@ -962,12 +977,13 @@ void DwarfException::EndFunction() {
if (TimePassesIsEnabled)
ExceptionTimer->startTimer();
EmitLabel("eh_func_end", SubprogramCount);
Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_end", SubprogramCount));
EmitExceptionTable();
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
MCSymbol *FunctionEHSym =
Asm->GetSymbolWithGlobalValueBase(MF->getFunction(), ".eh",
Asm->MAI->is_EHSymbolPrivate());
TLOF.isFunctionEHFrameSymbolPrivate());
// Save EH frame information
EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym, SubprogramCount,

View file

@ -1,32 +0,0 @@
//===--- lib/CodeGen/DwarfLabel.cpp - Dwarf Label -------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// DWARF Labels
//
//===----------------------------------------------------------------------===//
#include "DwarfLabel.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
/// Profile - Used to gather unique data for the folding set.
///
void DWLabel::Profile(FoldingSetNodeID &ID) const {
ID.AddString(Tag);
ID.AddInteger(Number);
}
#ifndef NDEBUG
void DWLabel::print(raw_ostream &O) const {
O << "." << Tag;
if (Number) O << Number;
}
#endif

View file

@ -1,52 +0,0 @@
//===--- lib/CodeGen/DwarfLabel.h - Dwarf Label -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// DWARF Labels.
//
//===----------------------------------------------------------------------===//
#ifndef CODEGEN_ASMPRINTER_DWARFLABEL_H__
#define CODEGEN_ASMPRINTER_DWARFLABEL_H__
namespace llvm {
class FoldingSetNodeID;
class raw_ostream;
//===--------------------------------------------------------------------===//
/// DWLabel - Labels are used to track locations in the assembler file.
/// Labels appear in the form @verbatim <prefix><Tag><Number> @endverbatim,
/// where the tag is a category of label (Ex. location) and number is a value
/// unique in that category.
class DWLabel {
/// Tag - Label category tag. Should always be a statically declared C
/// string.
///
const char *Tag;
/// Number - Value to make label unique.
///
unsigned Number;
public:
DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
// Accessors.
const char *getTag() const { return Tag; }
unsigned getNumber() const { return Number; }
/// Profile - Used to gather unique data for the folding set.
///
void Profile(FoldingSetNodeID &ID) const;
#ifndef NDEBUG
void print(raw_ostream &O) const;
#endif
};
} // end llvm namespace
#endif

View file

@ -31,11 +31,31 @@
#include "llvm/ADT/SmallString.h"
using namespace llvm;
DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
const char *flavor)
DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
: O(OS), Asm(A), MAI(T), TD(Asm->TM.getTargetData()),
RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
SubprogramCount(0), Flavor(flavor), SetCounter(1) {}
SubprogramCount(0) {}
/// getDWLabel - Return the MCSymbol corresponding to the assembler temporary
/// label with the specified stem and unique ID.
MCSymbol *DwarfPrinter::getDWLabel(const char *Name, unsigned ID) const {
// FIXME: REMOVE this. However, there is stuff in EH that passes counters in
// here that can be zero.
//assert(ID && "Should use getTempLabel if no ID");
if (ID == 0) return getTempLabel(Name);
return Asm->OutContext.GetOrCreateTemporarySymbol
(Twine(MAI->getPrivateGlobalPrefix()) + Twine(Name) + Twine(ID));
}
/// getTempLabel - Return the MCSymbol corresponding to the assembler temporary
/// label with the specified name.
MCSymbol *DwarfPrinter::getTempLabel(const char *Name) const {
return Asm->OutContext.GetOrCreateTemporarySymbol
(Twine(MAI->getPrivateGlobalPrefix()) + Name);
}
/// SizeOfEncodedValue - Return the size of the encoding in bytes.
unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const {
@ -57,33 +77,6 @@ unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const {
return 0;
}
void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const {
if (isInSection && MAI->getDwarfSectionOffsetDirective())
O << MAI->getDwarfSectionOffsetDirective();
else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t))
O << MAI->getData32bitsDirective();
else
O << MAI->getData64bitsDirective();
}
void DwarfPrinter::PrintRelDirective(unsigned Encoding) const {
unsigned Size = SizeOfEncodedValue(Encoding);
assert((Size == 4 || Size == 8) && "Do not support other types or rels!");
O << (Size == 4 ?
MAI->getData32bitsDirective() : MAI->getData64bitsDirective());
}
/// EOL - Print a newline character to asm stream. If a comment is present
/// then it will be printed first. Comments should not contain '\n'.
void DwarfPrinter::EOL(const Twine &Comment) const {
if (Asm->VerboseAsm && !Comment.isTriviallyEmpty()) {
Asm->O.PadToColumn(MAI->getCommentColumn());
Asm->O << Asm->MAI->getCommentString() << ' ' << Comment;
}
Asm->O << '\n';
}
static const char *DecodeDWARFEncoding(unsigned Encoding) {
switch (Encoding) {
case dwarf::DW_EH_PE_absptr: return "absptr";
@ -145,6 +138,7 @@ void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const {
Asm->OutStreamer.AddComment(Desc);
if (MAI->hasLEB128()) {
// FIXME: MCize.
O << "\t.sleb128\t" << Value;
Asm->OutStreamer.AddBlankLine();
return;
@ -170,6 +164,7 @@ void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc,
Asm->OutStreamer.AddComment(Desc);
if (MAI->hasLEB128() && PadTo == 0) {
// FIXME: MCize.
O << "\t.uleb128\t" << Value;
Asm->OutStreamer.AddBlankLine();
return;
@ -191,134 +186,48 @@ void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc,
}
/// PrintLabelName - Print label name in form used by Dwarf writer.
///
void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number) const {
O << MAI->getPrivateGlobalPrefix() << Tag;
if (Number) O << Number;
}
void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number,
const char *Suffix) const {
O << MAI->getPrivateGlobalPrefix() << Tag;
if (Number) O << Number;
O << Suffix;
}
/// EmitLabel - Emit location label for internal use by Dwarf.
///
void DwarfPrinter::EmitLabel(const char *Tag, unsigned Number) const {
PrintLabelName(Tag, Number);
O << ":\n";
}
/// EmitReference - Emit a reference to a label.
///
void DwarfPrinter::EmitReference(const char *Tag, unsigned Number,
bool IsPCRelative, bool Force32Bit) const {
PrintRelDirective(Force32Bit);
PrintLabelName(Tag, Number);
if (IsPCRelative) O << "-" << MAI->getPCSymbol();
}
void DwarfPrinter::EmitReference(const std::string &Name, bool IsPCRelative,
bool Force32Bit) const {
PrintRelDirective(Force32Bit);
O << Name;
if (IsPCRelative) O << "-" << MAI->getPCSymbol();
}
void DwarfPrinter::EmitReference(const MCSymbol *Sym, bool IsPCRelative,
bool Force32Bit) const {
PrintRelDirective(Force32Bit);
O << *Sym;
if (IsPCRelative) O << "-" << MAI->getPCSymbol();
}
void DwarfPrinter::EmitReference(const char *Tag, unsigned Number,
unsigned Encoding) const {
SmallString<64> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
<< Tag << Number;
MCSymbol *Sym = Asm->OutContext.GetOrCreateSymbol(Name.str());
EmitReference(Sym, Encoding);
}
void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
PrintRelDirective(Encoding);
O << *TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding);;
const MCExpr *Exp = TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding);
Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0);
}
void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const {
void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
PrintRelDirective(Encoding);
O << *TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang,
Asm->MMI, Encoding);;
const MCExpr *Exp =
TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang, Asm->MMI, Encoding);
Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0);
}
/// EmitDifference - Emit the difference between two labels. If this assembler
/// supports .set, we emit a .set of a temporary and then use it in the .word.
void DwarfPrinter::EmitDifference(const char *TagHi, unsigned NumberHi,
const char *TagLo, unsigned NumberLo,
void DwarfPrinter::EmitDifference(const MCSymbol *TagHi, const MCSymbol *TagLo,
bool IsSmall) {
if (MAI->hasSetDirective()) {
// FIXME: switch to OutStreamer.EmitAssignment.
O << "\t.set\t";
PrintLabelName("set", SetCounter, Flavor);
O << ",";
PrintLabelName(TagHi, NumberHi);
O << "-";
PrintLabelName(TagLo, NumberLo);
O << "\n";
PrintRelDirective(IsSmall);
PrintLabelName("set", SetCounter, Flavor);
++SetCounter;
} else {
PrintRelDirective(IsSmall);
PrintLabelName(TagHi, NumberHi);
O << "-";
PrintLabelName(TagLo, NumberLo);
}
unsigned Size = IsSmall ? 4 : TD->getPointerSize();
Asm->EmitLabelDifference(TagHi, TagLo, Size);
}
void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section,
unsigned LabelNumber,
unsigned SectionNumber,
bool IsSmall, bool isEH,
bool useSet) {
bool printAbsolute = false;
void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label,
const MCSymbol *Section,
bool IsSmall, bool isEH) {
bool isAbsolute;
if (isEH)
printAbsolute = MAI->isAbsoluteEHSectionOffsets();
isAbsolute = MAI->isAbsoluteEHSectionOffsets();
else
printAbsolute = MAI->isAbsoluteDebugSectionOffsets();
isAbsolute = MAI->isAbsoluteDebugSectionOffsets();
if (MAI->hasSetDirective() && useSet) {
// FIXME: switch to OutStreamer.EmitAssignment.
O << "\t.set\t";
PrintLabelName("set", SetCounter, Flavor);
O << ",";
PrintLabelName(Label, LabelNumber);
if (!printAbsolute) {
O << "-";
PrintLabelName(Section, SectionNumber);
}
O << "\n";
PrintRelDirective(IsSmall);
PrintLabelName("set", SetCounter, Flavor);
++SetCounter;
} else {
PrintRelDirective(IsSmall, true);
PrintLabelName(Label, LabelNumber);
if (!printAbsolute) {
O << "-";
PrintLabelName(Section, SectionNumber);
}
if (!isAbsolute)
return EmitDifference(Label, Section, IsSmall);
// On COFF targets, we have to emit the weird .secrel32 directive.
if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective())
// FIXME: MCize.
Asm->O << SecOffDir << Label->getName();
else {
unsigned Size = IsSmall ? 4 : TD->getPointerSize();
Asm->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/);
}
}
@ -337,12 +246,9 @@ void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
const MachineMove &Move = Moves[i];
unsigned LabelID = Move.getLabelID();
if (LabelID) {
LabelID = MMI->MappedLabel(LabelID);
// Throw out move if the label is invalid.
if (!LabelID) continue;
}
// Throw out move if the label is invalid.
if (LabelID && MMI->isLabelDeleted(LabelID))
continue;
const MachineLocation &Dst = Move.getDestination();
const MachineLocation &Src = Move.getSource();
@ -350,9 +256,8 @@ void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
// Advance row if new location.
if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
EmitCFAByte(dwarf::DW_CFA_advance_loc4);
EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true);
Asm->O << '\n';
EmitDifference(getDWLabel("label", LabelID),
getDWLabel(BaseLabel, BaseLabelID), true);
BaseLabelID = LabelID;
BaseLabel = "label";
IsLocal = true;

View file

@ -14,7 +14,6 @@
#ifndef CODEGEN_ASMPRINTER_DWARFPRINTER_H__
#define CODEGEN_ASMPRINTER_DWARFPRINTER_H__
#include "DwarfLabel.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/FormattedStream.h"
@ -67,15 +66,7 @@ protected:
/// SubprogramCount - The running count of functions being compiled.
unsigned SubprogramCount;
/// Flavor - A unique string indicating what dwarf producer this is, used to
/// unique labels.
const char * const Flavor;
/// SetCounter - A unique number for each '.set' directive.
unsigned SetCounter;
DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
const char *flavor);
DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T);
public:
//===------------------------------------------------------------------===//
@ -86,17 +77,17 @@ public:
const MCAsmInfo *getMCAsmInfo() const { return MAI; }
const TargetData *getTargetData() const { return TD; }
/// getDWLabel - Return the MCSymbol corresponding to the assembler temporary
/// label with the specified stem and unique ID.
MCSymbol *getDWLabel(const char *Name, unsigned ID) const;
/// getTempLabel - Return an assembler temporary label with the specified
/// name.
MCSymbol *getTempLabel(const char *Name) const;
/// SizeOfEncodedValue - Return the size of the encoding in bytes.
unsigned SizeOfEncodedValue(unsigned Encoding) const;
void PrintRelDirective(unsigned Encoding) const;
void PrintRelDirective(bool Force32Bit = false,
bool isInSection = false) const;
/// EOL - Print a newline character to asm stream. If a comment is present
/// then it will be printed first. Comments should not contain '\n'.
void EOL(const Twine &Comment) const;
/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
/// encoding. If verbose assembly output is enabled, we output comments
/// describing the encoding. Desc is a string saying what the encoding is
@ -115,57 +106,20 @@ public:
unsigned PadTo = 0) const;
/// PrintLabelName - Print label name in form used by Dwarf writer.
///
void PrintLabelName(const DWLabel &Label) const {
PrintLabelName(Label.getTag(), Label.getNumber());
}
void PrintLabelName(const char *Tag, unsigned Number) const;
void PrintLabelName(const char *Tag, unsigned Number,
const char *Suffix) const;
/// EmitLabel - Emit location label for internal use by Dwarf.
///
void EmitLabel(const DWLabel &Label) const {
EmitLabel(Label.getTag(), Label.getNumber());
}
void EmitLabel(const char *Tag, unsigned Number) const;
/// EmitReference - Emit a reference to a label.
///
void EmitReference(const DWLabel &Label, bool IsPCRelative = false,
bool Force32Bit = false) const {
EmitReference(Label.getTag(), Label.getNumber(),
IsPCRelative, Force32Bit);
}
void EmitReference(const char *Tag, unsigned Number,
bool IsPCRelative = false,
bool Force32Bit = false) const;
void EmitReference(const std::string &Name, bool IsPCRelative = false,
bool Force32Bit = false) const;
void EmitReference(const MCSymbol *Sym, bool IsPCRelative = false,
bool Force32Bit = false) const;
void EmitReference(const char *Tag, unsigned Number, unsigned Encoding) const;
void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
/// EmitDifference - Emit the difference between two labels.
void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo,
bool IsSmall = false) {
EmitDifference(LabelHi.getTag(), LabelHi.getNumber(),
LabelLo.getTag(), LabelLo.getNumber(),
IsSmall);
}
void EmitDifference(const char *TagHi, unsigned NumberHi,
const char *TagLo, unsigned NumberLo,
void EmitDifference(const MCSymbol *LabelHi, const MCSymbol *LabelLo,
bool IsSmall = false);
void EmitSectionOffset(const char* Label, const char* Section,
unsigned LabelNumber, unsigned SectionNumber,
bool IsSmall = false, bool isEH = false,
bool useSet = true);
/// EmitSectionOffset - Emit Label-Section or use a special purpose directive
/// to emit a section offset if the target has one.
void EmitSectionOffset(const MCSymbol *Label, const MCSymbol *Section,
bool IsSmall = false, bool isEH = false);
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,

View file

@ -73,11 +73,11 @@ void DwarfWriter::EndFunction(const MachineFunction *MF) {
MMI->EndFunction();
}
/// RecordSourceLine - Records location information and associates it with a
/// label. Returns a unique label ID used to generate a label and provide
/// correspondence to the source line list.
unsigned DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
MDNode *Scope) {
/// RecordSourceLine - Register a source line with debug info. Returns the
/// unique label that was emitted and which provides correspondence to
/// the source line list.
MCSymbol *DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col,
MDNode *Scope) {
return DD->recordSourceLine(Line, Col, Scope);
}
@ -92,7 +92,7 @@ bool DwarfWriter::ShouldEmitDwarfDebug() const {
return DD && DD->ShouldEmitDwarfDebug();
}
void DwarfWriter::BeginScope(const MachineInstr *MI, unsigned L) {
void DwarfWriter::BeginScope(const MachineInstr *MI, MCSymbol *L) {
DD->beginScope(MI, L);
}
void DwarfWriter::EndScope(const MachineInstr *MI) {

View file

@ -310,12 +310,23 @@ static unsigned HashEndOfMBB(const MachineBasicBlock *MBB,
return 0; // Empty MBB.
--I;
// Skip debug info so it will not affect codegen.
while (I->isDebugValue()) {
if (I==MBB->begin())
return 0; // MBB empty except for debug info.
--I;
}
unsigned Hash = HashMachineInstr(I);
if (I == MBB->begin() || minCommonTailLength == 1)
return Hash; // Single instr MBB.
--I;
while (I->isDebugValue()) {
if (I==MBB->begin())
return Hash; // MBB with single non-debug instr.
--I;
}
// Hash in the second-to-last instruction.
Hash ^= HashMachineInstr(I) << 2;
return Hash;
@ -334,9 +345,32 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
unsigned TailLen = 0;
while (I1 != MBB1->begin() && I2 != MBB2->begin()) {
--I1; --I2;
// Don't merge debugging pseudos.
if (I1->isDebugValue() || I2->isDebugValue() ||
!I1->isIdenticalTo(I2) ||
// Skip debugging pseudos; necessary to avoid changing the code.
while (I1->isDebugValue()) {
if (I1==MBB1->begin()) {
while (I2->isDebugValue()) {
if (I2==MBB2->begin())
// I1==DBG at begin; I2==DBG at begin
return TailLen;
--I2;
}
++I2;
// I1==DBG at begin; I2==non-DBG, or first of DBGs not at begin
return TailLen;
}
--I1;
}
// I1==first (untested) non-DBG preceding known match
while (I2->isDebugValue()) {
if (I2==MBB2->begin()) {
++I1;
// I1==non-DBG, or first of DBGs not at begin; I2==DBG at begin
return TailLen;
}
--I2;
}
// I1, I2==first (untested) non-DBGs preceding known match
if (!I1->isIdenticalTo(I2) ||
// FIXME: This check is dubious. It's used to get around a problem where
// people incorrectly expect inline asm directives to remain in the same
// relative order. This is untenable because normal compiler
@ -348,6 +382,29 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
}
++TailLen;
}
// Back past possible debugging pseudos at beginning of block. This matters
// when one block differs from the other only by whether debugging pseudos
// are present at the beginning. (This way, the various checks later for
// I1==MBB1->begin() work as expected.)
if (I1 == MBB1->begin() && I2 != MBB2->begin()) {
--I2;
while (I2->isDebugValue()) {
if (I2 == MBB2->begin()) {
return TailLen;
}
--I2;
}
++I2;
}
if (I2 == MBB2->begin() && I1 != MBB1->begin()) {
--I1;
while (I1->isDebugValue()) {
if (I1 == MBB1->begin())
return TailLen;
--I1;
}
++I1;
}
return TailLen;
}
@ -643,6 +700,8 @@ unsigned BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
SameTails[commonTailIndex].getTailStartPos();
MachineBasicBlock *MBB = SameTails[commonTailIndex].getBlock();
// If the common tail includes any debug info we will take it pretty
// randomly from one of the inputs. Might be better to remove it?
DEBUG(dbgs() << "\nSplitting BB#" << MBB->getNumber() << ", size "
<< maxCommonTailLength);
@ -912,6 +971,18 @@ bool BranchFolder::OptimizeBranches(MachineFunction &MF) {
return MadeChange;
}
// Blocks should be considered empty if they contain only debug info;
// else the debug info would affect codegen.
static bool IsEmptyBlock(MachineBasicBlock *MBB) {
if (MBB->empty())
return true;
for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end();
MBBI!=MBBE; ++MBBI) {
if (!MBBI->isDebugValue())
return false;
}
return true;
}
/// IsBetterFallthrough - Return true if it would be clearly better to
/// fall-through to MBB1 than to fall through into MBB2. This has to return
@ -949,7 +1020,7 @@ ReoptimizeBlock:
// explicitly. Landing pads should not do this since the landing-pad table
// points to this block. Blocks with their addresses taken shouldn't be
// optimized away.
if (MBB->empty() && !MBB->isLandingPad() && !MBB->hasAddressTaken()) {
if (IsEmptyBlock(MBB) && !MBB->isLandingPad() && !MBB->hasAddressTaken()) {
// Dead block? Leave for cleanup later.
if (MBB->pred_empty()) return MadeChange;
@ -1141,7 +1212,23 @@ ReoptimizeBlock:
// be 'non-branch terminators' in the block, try removing the branch and
// then seeing if the block is empty.
TII->RemoveBranch(*MBB);
// If the only things remaining in the block are debug info, remove these
// as well, so this will behave the same as an empty block in non-debug
// mode.
if (!MBB->empty()) {
bool NonDebugInfoFound = false;
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
if (!I->isDebugValue()) {
NonDebugInfoFound = true;
break;
}
}
if (!NonDebugInfoFound)
// Make the block empty, losing the debug info (we could probably
// improve this in some cases.)
MBB->erase(MBB->begin(), MBB->end());
}
// If this block is just an unconditional branch to CurTBB, we can
// usually completely eliminate the block. The only case we cannot
// completely eliminate the block is when the block before this one

View file

@ -67,9 +67,6 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
cl::desc("Verify generated machine code"),
cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));
static cl::opt<bool> EnableMachineCSE("enable-machine-cse", cl::Hidden,
cl::desc("Enable Machine CSE"));
static cl::opt<cl::boolOrDefault>
AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
cl::init(cl::BOU_UNSET));
@ -328,11 +325,10 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
PM.add(createOptimizeExtsPass());
if (!DisableMachineLICM)
PM.add(createMachineLICMPass());
if (EnableMachineCSE)
PM.add(createMachineCSEPass());
PM.add(createMachineCSEPass());
if (!DisableMachineSink)
PM.add(createMachineSinkingPass());
printAndVerify(PM, "After MachineLICM and MachineSinking",
printAndVerify(PM, "After Machine LICM, CSE and Sinking passes",
/* allowDoubleDefs= */ true);
}

View file

@ -593,13 +593,10 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
MachineBasicBlock::iterator E = MBB->end();
while (mi != E) {
if (mi->isDebugValue()) {
while (mi != E && mi->isDebugValue())
++mi;
if (mi != E && !mi->isDebugValue()) {
baseIndex = indexes_->getNextNonNullIndex(baseIndex);
}
continue;
}
if (mi == E)
break;
if (mi->killsRegister(interval.reg, tri_)) {
DEBUG(dbgs() << " killed");
end = baseIndex.getDefIndex();

View file

@ -42,12 +42,11 @@ MachineBasicBlock::~MachineBasicBlock() {
/// getSymbol - Return the MCSymbol for this basic block.
///
MCSymbol *MachineBasicBlock::getSymbol(MCContext &Ctx) const {
SmallString<60> Name;
const MachineFunction *MF = getParent();
raw_svector_ostream(Name)
<< MF->getTarget().getMCAsmInfo()->getPrivateGlobalPrefix() << "BB"
<< MF->getFunctionNumber() << '_' << getNumber();
return Ctx.GetOrCreateSymbol(Name.str());
const char *Prefix = MF->getTarget().getMCAsmInfo()->getPrivateGlobalPrefix();
return Ctx.GetOrCreateTemporarySymbol(Twine(Prefix) + "BB" +
Twine(MF->getFunctionNumber()) + "_" +
Twine(getNumber()));
}

View file

@ -33,9 +33,9 @@ namespace {
class MachineCSE : public MachineFunctionPass {
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
MachineRegisterInfo *MRI;
MachineDominatorTree *DT;
AliasAnalysis *AA;
MachineDominatorTree *DT;
MachineRegisterInfo *MRI;
public:
static char ID; // Pass identification
MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {}
@ -61,6 +61,8 @@ namespace {
MachineBasicBlock::const_iterator E);
bool hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB);
bool isCSECandidate(MachineInstr *MI);
bool isProfitableToCSE(unsigned CSReg, unsigned Reg,
MachineInstr *CSMI, MachineInstr *MI);
bool ProcessBlock(MachineDomTreeNode *Node);
};
} // end anonymous namespace
@ -92,7 +94,16 @@ bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
TargetRegisterInfo::isVirtualRegister(SrcReg) &&
!SrcSubIdx && !DstSubIdx) {
const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg);
const TargetRegisterClass *RC = MRI->getRegClass(Reg);
const TargetRegisterClass *NewRC = getCommonSubClass(RC, SRC);
if (!NewRC)
continue;
DEBUG(dbgs() << "Coalescing: " << *DefMI);
DEBUG(dbgs() << "*** to: " << *MI);
MO.setReg(SrcReg);
if (NewRC != SRC)
MRI->setRegClass(SrcReg, NewRC);
DefMI->eraseFromParent();
++NumCoalesces;
Changed = true;
@ -133,6 +144,8 @@ bool MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
return false;
}
/// hasLivePhysRegDefUse - Return true if the specified instruction read / write
/// physical registers (except for dead defs of physical registers).
bool MachineCSE::hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB){
unsigned PhysDef = 0;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
@ -167,12 +180,19 @@ bool MachineCSE::hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB){
return false;
}
bool MachineCSE::isCSECandidate(MachineInstr *MI) {
// Ignore copies or instructions that read / write physical registers
// (except for dead defs of physical registers).
static bool isCopy(const MachineInstr *MI, const TargetInstrInfo *TII) {
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) ||
MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg())
return TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) ||
MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg();
}
bool MachineCSE::isCSECandidate(MachineInstr *MI) {
if (MI->isLabel() || MI->isPHI() || MI->isImplicitDef() ||
MI->isKill() || MI->isInlineAsm())
return false;
// Ignore copies.
if (isCopy(MI, TII))
return false;
// Ignore stuff that we obviously can't move.
@ -194,9 +214,69 @@ bool MachineCSE::isCSECandidate(MachineInstr *MI) {
return true;
}
/// isProfitableToCSE - Return true if it's profitable to eliminate MI with a
/// common expression that defines Reg.
bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg,
MachineInstr *CSMI, MachineInstr *MI) {
// FIXME: Heuristics that works around the lack the live range splitting.
// Heuristics #1: Don't cse "cheap" computating if the def is not local or in an
// immediate predecessor. We don't want to increase register pressure and end up
// causing other computation to be spilled.
if (MI->getDesc().isAsCheapAsAMove()) {
MachineBasicBlock *CSBB = CSMI->getParent();
MachineBasicBlock *BB = MI->getParent();
if (CSBB != BB &&
find(CSBB->succ_begin(), CSBB->succ_end(), BB) == CSBB->succ_end())
return false;
}
// Heuristics #2: If the expression doesn't not use a vr and the only use
// of the redundant computation are copies, do not cse.
bool HasVRegUse = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
if (MO.isReg() && MO.isUse() && MO.getReg() &&
TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
HasVRegUse = true;
break;
}
}
if (!HasVRegUse) {
bool HasNonCopyUse = false;
for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(Reg),
E = MRI->use_nodbg_end(); I != E; ++I) {
MachineInstr *Use = &*I;
// Ignore copies.
if (!isCopy(Use, TII)) {
HasNonCopyUse = true;
break;
}
}
if (!HasNonCopyUse)
return false;
}
// Heuristics #3: If the common subexpression is used by PHIs, do not reuse
// it unless the defined value is already used in the BB of the new use.
bool HasPHI = false;
SmallPtrSet<MachineBasicBlock*, 4> CSBBs;
for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(CSReg),
E = MRI->use_nodbg_end(); I != E; ++I) {
MachineInstr *Use = &*I;
HasPHI |= Use->isPHI();
CSBBs.insert(Use->getParent());
}
if (!HasPHI)
return true;
return CSBBs.count(MI->getParent());
}
bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
bool Changed = false;
SmallVector<std::pair<unsigned, unsigned>, 8> CSEPairs;
ScopedHashTableScope<MachineInstr*, unsigned,
MachineInstrExpressionTrait> VNTS(VNT);
MachineBasicBlock *MBB = Node->getBlock();
@ -231,6 +311,9 @@ bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
MachineInstr *CSMI = Exps[CSVN];
DEBUG(dbgs() << "Examining: " << *MI);
DEBUG(dbgs() << "*** Found a common subexpression: " << *CSMI);
// Check if it's profitable to perform this CSE.
bool DoCSE = true;
unsigned NumDefs = MI->getDesc().getNumDefs();
for (unsigned i = 0, e = MI->getNumOperands(); NumDefs && i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
@ -243,11 +326,26 @@ bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
assert(TargetRegisterInfo::isVirtualRegister(OldReg) &&
TargetRegisterInfo::isVirtualRegister(NewReg) &&
"Do not CSE physical register defs!");
MRI->replaceRegWith(OldReg, NewReg);
if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) {
DoCSE = false;
break;
}
CSEPairs.push_back(std::make_pair(OldReg, NewReg));
--NumDefs;
}
MI->eraseFromParent();
++NumCSEs;
// Actually perform the elimination.
if (DoCSE) {
for (unsigned i = 0, e = CSEPairs.size(); i != e; ++i)
MRI->replaceRegWith(CSEPairs[i].first, CSEPairs[i].second);
MI->eraseFromParent();
++NumCSEs;
} else {
DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n");
VNT.insert(MI, CurrVN++);
Exps.push_back(MI);
}
CSEPairs.clear();
}
// Recursively call ProcessBlock with childred.
@ -262,7 +360,7 @@ bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getTarget().getInstrInfo();
TRI = MF.getTarget().getRegisterInfo();
MRI = &MF.getRegInfo();
DT = &getAnalysis<MachineDominatorTree>();
AA = &getAnalysis<AliasAnalysis>();
DT = &getAnalysis<MachineDominatorTree>();
return ProcessBlock(DT->getRootNode());
}

View file

@ -464,7 +464,9 @@ MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx,
SmallString<60> Name;
raw_svector_ostream(Name)
<< Prefix << "JTI" << getFunctionNumber() << '_' << JTI;
return Ctx.GetOrCreateSymbol(Name.str());
if (isLinkerPrivate)
return Ctx.GetOrCreateSymbol(Name.str());
return Ctx.GetOrCreateTemporarySymbol(Name.str());
}

View file

@ -1219,7 +1219,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
DIScope Scope = DLT.getScope();
OS << " dbg:";
// Omit the directory, since it's usually long and uninteresting.
if (!Scope.isNull())
if (Scope.Verify())
OS << Scope.getFilename();
else
OS << "<unknown>";

View file

@ -185,7 +185,8 @@ void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
void MachineModuleInfo::TidyLandingPads() {
for (unsigned i = 0; i != LandingPads.size(); ) {
LandingPadInfo &LandingPad = LandingPads[i];
LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
if (isLabelDeleted(LandingPad.LandingPadLabel))
LandingPad.LandingPadLabel = 0;
// Special case: we *should* emit LPs with null LP MBB. This indicates
// "nounwind" case.
@ -195,17 +196,14 @@ void MachineModuleInfo::TidyLandingPads() {
}
for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
if (!BeginLabel || !EndLabel) {
unsigned BeginLabel = LandingPad.BeginLabels[j];
unsigned EndLabel = LandingPad.EndLabels[j];
if (isLabelDeleted(BeginLabel) || isLabelDeleted(EndLabel)) {
LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
continue;
}
LandingPad.BeginLabels[j] = BeginLabel;
LandingPad.EndLabels[j] = EndLabel;
++j;
}

View file

@ -57,6 +57,7 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL;
FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
FrameConstantRegMap.clear();
// Get MachineModuleInfo so that we can track the construction of the
// frame.
@ -685,7 +686,7 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
// If this instruction has a FrameIndex operand, we need to
// use that target machine register info object to eliminate
// it.
int Value;
TargetRegisterInfo::FrameIndexValue Value;
unsigned VReg =
TRI.eliminateFrameIndex(MI, SPAdj, &Value,
FrameIndexVirtualScavenging ? NULL : RS);
@ -764,12 +765,12 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
unsigned CurrentVirtReg = 0;
unsigned CurrentScratchReg = 0;
bool havePrevValue = false;
int PrevValue = 0;
TargetRegisterInfo::FrameIndexValue PrevValue(0,0);
TargetRegisterInfo::FrameIndexValue Value(0,0);
MachineInstr *PrevLastUseMI = NULL;
unsigned PrevLastUseOp = 0;
bool trackingCurrentValue = false;
int SPAdj = 0;
int Value = 0;
// The instruction stream may change in the loop, so check BB->end()
// directly.
@ -826,8 +827,11 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
if (trackingCurrentValue) {
SPAdj = (*Entry).second.second;
Value = (*Entry).second.first;
} else
SPAdj = Value = 0;
} else {
SPAdj = 0;
Value.first = 0;
Value.second = 0;
}
// If the scratch register from the last allocation is still
// available, see if the value matches. If it does, just re-use it.

View file

@ -102,7 +102,8 @@ namespace llvm {
// When using the scavenger post-pass to resolve frame reference
// materialization registers, maintain a map of the registers to
// the constant value and SP adjustment associated with it.
typedef std::pair<int, int> FrameConstantEntry;
typedef std::pair<TargetRegisterInfo::FrameIndexValue, int>
FrameConstantEntry;
DenseMap<unsigned, FrameConstantEntry> FrameConstantRegMap;
#ifndef NDEBUG

View file

@ -34,14 +34,16 @@ class SDDbgValue {
MDNode *mdPtr;
uint64_t Offset;
DebugLoc DL;
unsigned Order;
public:
// Constructor for non-constants.
SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl) :
Node(N), ResNo(R), Const(0), mdPtr(mdP), Offset(off), DL(dl) {}
SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl,
unsigned O) :
Node(N), ResNo(R), Const(0), mdPtr(mdP), Offset(off), DL(dl), Order(O) {}
// Constructor for constants.
SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl) : Node(0),
ResNo(0), Const(C), mdPtr(mdP), Offset(off), DL(dl) {}
SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl, unsigned O) :
Node(0), ResNo(0), Const(C), mdPtr(mdP), Offset(off), DL(dl), Order(O) {}
// Returns the MDNode pointer.
MDNode *getMDPtr() { return mdPtr; }
@ -60,6 +62,10 @@ public:
// Returns the DebugLoc.
DebugLoc getDebugLoc() { return DL; }
// Returns the SDNodeOrder. This is the order of the preceding node in the
// input.
unsigned getOrder() { return Order; }
};
} // end llvm namespace

View file

@ -3208,7 +3208,7 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
bool isSrcConst = isa<ConstantSDNode>(Src);
EVT VT = TLI.getOptimalMemOpType(Size, Align, isSrcConst, isSrcStr, DAG);
bool AllowUnalign = TLI.allowsUnalignedMemoryAccesses(VT);
if (VT != MVT::iAny) {
if (VT != MVT::Other) {
const Type *Ty = VT.getTypeForEVT(*DAG.getContext());
unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
// If source is a string constant, this will require an unaligned load.
@ -3216,14 +3216,14 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
if (Dst.getOpcode() != ISD::FrameIndex) {
// Can't change destination alignment. It requires a unaligned store.
if (AllowUnalign)
VT = MVT::iAny;
VT = MVT::Other;
} else {
int FI = cast<FrameIndexSDNode>(Dst)->getIndex();
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
if (MFI->isFixedObjectIndex(FI)) {
// Can't change destination alignment. It requires a unaligned store.
if (AllowUnalign)
VT = MVT::iAny;
VT = MVT::Other;
} else {
// Give the stack frame object a larger alignment if needed.
if (MFI->getObjectAlignment(FI) < NewAlign)
@ -3234,7 +3234,7 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
}
}
if (VT == MVT::iAny) {
if (VT == MVT::Other) {
if (TLI.allowsUnalignedMemoryAccesses(MVT::i64)) {
VT = MVT::i64;
} else {

View file

@ -2141,6 +2141,9 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
while (1) {
assert(MatcherIndex < TableSize && "Invalid index");
#ifndef NDEBUG
unsigned CurrentOpcodeIndex = MatcherIndex;
#endif
BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++];
switch (Opcode) {
case OPC_Scope: {
@ -2666,6 +2669,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
// If the code reached this point, then the match failed. See if there is
// another child to try in the current 'Scope', otherwise pop it until we
// find a case to check.
DEBUG(errs() << " Match failed at index " << CurrentOpcodeIndex << "\n");
while (1) {
if (MatchScopes.empty()) {
CannotYetSelect(NodeToMatch);
@ -2680,13 +2684,12 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
NodeStack.append(LastScope.NodeStack.begin(), LastScope.NodeStack.end());
N = NodeStack.back();
DEBUG(errs() << " Match failed at index " << MatcherIndex
<< " continuing at " << LastScope.FailIndex << "\n");
if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size())
MatchedMemRefs.resize(LastScope.NumMatchedMemRefs);
MatcherIndex = LastScope.FailIndex;
DEBUG(errs() << " Continuing at " << MatcherIndex << "\n");
InputChain = LastScope.InputChain;
InputFlag = LastScope.InputFlag;
if (!LastScope.HasChainNodesMatched)

View file

@ -1671,8 +1671,20 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// density, do not join them, instead mark the physical register as its
// allocation preference.
LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt;
LiveInterval &JoinPInt = SrcIsPhys ? SrcInt : DstInt;
unsigned JoinVReg = SrcIsPhys ? DstReg : SrcReg;
unsigned JoinPReg = SrcIsPhys ? SrcReg : DstReg;
// Don't join with physregs that have a ridiculous number of live
// ranges. The data structure performance is really bad when that
// happens.
if (JoinPInt.ranges.size() > 1000) {
mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
++numAborts;
DEBUG(dbgs() << "\tPhysical register too complicated, abort!\n");
return false;
}
const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
unsigned Length = li_->getApproximateInstructionCount(JoinVInt);

View file

@ -403,12 +403,15 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
// Add information about the stub reference to ELFMMI so that the stub
// gets emitted by the asmprinter.
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
MCSymbol *Sym = getContext().GetOrCreateTemporarySymbol(Name.str());
MCSymbol *&StubSym = ELFMMI.getGVStubEntry(Sym);
if (StubSym == 0) {
Name.clear();
Mang->getNameWithPrefix(Name, GV, false);
StubSym = getContext().GetOrCreateSymbol(Name.str());
if (GV->hasPrivateLinkage())
StubSym = getContext().GetOrCreateTemporarySymbol(Name.str());
else
StubSym = getContext().GetOrCreateSymbol(Name.str());
}
return TargetLoweringObjectFile::
@ -463,6 +466,14 @@ getMachOSection(StringRef Segment, StringRef Section,
void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
// _foo.eh symbols are currently always exported so that the linker knows
// about them. This is not necessary on 10.6 and later, but it
// doesn't hurt anything.
// FIXME: I need to get this from Triple.
IsFunctionEHSymbolGlobal = true;
IsFunctionEHFrameSymbolPrivate = false;
SupportsWeakOmittedEHFrame = false;
if (UniquingMap != 0)
((MachOUniqueMapTy*)UniquingMap)->clear();
TargetLoweringObjectFile::Initialize(Ctx, TM);
@ -651,16 +662,16 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
}
// FIXME: Alignment check should be handled by section classifier.
if (Kind.isMergeable1ByteCString() ||
(Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage())) {
if (TM.getTargetData()->getPreferredAlignment(
cast<GlobalVariable>(GV)) < 32) {
if (Kind.isMergeable1ByteCString())
return CStringSection;
assert(Kind.isMergeable2ByteCString());
return UStringSection;
}
}
if (Kind.isMergeable1ByteCString() &&
TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
return CStringSection;
// Do not put 16-bit arrays in the UString section if they have an
// externally visible label, this runs into issues with certain linker
// versions.
if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() &&
TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
return UStringSection;
if (Kind.isMergeableConst()) {
if (Kind.isMergeableConst4())
@ -749,12 +760,15 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
// Add information about the stub reference to MachOMMI so that the stub
// gets emitted by the asmprinter.
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str());
MCSymbol *Sym = getContext().GetOrCreateTemporarySymbol(Name.str());
MCSymbol *&StubSym = MachOMMI.getGVStubEntry(Sym);
if (StubSym == 0) {
Name.clear();
Mang->getNameWithPrefix(Name, GV, false);
StubSym = getContext().GetOrCreateSymbol(Name.str());
if (GV->hasPrivateLinkage())
StubSym = getContext().GetOrCreateTemporarySymbol(Name.str());
else
StubSym = getContext().GetOrCreateSymbol(Name.str());
}
return TargetLoweringObjectFile::

View file

@ -75,10 +75,9 @@ JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
unsigned LabelID = Move.getLabelID();
if (LabelID) {
LabelID = MMI->MappedLabel(LabelID);
// Throw out move if the label is invalid.
if (!LabelID) continue;
if (MMI->isLabelDeleted(LabelID))
continue;
}
intptr_t LabelPtr = 0;
@ -722,10 +721,9 @@ JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr,
unsigned LabelID = Move.getLabelID();
if (LabelID) {
LabelID = MMI->MappedLabel(LabelID);
// Throw out move if the label is invalid.
if (!LabelID) continue;
if (MMI->isLabelDeleted(LabelID))
continue;
}
intptr_t LabelPtr = 0;

View file

@ -68,9 +68,6 @@ MCAsmInfo::MCAsmInfo() {
ExceptionsType = ExceptionHandling::None;
DwarfRequiresFrameSection = true;
DwarfUsesInlineInfoSection = false;
Is_EHSymbolPrivate = true;
GlobalEHDirective = 0;
SupportsWeakOmittedEHFrame = true;
DwarfSectionOffsetDirective = 0;
AsmTransCBE = 0;

View file

@ -40,19 +40,8 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HiddenVisibilityAttr = MCSA_PrivateExtern;
// Doesn't support protected visibility.
ProtectedVisibilityAttr = MCSA_Global;
HasDotTypeDotSizeDirective = false;
HasNoDeadStrip = true;
// Note: Even though darwin has the .lcomm directive, it is just a synonym for
// zerofill, so we prefer to use .zerofill.
// _foo.eh symbols are currently always exported so that the linker knows
// about them. This is not necessary on 10.6 and later, but it
// doesn't hurt anything.
// FIXME: I need to get this from Triple.
Is_EHSymbolPrivate = false;
GlobalEHDirective = "\t.globl\t";
SupportsWeakOmittedEHFrame = false;
}

View file

@ -440,29 +440,49 @@ public:
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
unsigned IsPCRel = 0;
unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned Type = RIT_Vanilla;
// See <reloc.h>.
const MCSymbol *A = Target.getSymA();
MCSymbolData *SD = SymbolMap.lookup(A);
uint32_t Value = SD->getFragment()->getAddress() + SD->getOffset();
MCSymbolData *A_SD = SymbolMap.lookup(A);
if (!A_SD->getFragment())
llvm_report_error("symbol '" + A->getName() +
"' can not be undefined in a subtraction expression");
uint32_t Value = A_SD->getFragment()->getAddress() + A_SD->getOffset();
uint32_t Value2 = 0;
if (const MCSymbol *B = Target.getSymB()) {
Type = RIT_LocalDifference;
MCSymbolData *B_SD = SymbolMap.lookup(B);
MCSymbolData *SD = SymbolMap.lookup(B);
Value2 = SD->getFragment()->getAddress() + SD->getOffset();
if (!B_SD->getFragment())
llvm_report_error("symbol '" + B->getName() +
"' can not be undefined in a subtraction expression");
// Select the appropriate difference relocation type.
//
// Note that there is no longer any semantic difference between these two
// relocation types from the linkers point of view, this is done solely
// for pedantic compatibility with 'as'.
Type = A_SD->isExternal() ? RIT_Difference : RIT_LocalDifference;
Value2 = B_SD->getFragment()->getAddress() + B_SD->getOffset();
}
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value - Value2 + Target.getConstant();
if (isFixupKindPCRel(Fixup.Kind)) {
if (IsPCRel)
Fixup.FixedValue -= Address;
IsPCRel = 1;
}
// If this fixup is a vanilla PC relative relocation for a local label, we
// don't need a relocation.
//
// FIXME: Implement proper atom support.
if (IsPCRel && Target.getSymA() && Target.getSymA()->isTemporary() &&
!Target.getSymB())
return;
MachRelocationEntry MRE;
MRE.Word0 = ((Address << 0) |
@ -473,14 +493,12 @@ public:
MRE.Word1 = Value;
Relocs.push_back(MRE);
if (Type == RIT_LocalDifference) {
Type = RIT_Pair;
if (Type == RIT_Difference || Type == RIT_LocalDifference) {
MachRelocationEntry MRE;
MRE.Word0 = ((0 << 0) |
(Type << 24) |
(RIT_Pair << 24) |
(Log2Size << 28) |
(0 << 30) |
(IsPCRel << 30) |
RF_Scattered);
MRE.Word1 = Value2;
Relocs.push_back(MRE);
@ -491,15 +509,21 @@ public:
MCAsmFixup &Fixup,
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
std::vector<MachRelocationEntry> &Relocs) {
unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind);
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
MCValue Target;
if (!Fixup.Value->EvaluateAsRelocatable(Target))
llvm_report_error("expected relocatable expression");
// If this is a difference or a local symbol plus an offset, then we need a
// scattered relocation entry.
// If this is a difference or a defined symbol plus an offset, then we need
// a scattered relocation entry.
uint32_t Offset = Target.getConstant();
if (IsPCRel)
Offset += 1 << Log2Size;
if (Target.getSymB() ||
(Target.getSymA() && !Target.getSymA()->isUndefined() &&
Target.getConstant()))
Offset))
return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
SymbolMap, Relocs);
@ -507,8 +531,6 @@ public:
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
uint32_t Value = 0;
unsigned Index = 0;
unsigned IsPCRel = 0;
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
unsigned IsExtern = 0;
unsigned Type = 0;
@ -545,11 +567,15 @@ public:
// The value which goes in the fixup is current value of the expression.
Fixup.FixedValue = Value + Target.getConstant();
if (isFixupKindPCRel(Fixup.Kind)) {
if (IsPCRel)
Fixup.FixedValue -= Address;
IsPCRel = 1;
}
// If this fixup is a vanilla PC relative relocation for a local label, we
// don't need a relocation.
//
// FIXME: Implement proper atom support.
if (IsPCRel && Target.getSymA() && Target.getSymA()->isTemporary())
return;
// struct relocation_info (8 bytes)
MachRelocationEntry MRE;
@ -1040,8 +1066,8 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
// Align the fragment offset; it is safe to adjust the offset freely since
// this is only in virtual sections.
uint64_t Aligned = RoundUpToAlignment(Address, ZFF.getAlignment());
F.setOffset(Aligned - SD.getAddress());
Address = RoundUpToAlignment(Address, ZFF.getAlignment());
F.setOffset(Address - SD.getAddress());
// FIXME: This is misnamed.
F.setFileSize(ZFF.getSize());
@ -1270,9 +1296,15 @@ void MCAssembler::Finish() {
if (!isVirtualSection(SD.getSection()))
continue;
// Align this section if necessary by adding padding bytes to the previous
// section.
if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment()))
Address += Pad;
SD.setAddress(Address);
LayoutSection(SD);
Address += SD.getSize();
}
DEBUG_WITH_TYPE("mc-dump", {
@ -1336,7 +1368,7 @@ void MCDataFragment::dump() {
OS << ",\n ";
OS << " Fixups:[";
for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
if (it != fixup_begin()) OS << ",\n ";
if (it != fixup_begin()) OS << ",\n ";
OS << *it;
}
OS << "]";
@ -1379,7 +1411,7 @@ void MCSectionData::dump() {
OS << "<MCSectionData";
OS << " Alignment:" << getAlignment() << " Address:" << Address
<< " Size:" << Size << " FileSize:" << FileSize
<< " Fragments:[";
<< " Fragments:[\n ";
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (it != begin()) OS << ",\n ";
it->dump();
@ -1407,7 +1439,7 @@ void MCAssembler::dump() {
raw_ostream &OS = llvm::errs();
OS << "<MCAssembler\n";
OS << " Sections:[";
OS << " Sections:[\n ";
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (it != begin()) OS << ",\n ";
it->dump();
@ -1416,7 +1448,7 @@ void MCAssembler::dump() {
OS << " Symbols:[";
for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
if (it != symbol_begin()) OS << ",\n ";
if (it != symbol_begin()) OS << ",\n ";
it->dump();
}
OS << "]>\n";

View file

@ -23,16 +23,8 @@ MCContext::~MCContext() {
// we don't need to free them here.
}
MCSymbol *MCContext::CreateSymbol(StringRef Name) {
assert(Name[0] != '\0' && "Normal symbols cannot be unnamed!");
// Create and bind the symbol, and ensure that names are unique.
MCSymbol *&Entry = Symbols[Name];
assert(!Entry && "Duplicate symbol definition!");
return Entry = new (*this) MCSymbol(Name, false);
}
MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
assert(!Name.empty() && "Normal symbols cannot be unnamed!");
MCSymbol *&Entry = Symbols[Name];
if (Entry) return Entry;
@ -46,17 +38,24 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
}
MCSymbol *MCContext::CreateTemporarySymbol(StringRef Name) {
MCSymbol *MCContext::GetOrCreateTemporarySymbol(StringRef Name) {
// If unnamed, just create a symbol.
if (Name.empty())
new (*this) MCSymbol("", true);
// Otherwise create as usual.
MCSymbol *&Entry = Symbols[Name];
assert(!Entry && "Duplicate symbol definition!");
if (Entry) return Entry;
return Entry = new (*this) MCSymbol(Name, true);
}
MCSymbol *MCContext::GetOrCreateTemporarySymbol(const Twine &Name) {
SmallString<128> NameSV;
Name.toVector(NameSV);
return GetOrCreateTemporarySymbol(NameSV.str());
}
MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
return Symbols.lookup(Name);
}

View file

@ -133,6 +133,11 @@ const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, MCContext &Ctx) {
return Create(Ctx.GetOrCreateSymbol(Name), Ctx);
}
const MCSymbolRefExpr *MCSymbolRefExpr::CreateTemp(StringRef Name,
MCContext &Ctx) {
return Create(Ctx.GetOrCreateTemporarySymbol(Name), Ctx);
}
void MCTargetExpr::Anchor() {}
/* *** */

View file

@ -29,7 +29,11 @@ namespace {
CurSection = Section;
}
virtual void EmitLabel(MCSymbol *Symbol) {}
virtual void EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
assert(CurSection && "Cannot emit before setting section!");
Symbol->setSection(*CurSection);
}
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}

View file

@ -240,14 +240,10 @@ bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
if (MCSymbol *S = Ctx.LookupSymbol(Name))
return S;
// If the label starts with L it is an assembler temporary label.
if (Name.startswith("L"))
return Ctx.CreateTemporarySymbol(Name);
return Ctx.CreateSymbol(Name);
return Ctx.GetOrCreateTemporarySymbol(Name);
return Ctx.GetOrCreateSymbol(Name);
}
/// ParsePrimaryExpr - Parse a primary expression and return it.

View file

@ -31,6 +31,11 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
}
void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
unsigned AddrSpace) {
EmitValue(MCSymbolRefExpr::Create(Sym, getContext()), Size, AddrSpace);
}
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,

View file

@ -3366,7 +3366,7 @@ namespace {
void APFloat::toString(SmallVectorImpl<char> &Str,
unsigned FormatPrecision,
unsigned FormatMaxPadding) {
unsigned FormatMaxPadding) const {
switch (category) {
case fcInfinity:
if (isNegative())

View file

@ -332,7 +332,7 @@ bool isJumpTableBranchOpcode(int Opc) {
static inline
bool isIndirectBranchOpcode(int Opc) {
return Opc == ARM::BRIND || Opc == ARM::tBRIND;
return Opc == ARM::BRIND || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
}
/// getInstrPredicate - If instruction is predicated, returns its predicate

View file

@ -40,7 +40,7 @@
#include "llvm/Support/CommandLine.h"
using namespace llvm;
static cl::opt<bool>
cl::opt<bool>
ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true),
cl::desc("Reuse repeated frame index values"));
@ -1153,7 +1153,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
unsigned
ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value,
int SPAdj, FrameIndexValue *Value,
RegScavenger *RS) const {
unsigned i = 0;
MachineInstr &MI = *II;
@ -1205,7 +1205,10 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
else {
ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass);
if (Value) *Value = Offset;
if (Value) {
Value->first = FrameReg; // use the frame register as a kind indicator
Value->second = Offset;
}
if (!AFI->isThumbFunction())
emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
Offset, Pred, PredReg, TII);

View file

@ -145,7 +145,7 @@ public:
MachineBasicBlock::iterator I) const;
virtual unsigned eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value = NULL,
int SPAdj, FrameIndexValue *Value = NULL,
RegScavenger *RS = NULL) const;
virtual void emitPrologue(MachineFunction &MF) const;

View file

@ -1138,7 +1138,7 @@ void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
if (TID.Opcode == ARM::BX_RET)
if (TID.Opcode == ARM::BX_RET || TID.Opcode == ARM::MOVPCLR)
// The return register is LR.
Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR);
else

View file

@ -37,9 +37,9 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
@ -130,7 +130,8 @@ void ARMTargetLowering::addQRTypeForNEON(EVT VT) {
static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) {
if (TM.getSubtarget<ARMSubtarget>().isTargetDarwin())
return new TargetLoweringObjectFileMachO();
return new ARMMachOTargetObjectFile();
return new ARMElfTargetObjectFile();
}

View file

@ -21,7 +21,7 @@ def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
def SDT_ARMCMov : SDTypeProfile<1, 3,
[SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
@ -113,6 +113,8 @@ def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
//===----------------------------------------------------------------------===//
// ARM Instruction Predicate Definitions.
//
def HasV4T : Predicate<"Subtarget->hasV4TOps()">;
def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
@ -851,24 +853,50 @@ def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
// Control Flow Instructions.
//
let isReturn = 1, isTerminator = 1, isBarrier = 1 in
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
// ARMV4T and above
def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br,
"bx", "\tlr", [(ARMretflag)]> {
let Inst{3-0} = 0b1110;
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
"bx", "\tlr", [(ARMretflag)]>,
Requires<[IsARM, HasV4T]> {
let Inst{3-0} = 0b1110;
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
}
// ARMV4 only
def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br,
"mov", "\tpc, lr", [(ARMretflag)]>,
Requires<[IsARM, NoV4T]> {
let Inst{11-0} = 0b000000001110;
let Inst{15-12} = 0b1111;
let Inst{19-16} = 0b0000;
let Inst{27-20} = 0b00011010;
}
}
// Indirect branches
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
// ARMV4T and above
def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst",
[(brind GPR:$dst)]> {
[(brind GPR:$dst)]>,
Requires<[IsARM, HasV4T]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
let Inst{31-28} = 0b1110;
}
// ARMV4 only
def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst",
[(brind GPR:$dst)]>,
Requires<[IsARM, NoV4T]> {
let Inst{11-4} = 0b00000000;
let Inst{15-12} = 0b1111;
let Inst{19-16} = 0b0000;
let Inst{27-20} = 0b00011010;
let Inst{31-28} = 0b1110;
}
}
// FIXME: remove when we have a way to marking a MI with these properties.
@ -913,11 +941,22 @@ let isCall = 1,
def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, IsNotDarwin]> {
Requires<[IsARM, HasV4T, IsNotDarwin]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
}
// ARMv4
def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, NoV4T, IsNotDarwin]> {
let Inst{11-4} = 0b00000000;
let Inst{15-12} = 0b1111;
let Inst{19-16} = 0b0000;
let Inst{27-20} = 0b00011010;
}
}
// On Darwin R9 is call-clobbered.
@ -950,11 +989,23 @@ let isCall = 1,
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink tGPR:$func)]>, Requires<[IsARM, IsDarwin]> {
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, HasV4T, IsDarwin]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;
}
// ARMv4
def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, NoV4T, IsDarwin]> {
let Inst{11-4} = 0b00000000;
let Inst{15-12} = 0b1111;
let Inst{19-16} = 0b0000;
let Inst{27-20} = 0b00011010;
}
}
let isBranch = 1, isTerminator = 1 in {
@ -2793,29 +2844,29 @@ def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
let Inst{7-4} = 0b0000;
}
// FIXME: mask is ignored for the time being.
def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
def MSR : ABI<0b0001, (outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr",
"\tcpsr${mask:msr}, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0010;
let Inst{7-4} = 0b0000;
}
// FIXME: mask is ignored for the time being.
def MSRi : ABI<0b0011,(outs),(ins so_imm:$a), NoItinerary, "msr", "\tcpsr, $a",
def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, i32imm:$mask), NoItinerary,"msr",
"\tcpsr${mask:msr}, $a",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0010;
let Inst{7-4} = 0b0000;
}
// FIXME: mask is ignored for the time being.
def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"msr","\tspsr, $src",
def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, i32imm:$mask),NoItinerary,"msr",
"\tspsr${mask:msr}, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0110;
let Inst{7-4} = 0b0000;
}
// FIXME: mask is ignored for the time being.
def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a),NoItinerary,"msr","\tspsr, $a",
def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a, i32imm:$mask),NoItinerary,"msr",
"\tspsr${mask:msr}, $a",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0110;
let Inst{7-4} = 0b0000;

View file

@ -2707,21 +2707,21 @@ def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$dst),
}
def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane),
(v16i8 (INSERT_SUBREG QPR:$src1,
(VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1,
(v8i8 (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1,
(DSubReg_i8_reg imm:$lane))),
GPR:$src2, (SubReg_i8_lane imm:$lane)),
GPR:$src2, (SubReg_i8_lane imm:$lane))),
(DSubReg_i8_reg imm:$lane)))>;
def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane),
(v8i16 (INSERT_SUBREG QPR:$src1,
(VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1,
(v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1,
(DSubReg_i16_reg imm:$lane))),
GPR:$src2, (SubReg_i16_lane imm:$lane)),
GPR:$src2, (SubReg_i16_lane imm:$lane))),
(DSubReg_i16_reg imm:$lane)))>;
def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane),
(v4i32 (INSERT_SUBREG QPR:$src1,
(VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1,
(v2i32 (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1,
(DSubReg_i32_reg imm:$lane))),
GPR:$src2, (SubReg_i32_lane imm:$lane)),
GPR:$src2, (SubReg_i32_lane imm:$lane))),
(DSubReg_i32_reg imm:$lane)))>;
def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)),
@ -3093,16 +3093,17 @@ def VTBX4
class N2VSPat<SDNode OpNode, ValueType ResTy, ValueType OpTy, NeonI Inst>
: NEONFPPat<(ResTy (OpNode SPR:$a)),
(EXTRACT_SUBREG (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)),
SPR:$a, arm_ssubreg_0)),
(EXTRACT_SUBREG (OpTy (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)),
SPR:$a, arm_ssubreg_0))),
arm_ssubreg_0)>;
class N3VSPat<SDNode OpNode, NeonI Inst>
: NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)),
(EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
SPR:$a, arm_ssubreg_0),
(INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
SPR:$b, arm_ssubreg_0)),
(EXTRACT_SUBREG (v2f32
(Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
SPR:$a, arm_ssubreg_0),
(INSERT_SUBREG (v2f32 (IMPLICIT_DEF)),
SPR:$b, arm_ssubreg_0))),
arm_ssubreg_0)>;
class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst>

View file

@ -331,9 +331,9 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
let Inst{15} = 0;
}
// 12-bit imm
def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
!strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
[(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
def ri12 : T2I<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
!strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
[(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> {
let Inst{31-27} = 0b11110;
let Inst{25} = 1;
let Inst{24} = 0;
@ -2637,9 +2637,9 @@ def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
let Inst{12} = 0;
}
// FIXME: mask is ignored for the time being.
// Rn = Inst{19-16}
def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
def t2MSR : T2I<(outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr",
"\tcpsr${mask:msr}, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
@ -2649,9 +2649,9 @@ def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src",
let Inst{12} = 0;
}
// FIXME: mask is ignored for the time being.
// Rn = Inst{19-16}
def t2MSRsys : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tspsr, $src",
def t2MSRsys : T2I<(outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr",
"\tspsr${mask:msr}, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;

View file

@ -57,7 +57,7 @@ def vfp_f64imm : Operand<f64>,
let canFoldAsLoad = 1, isReMaterializable = 1 in {
def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
IIC_fpLoad64, "vldr", ".64\t$dst, $addr",
[(set DPR:$dst, (load addrmode5:$addr))]>;
[(set DPR:$dst, (f64 (load addrmode5:$addr)))]>;
def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
IIC_fpLoad32, "vldr", ".32\t$dst, $addr",
@ -66,7 +66,7 @@ def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
IIC_fpStore64, "vstr", ".64\t$src, $addr",
[(store DPR:$src, addrmode5:$addr)]>;
[(store (f64 DPR:$src), addrmode5:$addr)]>;
def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
IIC_fpStore32, "vstr", ".32\t$src, $addr",
@ -116,7 +116,7 @@ def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
def VADDD : ADbI<0b11100, 0b11, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpALU64, "vadd", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>;
[(set DPR:$dst, (fadd DPR:$a, (f64 DPR:$b)))]>;
def VADDS : ASbIn<0b11100, 0b11, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpALU32, "vadd", ".f32\t$dst, $a, $b",
@ -126,7 +126,7 @@ def VADDS : ASbIn<0b11100, 0b11, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
let Defs = [FPSCR] in {
def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0, (outs), (ins DPR:$a, DPR:$b),
IIC_fpCMP64, "vcmpe", ".f64\t$a, $b",
[(arm_cmpfp DPR:$a, DPR:$b)]>;
[(arm_cmpfp DPR:$a, (f64 DPR:$b))]>;
def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0, (outs), (ins DPR:$a, DPR:$b),
IIC_fpCMP64, "vcmp", ".f64\t$a, $b",
@ -143,7 +143,7 @@ def VCMPS : ASuI<0b11101, 0b11, 0b0100, 0b01, 0, (outs), (ins SPR:$a, SPR:$b),
def VDIVD : ADbI<0b11101, 0b00, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpDIV64, "vdiv", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>;
[(set DPR:$dst, (fdiv DPR:$a, (f64 DPR:$b)))]>;
def VDIVS : ASbI<0b11101, 0b00, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpDIV32, "vdiv", ".f32\t$dst, $a, $b",
@ -151,7 +151,7 @@ def VDIVS : ASbI<0b11101, 0b00, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
def VMULD : ADbI<0b11100, 0b10, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpMUL64, "vmul", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>;
[(set DPR:$dst, (fmul DPR:$a, (f64 DPR:$b)))]>;
def VMULS : ASbIn<0b11100, 0b10, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpMUL32, "vmul", ".f32\t$dst, $a, $b",
@ -159,14 +159,14 @@ def VMULS : ASbIn<0b11100, 0b10, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
def VNMULD : ADbI<0b11100, 0b10, 1, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpMUL64, "vnmul", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]>;
[(set DPR:$dst, (fneg (fmul DPR:$a, (f64 DPR:$b))))]>;
def VNMULS : ASbI<0b11100, 0b10, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpMUL32, "vnmul", ".f32\t$dst, $a, $b",
[(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]>;
// Match reassociated forms only if not sign dependent rounding.
def : Pat<(fmul (fneg DPR:$a), DPR:$b),
def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
(VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
def : Pat<(fmul (fneg SPR:$a), SPR:$b),
(VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
@ -174,7 +174,7 @@ def : Pat<(fmul (fneg SPR:$a), SPR:$b),
def VSUBD : ADbI<0b11100, 0b11, 1, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
IIC_fpALU64, "vsub", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fsub DPR:$a, DPR:$b))]>;
[(set DPR:$dst, (fsub DPR:$a, (f64 DPR:$b)))]>;
def VSUBS : ASbIn<0b11100, 0b11, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
IIC_fpALU32, "vsub", ".f32\t$dst, $a, $b",
@ -186,7 +186,7 @@ def VSUBS : ASbIn<0b11100, 0b11, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
def VABSD : ADuI<0b11101, 0b11, 0b0000, 0b11, 0, (outs DPR:$dst), (ins DPR:$a),
IIC_fpUNA64, "vabs", ".f64\t$dst, $a",
[(set DPR:$dst, (fabs DPR:$a))]>;
[(set DPR:$dst, (fabs (f64 DPR:$a)))]>;
def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,(outs SPR:$dst), (ins SPR:$a),
IIC_fpUNA32, "vabs", ".f32\t$dst, $a",
@ -195,7 +195,7 @@ def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,(outs SPR:$dst), (ins SPR:$a),
let Defs = [FPSCR] in {
def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0, (outs), (ins DPR:$a),
IIC_fpCMP64, "vcmpe", ".f64\t$a, #0",
[(arm_cmpfp0 DPR:$a)]>;
[(arm_cmpfp0 (f64 DPR:$a))]>;
def VCMPZD : ADuI<0b11101, 0b11, 0b0101, 0b01, 0, (outs), (ins DPR:$a),
IIC_fpCMP64, "vcmp", ".f64\t$a, #0",
@ -253,7 +253,7 @@ def VMOVS: ASuI<0b11101, 0b11, 0b0000, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
def VNEGD : ADuI<0b11101, 0b11, 0b0001, 0b01, 0, (outs DPR:$dst), (ins DPR:$a),
IIC_fpUNA64, "vneg", ".f64\t$dst, $a",
[(set DPR:$dst, (fneg DPR:$a))]>;
[(set DPR:$dst, (fneg (f64 DPR:$a)))]>;
def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,(outs SPR:$dst), (ins SPR:$a),
IIC_fpUNA32, "vneg", ".f32\t$dst, $a",
@ -261,7 +261,7 @@ def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,(outs SPR:$dst), (ins SPR:$a),
def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0, (outs DPR:$dst), (ins DPR:$a),
IIC_fpSQRT64, "vsqrt", ".f64\t$dst, $a",
[(set DPR:$dst, (fsqrt DPR:$a))]>;
[(set DPR:$dst, (fsqrt (f64 DPR:$a)))]>;
def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
IIC_fpSQRT32, "vsqrt", ".f32\t$dst, $a",
@ -325,7 +325,7 @@ def VMOVSRR : AVConv5I<0b11000100, 0b1010,
def VSITOD : AVConv1I<0b11101, 0b11, 0b1000, 0b1011,
(outs DPR:$dst), (ins SPR:$a),
IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a",
[(set DPR:$dst, (arm_sitof SPR:$a))]> {
[(set DPR:$dst, (f64 (arm_sitof SPR:$a)))]> {
let Inst{7} = 1; // s32
}
@ -339,7 +339,7 @@ def VSITOS : AVConv1In<0b11101, 0b11, 0b1000, 0b1010,
def VUITOD : AVConv1I<0b11101, 0b11, 0b1000, 0b1011,
(outs DPR:$dst), (ins SPR:$a),
IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a",
[(set DPR:$dst, (arm_uitof SPR:$a))]> {
[(set DPR:$dst, (f64 (arm_uitof SPR:$a)))]> {
let Inst{7} = 0; // u32
}
@ -356,7 +356,7 @@ def VUITOS : AVConv1In<0b11101, 0b11, 0b1000, 0b1010,
def VTOSIZD : AVConv1I<0b11101, 0b11, 0b1101, 0b1011,
(outs SPR:$dst), (ins DPR:$a),
IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a",
[(set SPR:$dst, (arm_ftosi DPR:$a))]> {
[(set SPR:$dst, (arm_ftosi (f64 DPR:$a)))]> {
let Inst{7} = 1; // Z bit
}
@ -370,7 +370,7 @@ def VTOSIZS : AVConv1In<0b11101, 0b11, 0b1101, 0b1010,
def VTOUIZD : AVConv1I<0b11101, 0b11, 0b1100, 0b1011,
(outs SPR:$dst), (ins DPR:$a),
IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a",
[(set SPR:$dst, (arm_ftoui DPR:$a))]> {
[(set SPR:$dst, (arm_ftoui (f64 DPR:$a)))]> {
let Inst{7} = 1; // Z bit
}
@ -514,7 +514,8 @@ def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1,
def VMLAD : ADbI<0b11100, 0b00, 0, 0,
(outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vmla", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
[(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b),
(f64 DPR:$dstin)))]>,
RegConstraint<"$dstin = $dst">;
def VMLAS : ASbIn<0b11100, 0b00, 0, 0,
@ -526,7 +527,8 @@ def VMLAS : ASbIn<0b11100, 0b00, 0, 0,
def VNMLSD : ADbI<0b11100, 0b01, 0, 0,
(outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vnmls", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
[(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b),
(f64 DPR:$dstin)))]>,
RegConstraint<"$dstin = $dst">;
def VNMLSS : ASbI<0b11100, 0b01, 0, 0,
@ -538,7 +540,8 @@ def VNMLSS : ASbI<0b11100, 0b01, 0, 0,
def VMLSD : ADbI<0b11100, 0b00, 1, 0,
(outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vmls", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
[(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)),
(f64 DPR:$dstin)))]>,
RegConstraint<"$dstin = $dst">;
def VMLSS : ASbIn<0b11100, 0b00, 1, 0,
@ -547,7 +550,7 @@ def VMLSS : ASbIn<0b11100, 0b00, 1, 0,
[(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
RegConstraint<"$dstin = $dst">;
def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, DPR:$b)),
def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))),
(VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
(VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
@ -555,7 +558,8 @@ def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
def VNMLAD : ADbI<0b11100, 0b01, 1, 0,
(outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
IIC_fpMAC64, "vnmla", ".f64\t$dst, $a, $b",
[(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
[(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)),
(f64 DPR:$dstin)))]>,
RegConstraint<"$dstin = $dst">;
def VNMLAS : ASbI<0b11100, 0b01, 1, 0,

View file

@ -48,7 +48,6 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin() {
// Exceptions handling
ExceptionsType = ExceptionHandling::SjLj;
AbsoluteEHSectionOffsets = false;
}
ARMELFMCAsmInfo::ARMELFMCAsmInfo() {

View file

@ -33,7 +33,7 @@ UseMOVT("arm-use-movt",
ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
bool isT)
: ARMArchVersion(V4T)
: ARMArchVersion(V4)
, ARMFPUType(None)
, UseNEONForSinglePrecisionFP(UseNEONFP)
, IsThumb(isT)
@ -54,6 +54,11 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
// Parse features string.
CPUString = ParseSubtargetFeatures(FS, CPUString);
// When no arch is specified either by CPU or by attributes, make the default
// ARMv4T.
if (CPUString == "generic" && (FS.empty() || FS == "generic"))
ARMArchVersion = V4T;
// Set the boolean corresponding to the current target triple, or the default
// if one cannot be determined, to true.
unsigned Len = TT.length();
@ -68,25 +73,28 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
}
if (Idx) {
unsigned SubVer = TT[Idx];
if (SubVer > '4' && SubVer <= '9') {
if (SubVer >= '7') {
ARMArchVersion = V7A;
} else if (SubVer == '6') {
ARMArchVersion = V6;
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
ARMArchVersion = V6T2;
} else if (SubVer == '5') {
ARMArchVersion = V5T;
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
ARMArchVersion = V5TE;
}
if (ARMArchVersion >= V6T2)
ThumbMode = Thumb2;
if (SubVer >= '7' && SubVer <= '9') {
ARMArchVersion = V7A;
} else if (SubVer == '6') {
ARMArchVersion = V6;
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
ARMArchVersion = V6T2;
} else if (SubVer == '5') {
ARMArchVersion = V5T;
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
ARMArchVersion = V5TE;
} else if (SubVer == '4') {
if (Len >= Idx+2 && TT[Idx+1] == 't')
ARMArchVersion = V4T;
else
ARMArchVersion = V4;
}
}
// Thumb2 implies at least V6T2.
if (ARMArchVersion < V6T2 && ThumbMode >= Thumb2)
if (ARMArchVersion >= V6T2)
ThumbMode = Thumb2;
else if (ThumbMode >= Thumb2)
ARMArchVersion = V6T2;
if (Len >= 10) {

View file

@ -26,7 +26,7 @@ class GlobalValue;
class ARMSubtarget : public TargetSubtarget {
protected:
enum ARMArchEnum {
V4T, V5T, V5TE, V6, V6T2, V7A
V4, V4T, V5T, V5TE, V6, V6T2, V7A
};
enum ARMFPEnum {
@ -38,7 +38,7 @@ protected:
Thumb2
};
/// ARMArchVersion - ARM architecture version: V4T (base), V5T, V5TE,
/// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE,
/// V6, V6T2, V7A.
ARMArchEnum ARMArchVersion;

View file

@ -0,0 +1,54 @@
//===-- llvm/Target/ARMTargetObjectFile.cpp - ARM Object Info Impl --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ARMTargetObjectFile.h"
#include "ARMSubtarget.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
using namespace dwarf;
//===----------------------------------------------------------------------===//
// ELF Target
//===----------------------------------------------------------------------===//
void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) {
StaticCtorSection =
getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
StaticDtorSection =
getELFSection(".fini_array", MCSectionELF::SHT_FINI_ARRAY,
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
}
}
//===----------------------------------------------------------------------===//
// Mach-O Target
//===----------------------------------------------------------------------===//
void ARMMachOTargetObjectFile::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFileMachO::Initialize(Ctx, TM);
// Exception Handling.
LSDASection = getMachOSection("__TEXT", "__gcc_except_tab", 0,
SectionKind::getReadOnlyWithRel());
}
unsigned ARMMachOTargetObjectFile::getTTypeEncoding() const {
return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
}

View file

@ -11,29 +11,31 @@
#define LLVM_TARGET_ARM_TARGETOBJECTFILE_H
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCSectionELF.h"
namespace llvm {
class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF {
public:
ARMElfTargetObjectFile() : TargetLoweringObjectFileELF() {}
class MCContext;
class TargetMachine;
void Initialize(MCContext &Ctx, const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF {
public:
ARMElfTargetObjectFile() : TargetLoweringObjectFileELF() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
};
// FIXME: This subclass isn't 100% necessary. It will become obsolete once we
// can place all LSDAs into the TEXT section. See
// <rdar://problem/6804645>.
class ARMMachOTargetObjectFile : public TargetLoweringObjectFileMachO {
public:
ARMMachOTargetObjectFile() : TargetLoweringObjectFileMachO() {}
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual unsigned getTTypeEncoding() const;
};
if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) {
StaticCtorSection =
getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
StaticDtorSection =
getELFSection(".fini_array", MCSectionELF::SHT_FINI_ARRAY,
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
}
}
};
} // end namespace llvm
#endif

View file

@ -33,6 +33,7 @@
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
@ -848,7 +849,7 @@ GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
<< getFunctionNumber() << '_' << uid << '_' << uid2
<< "_set_" << MBB->getNumber();
return OutContext.GetOrCreateSymbol(Name.str());
return OutContext.GetOrCreateTemporarySymbol(Name.str());
}
MCSymbol *ARMAsmPrinter::
@ -856,7 +857,7 @@ GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
SmallString<60> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
<< getFunctionNumber() << '_' << uid << '_' << uid2;
return OutContext.GetOrCreateSymbol(Name.str());
return OutContext.GetOrCreateTemporarySymbol(Name.str());
}
void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
@ -1128,17 +1129,40 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
EmitAlignment(2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
O << *Stubs[i].first << ":\n\t.indirect_symbol ";
O << *Stubs[i].second << "\n\t.long\t0\n";
// L_foo$stub:
OutStreamer.EmitLabel(Stubs[i].first);
// .indirect_symbol _foo
MCSymbol *MCSym = Stubs[i].second;
OutStreamer.EmitSymbolAttribute(MCSym, MCSA_IndirectSymbol);
if (MCSym->isUndefined())
// External to current translation unit.
OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
else
// Internal to current translation unit.
OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym, OutContext),
4/*size*/, 0/*addrspace*/);
}
Stubs.clear();
OutStreamer.AddBlankLine();
}
Stubs = MMIMacho.GetHiddenGVStubList();
if (!Stubs.empty()) {
OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
EmitAlignment(2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i)
O << *Stubs[i].first << ":\n\t.long " << *Stubs[i].second << "\n";
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
// L_foo$stub:
OutStreamer.EmitLabel(Stubs[i].first);
// .long _foo
OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second,
OutContext),
4/*size*/, 0/*addrspace*/);
}
Stubs.clear();
OutStreamer.AddBlankLine();
}
// Funny Darwin hack: This flag tells the linker that no global symbols
@ -1168,7 +1192,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
// FIXME: MOVE TO SHARED PLACE.
unsigned Id = (unsigned)MI->getOperand(2).getImm();
const char *Prefix = MAI->getPrivateGlobalPrefix();
MCSymbol *Label =OutContext.GetOrCreateSymbol(Twine(Prefix)
MCSymbol *Label =OutContext.GetOrCreateTemporarySymbol(Twine(Prefix)
+ "PC" + Twine(getFunctionNumber()) + "_" + Twine(Id));
OutStreamer.EmitLabel(Label);

View file

@ -74,7 +74,7 @@ GetJumpTableSymbol(const MachineOperand &MO) const {
#endif
// Create a symbol for the name.
return Ctx.GetOrCreateSymbol(Name.str());
return Ctx.GetOrCreateTemporarySymbol(Name.str());
}
MCSymbol *ARMMCInstLower::
@ -90,7 +90,7 @@ GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
#endif
// Create a symbol for the name.
return Ctx.GetOrCreateSymbol(Name.str());
return Ctx.GetOrCreateTemporarySymbol(Name.str());
}
MCOperand ARMMCInstLower::

View file

@ -27,6 +27,7 @@ add_llvm_target(ARMCodeGen
ARMRegisterInfo.cpp
ARMSubtarget.cpp
ARMTargetMachine.cpp
ARMTargetObjectFile.cpp
NEONMoveFix.cpp
NEONPreAllocPass.cpp
Thumb1InstrInfo.cpp

View file

@ -33,10 +33,13 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
extern cl::opt<bool> ReuseFrameIndexVals;
Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii,
const ARMSubtarget &sti)
: ARMBaseRegisterInfo(tii, sti) {
@ -426,7 +429,7 @@ Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
unsigned
Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value,
int SPAdj, FrameIndexValue *Value,
RegScavenger *RS) const{
unsigned VReg = 0;
unsigned i = 0;
@ -638,8 +641,10 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
} else if (Desc.mayStore()) {
VReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass);
assert (Value && "Frame index virtual allocated, but Value arg is NULL!");
*Value = Offset;
bool UseRR = false;
bool TrackVReg = true;
Value->first = FrameReg; // use the frame register as a kind indicator
Value->second = Offset;
if (Opcode == ARM::tSpill) {
if (FrameReg == ARM::SP)
@ -648,6 +653,7 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
else {
emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
UseRR = true;
TrackVReg = false;
}
} else
emitThumbRegPlusImmediate(MBB, II, VReg, FrameReg, Offset, TII,
@ -658,6 +664,8 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
else // tSTR has an extra register operand.
MI.addOperand(MachineOperand::CreateReg(0, false));
if (!ReuseFrameIndexVals || !TrackVReg)
VReg = 0;
} else
assert(false && "Unexpected opcode!");

View file

@ -59,7 +59,7 @@ public:
const TargetRegisterClass *RC,
unsigned Reg) const;
unsigned eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value = NULL,
int SPAdj, FrameIndexValue *Value = NULL,
RegScavenger *RS = NULL) const;
void emitPrologue(MachineFunction &MF) const;

View file

@ -164,6 +164,7 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
continue;
}
bool HasCCOut = true;
if (BaseReg == ARM::SP) {
// sub sp, sp, #imm7
if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
@ -195,6 +196,7 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
NumBytes = 0;
} else if (ThisVal < 4096) {
Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
HasCCOut = false;
NumBytes = 0;
} else {
// FIXME: Move this to ARMAddressingModes.h?
@ -207,9 +209,12 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
}
// Build the new ADD / SUB.
AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
.addReg(BaseReg, RegState::Kill)
.addImm(ThisVal)));
MachineInstrBuilder MIB =
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
.addReg(BaseReg, RegState::Kill)
.addImm(ThisVal));
if (HasCCOut)
AddDefaultCC(MIB);
BaseReg = DestReg;
}
@ -328,7 +333,6 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
Offset += MI.getOperand(FrameRegIdx+1).getImm();
bool isSP = FrameReg == ARM::SP;
unsigned PredReg;
if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
// Turn it into a move.
@ -342,6 +346,9 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
return true;
}
bool isSP = FrameReg == ARM::SP;
bool HasCCOut = Opcode != ARM::t2ADDri12;
if (Offset < 0) {
Offset = -Offset;
isSub = true;
@ -354,17 +361,24 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
if (ARM_AM::getT2SOImmVal(Offset) != -1) {
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
// Add cc_out operand if the original instruction did not have one.
if (!HasCCOut)
MI.addOperand(MachineOperand::CreateReg(0, false));
Offset = 0;
return true;
}
// Another common case: imm12.
if (Offset < 4096) {
if (Offset < 4096 &&
(!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
unsigned NewOpc = isSP
? (isSub ? ARM::t2SUBrSPi12 : ARM::t2ADDrSPi12)
: (isSub ? ARM::t2SUBri12 : ARM::t2ADDri12);
MI.setDesc(TII.get(NewOpc));
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
// Remove the cc_out operand.
if (HasCCOut)
MI.RemoveOperand(MI.getNumOperands()-1);
Offset = 0;
return true;
}
@ -380,6 +394,10 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
"Bit extraction didn't work?");
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
// Add cc_out operand if the original instruction did not have one.
if (!HasCCOut)
MI.addOperand(MachineOperand::CreateReg(0, false));
} else {
// AddrMode4 and AddrMode6 cannot handle any offset.

View file

@ -892,7 +892,7 @@ def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP),
(COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>;
def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP),
(COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>;
def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
(COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>;
def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP),
(COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>;

View file

@ -153,7 +153,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
unsigned
AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value,
int SPAdj, FrameIndexValue *Value,
RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected");

View file

@ -42,7 +42,7 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo {
MachineBasicBlock::iterator I) const;
unsigned eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value = NULL,
int SPAdj, FrameIndexValue *Value = NULL,
RegScavenger *RS = NULL) const;
//void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;

View file

@ -221,7 +221,7 @@ static unsigned findScratchRegister(MachineBasicBlock::iterator II,
unsigned
BlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value,
int SPAdj, FrameIndexValue *Value,
RegScavenger *RS) const {
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();

View file

@ -65,7 +65,7 @@ namespace llvm {
MachineBasicBlock::iterator I) const;
unsigned eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, int *Value = NULL,
int SPAdj, FrameIndexValue *Value = NULL,
RegScavenger *RS = NULL) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,

View file

@ -205,6 +205,7 @@ def CellSDKnand:
// Shift/rotate intrinsics:
//===----------------------------------------------------------------------===//
/* FIXME: These have (currently unenforced) type conflicts. */
def CellSDKshli:
Pat<(int_spu_si_shli (v4i32 VECREG:$rA), uimm7:$val),
(SHLIv4i32 VECREG:$rA, uimm7:$val)>;

View file

@ -2370,7 +2370,7 @@ class ROTHInst<dag OOL, dag IOL, list<dag> pattern>:
class ROTHVecInst<ValueType vectype>:
ROTHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
[(set (vectype VECREG:$rT),
(SPUvec_rotl VECREG:$rA, VECREG:$rB))]>;
(SPUvec_rotl VECREG:$rA, (v8i16 VECREG:$rB)))]>;
class ROTHRegInst<RegisterClass rclass>:
ROTHInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB),

View file

@ -45,9 +45,9 @@ def : Pat<(mul (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)),
def MPYv4i32:
Pat<(mul (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)),
(Av4i32
(Av4i32 (MPYHv4i32 VECREG:$rA, VECREG:$rB),
(MPYHv4i32 VECREG:$rB, VECREG:$rA)),
(MPYUv4i32 VECREG:$rA, VECREG:$rB))>;
(v4i32 (Av4i32 (v4i32 (MPYHv4i32 VECREG:$rA, VECREG:$rB)),
(v4i32 (MPYHv4i32 VECREG:$rB, VECREG:$rA)))),
(v4i32 (MPYUv4i32 VECREG:$rA, VECREG:$rB)))>;
def MPYi32:
Pat<(mul R32C:$rA, R32C:$rB),

Some files were not shown because too many files have changed in this diff Show more