Update LLVM to 93512.
This commit is contained in:
parent
a16c51cee9
commit
3fba7d16b4
@ -296,6 +296,7 @@ add_subdirectory(lib/Bitcode/Reader)
|
||||
add_subdirectory(lib/Bitcode/Writer)
|
||||
add_subdirectory(lib/Transforms/Utils)
|
||||
add_subdirectory(lib/Transforms/Instrumentation)
|
||||
add_subdirectory(lib/Transforms/InstCombine)
|
||||
add_subdirectory(lib/Transforms/Scalar)
|
||||
add_subdirectory(lib/Transforms/IPO)
|
||||
add_subdirectory(lib/Transforms/Hello)
|
||||
|
@ -4,7 +4,7 @@ LLVM Release License
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign.
|
||||
Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
@ -512,7 +512,7 @@ case "$enableval" in
|
||||
PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
SystemZ) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
s390x) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
*) AC_MSG_ERROR([Can not set target to build]) ;;
|
||||
esac ;;
|
||||
|
@ -7,9 +7,9 @@ set(MSVC_LIB_DEPS_LLVMAlphaCodeGen LLVMAlphaInfo LLVMCodeGen LLVMCore LLVMMC LLV
|
||||
set(MSVC_LIB_DEPS_LLVMAlphaInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMAsmPrinter LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMBlackfinAsmPrinter LLVMAsmPrinter LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
|
||||
@ -21,15 +21,16 @@ set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC
|
||||
set(MSVC_LIB_DEPS_LLVMCellSPUInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMCodeGen LLVMAnalysis LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils)
|
||||
set(MSVC_LIB_DEPS_LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMScalarOpts LLVMSupport LLVMSystem LLVMTransformUtils)
|
||||
set(MSVC_LIB_DEPS_LLVMInstCombine LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils)
|
||||
set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTransformUtils)
|
||||
set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMLinker LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMMC LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMMSIL LLVMAnalysis LLVMCodeGen LLVMCore LLVMMSILInfo LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils LLVMipa)
|
||||
set(MSVC_LIB_DEPS_LLVMMSIL LLVMAnalysis LLVMCodeGen LLVMCore LLVMMSILInfo LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils LLVMipa)
|
||||
set(MSVC_LIB_DEPS_LLVMMSILInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMSP430Info LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMMSP430CodeGen LLVMCodeGen LLVMCore LLVMMC LLVMMSP430Info LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget)
|
||||
@ -37,13 +38,13 @@ set(MSVC_LIB_DEPS_LLVMMSP430Info LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMMipsAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMipsCodeGen LLVMMipsInfo LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMMipsCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMMipsInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMMipsInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMPIC16 LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMPIC16Info LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMPIC16AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPIC16 LLVMPIC16Info LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMPIC16 LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMPIC16Info LLVMSelectionDAG LLVMSupport LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMPIC16AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPIC16 LLVMPIC16Info LLVMSupport LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMPIC16Info LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCInfo LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMPowerPCCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils)
|
||||
set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMInstCombine LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils)
|
||||
set(MSVC_LIB_DEPS_LLVMSelectionDAG LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMSparcAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSparcInfo LLVMSupport LLVMSystem LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMSparcCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSparcInfo LLVMSupport LLVMSystem LLVMTarget)
|
||||
@ -53,14 +54,14 @@ set(MSVC_LIB_DEPS_LLVMSystem )
|
||||
set(MSVC_LIB_DEPS_LLVMSystemZAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMSystemZInfo LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystemZInfo LLVMTarget)
|
||||
set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport LLVMSystem)
|
||||
set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMipa)
|
||||
set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMX86CodeGen LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMX86Disassembler LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86Disassembler )
|
||||
set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMMC LLVMSupport LLVMX86Info)
|
||||
set(MSVC_LIB_DEPS_LLVMX86Info LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMXCore LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo)
|
||||
set(MSVC_LIB_DEPS_LLVMXCore LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget LLVMXCoreInfo)
|
||||
set(MSVC_LIB_DEPS_LLVMXCoreAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo)
|
||||
set(MSVC_LIB_DEPS_LLVMXCoreInfo LLVMSupport)
|
||||
set(MSVC_LIB_DEPS_LLVMipa LLVMAnalysis LLVMCore LLVMSupport LLVMSystem)
|
||||
|
2
configure
vendored
2
configure
vendored
@ -5080,7 +5080,7 @@ case "$enableval" in
|
||||
PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
SystemZ) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
s390x) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
*) { { echo "$as_me:$LINENO: error: Can not set target to build" >&5
|
||||
echo "$as_me: error: Can not set target to build" >&2;}
|
||||
|
@ -1731,11 +1731,6 @@ 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>
|
||||
|
||||
<p>On x86 and x86-64 one register is reserved for indirect tail calls (e.g via a
|
||||
function pointer). So there is one less register for integer argument
|
||||
passing. For x86 this means 2 registers (if <tt>inreg</tt> parameter
|
||||
attribute is used) and for x86-64 this means 5 register are used.</p>
|
||||
|
||||
</div>
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
@ -2121,7 +2116,7 @@ MOVSX32rm16 -> 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: 2009-10-10 23:30:55 +0200 (Sat, 10 Oct 2009) $
|
||||
Last modified: $Date: 2010-01-11 19:53:47 +0100 (Mon, 11 Jan 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -43,6 +43,7 @@
|
||||
<li><a href="#globalvars">Global Variables</a></li>
|
||||
<li><a href="#functionstructure">Functions</a></li>
|
||||
<li><a href="#aliasstructure">Aliases</a></li>
|
||||
<li><a href="#namedmetadatastructure">Named Metadata</a></li>
|
||||
<li><a href="#paramattrs">Parameter Attributes</a></li>
|
||||
<li><a href="#fnattrs">Function Attributes</a></li>
|
||||
<li><a href="#gc">Garbage Collector Names</a></li>
|
||||
@ -85,12 +86,12 @@
|
||||
<li><a href="#undefvalues">Undefined Values</a></li>
|
||||
<li><a href="#blockaddress">Addresses of Basic Blocks</a></li>
|
||||
<li><a href="#constantexprs">Constant Expressions</a></li>
|
||||
<li><a href="#metadata">Embedded Metadata</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#othervalues">Other Values</a>
|
||||
<ol>
|
||||
<li><a href="#inlineasm">Inline Assembler Expressions</a></li>
|
||||
<li><a href="#metadata">Metadata Nodes and Metadata Strings</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#intrinsic_globals">Intrinsic Global Variables</a>
|
||||
@ -498,14 +499,19 @@ define i32 @main() { <i>; i32()* </i>
|
||||
|
||||
<i>; Call puts function to write out the string to stdout.</i>
|
||||
<a href="#i_call">call</a> i32 @puts(i8 * %cast210) <i>; i32</i>
|
||||
<a href="#i_ret">ret</a> i32 0<br>}<br>
|
||||
<a href="#i_ret">ret</a> i32 0<br>}
|
||||
|
||||
<i>; Named metadata</i>
|
||||
!1 = metadata !{i32 41}
|
||||
!foo = !{!1, null}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This example is made up of a <a href="#globalvars">global variable</a> named
|
||||
"<tt>.LC0</tt>", an external declaration of the "<tt>puts</tt>" function, and
|
||||
"<tt>.LC0</tt>", an external declaration of the "<tt>puts</tt>" function,
|
||||
a <a href="#functionstructure">function definition</a> for
|
||||
"<tt>main</tt>".</p>
|
||||
"<tt>main</tt>" and <a href="#namedmetadatastructure">named metadata</a>
|
||||
"<tt>foo"</tt>.</p>
|
||||
|
||||
<p>In general, a module is made up of a list of global values, where both
|
||||
functions and global variables are global values. Global values are
|
||||
@ -558,10 +564,17 @@ define i32 @main() { <i>; i32()* </i>
|
||||
|
||||
<dt><tt><b><a name="linkage_linkonce">linkonce</a></b></tt></dt>
|
||||
<dd>Globals with "<tt>linkonce</tt>" linkage are merged with other globals of
|
||||
the same name when linkage occurs. This is typically used to implement
|
||||
inline functions, templates, or other code which must be generated in each
|
||||
translation unit that uses it. Unreferenced <tt>linkonce</tt> globals are
|
||||
allowed to be discarded.</dd>
|
||||
the same name when linkage occurs. This can be used to implement
|
||||
some forms of inline functions, templates, or other code which must be
|
||||
generated in each translation unit that uses it, but where the body may
|
||||
be overridden with a more definitive definition later. Unreferenced
|
||||
<tt>linkonce</tt> globals are allowed to be discarded. Note that
|
||||
<tt>linkonce</tt> linkage does not actually allow the optimizer to
|
||||
inline the body of this function into callers because it doesn't know if
|
||||
this definition of the function is the definitive definition within the
|
||||
program or whether it will be overridden by a stronger definition.
|
||||
To enable inlining and other optimizations, use "<tt>linkonce_odr</tt>"
|
||||
linkage.</dd>
|
||||
|
||||
<dt><tt><b><a name="linkage_weak">weak</a></b></tt></dt>
|
||||
<dd>"<tt>weak</tt>" linkage has the same merging semantics as
|
||||
@ -671,9 +684,9 @@ define i32 @main() { <i>; i32()* </i>
|
||||
(e.g. by passing things in registers). This calling convention allows the
|
||||
target to use whatever tricks it wants to produce fast code for the
|
||||
target, without having to conform to an externally specified ABI
|
||||
(Application Binary Interface). Implementations of this convention should
|
||||
allow arbitrary <a href="CodeGenerator.html#tailcallopt">tail call
|
||||
optimization</a> to be supported. This calling convention does not
|
||||
(Application Binary Interface).
|
||||
<a href="CodeGenerator.html#tailcallopt">Tail calls can only be optimized
|
||||
when this convention is used.</a> This calling convention does not
|
||||
support varargs and requires the prototype of all callees to exactly match
|
||||
the prototype of the function definition.</dd>
|
||||
|
||||
@ -904,6 +917,27 @@ define [<a href="#linkage">linkage</a>] [<a href="#visibility">visibility</a>]
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="namedmetadatastructure">Named Metadata</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Named metadata is a collection of metadata. <a href="#metadata"> Metadata </a>
|
||||
node and null are the only valid named metadata operands.
|
||||
Metadata strings are not allowed as an named metadata operand.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
!1 = metadata !{metadata !"one"}
|
||||
!name = !{null, !1}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="paramattrs">Parameter Attributes</a></div>
|
||||
|
||||
@ -1649,10 +1683,12 @@ Classifications</a> </div>
|
||||
underlying processor. The elements of a structure may be any type that has a
|
||||
size.</p>
|
||||
|
||||
<p>Structures are accessed using '<tt><a href="#i_load">load</a></tt> and
|
||||
'<tt><a href="#i_store">store</a></tt>' by getting a pointer to a field with
|
||||
the '<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.</p>
|
||||
|
||||
<p>Structures in memory are accessed using '<tt><a href="#i_load">load</a></tt>'
|
||||
and '<tt><a href="#i_store">store</a></tt>' by getting a pointer to a field
|
||||
with the '<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
|
||||
Structures in registers are accessed using the
|
||||
'<tt><a href="#i_extractvalue">extractvalue</a></tt>' and
|
||||
'<tt><a href="#i_insertvalue">insertvalue</a></tt>' instructions.</p>
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
{ <type list> }
|
||||
@ -2305,12 +2341,12 @@ has undefined behavior.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="metadata">Embedded Metadata</a>
|
||||
<div class="doc_subsection"><a name="metadata">Metadata Nodes and Metadata Strings</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Embedded metadata provides a way to attach arbitrary data to the instruction
|
||||
<p>Metadata provides a way to attach arbitrary data to the instruction
|
||||
stream without affecting the behaviour of the program. There are two
|
||||
metadata primitives, strings and nodes. All metadata has the
|
||||
<tt>metadata</tt> type and is identified in syntax by a preceding exclamation
|
||||
@ -2329,6 +2365,9 @@ has undefined behavior.</p>
|
||||
event that a value is deleted, it will be replaced with a typeless
|
||||
"<tt>null</tt>", such as "<tt>metadata !{null, i32 10}</tt>".</p>
|
||||
|
||||
<p>A <a href="#namedmetadatastructure">named metadata</a> is a collection of
|
||||
metadata nodes. For example: "<tt>!foo = metadata !{!4, !3}</tt>".
|
||||
|
||||
<p>Optimizations may rely on metadata to provide additional information about
|
||||
the program that isn't available in the instructions, or that isn't easily
|
||||
computable. Similarly, the code generator may expect a certain metadata
|
||||
@ -3848,7 +3887,7 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
<result> = insertvalue <aggregate type> <val>, <ty> <val>, <idx> <i>; yields <n x <ty>></i>
|
||||
<result> = insertvalue <aggregate type> <val>, <ty> <elt>, <idx> <i>; yields <aggregate type></i>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -3873,7 +3912,8 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
<result> = insertvalue {i32, float} %agg, i32 1, 0 <i>; yields {i32, float}</i>
|
||||
%agg1 = insertvalue {i32, float} undef, i32 1, 0 <i>; yields {i32 1, float undef}</i>
|
||||
%agg2 = insertvalue {i32, float} %agg1, float %val, 1 <i>; yields {i32 1, float %val}</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
@ -4983,15 +5023,31 @@ Loop: ; Infinite loop that counts from 0 on up...
|
||||
<p>This instruction requires several arguments:</p>
|
||||
|
||||
<ol>
|
||||
<li>The optional "tail" marker indicates whether the callee function accesses
|
||||
any allocas or varargs in the caller. If the "tail" marker is present,
|
||||
the function call is eligible for tail call optimization. Note that calls
|
||||
may be marked "tail" even if they do not occur before
|
||||
a <a href="#i_ret"><tt>ret</tt></a> instruction.</li>
|
||||
<li>The optional "tail" marker indicates that the callee function does not
|
||||
access any allocas or varargs in the caller. Note that calls may be
|
||||
marked "tail" even if they do not occur before
|
||||
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:
|
||||
<ul>
|
||||
<li>Caller and callee both have the calling
|
||||
convention <tt>fastcc</tt>.</li>
|
||||
<li>The call is in tail position (ret immediately follows call and ret
|
||||
uses value of call or is void).</li>
|
||||
<li>Option <tt>-tailcallopt</tt> is enabled,
|
||||
or <code>llvm::PerformTailCallOpt</code> is <code>true</code>.</li>
|
||||
<li><a href="CodeGenerator.html#tailcallopt">Platform specific
|
||||
constraints are met.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>The optional "cconv" marker indicates which <a href="#callingconv">calling
|
||||
convention</a> the call should use. If none is specified, the call
|
||||
defaults to using C calling conventions.</li>
|
||||
defaults to using C calling conventions. The calling convention of the
|
||||
call must match the calling convention of the target function, or else the
|
||||
behavior is undefined.</li>
|
||||
|
||||
<li>The optional <a href="#paramattrs">Parameter Attributes</a> list for
|
||||
return values. Only '<tt>zeroext</tt>', '<tt>signext</tt>', and
|
||||
@ -7263,7 +7319,7 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The <tt>llvm.objectsize</tt> intrinsic is designed to provide information
|
||||
to the optimizers to either discover at compile time either a) when an
|
||||
to the optimizers to discover at compile time either a) when an
|
||||
operation like memcpy will either overflow a buffer that corresponds to
|
||||
an object, or b) to determine that a runtime check for overflow isn't
|
||||
necessary. An object in this context means an allocation of a
|
||||
@ -7294,7 +7350,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: 2009-12-23 01:29:49 +0100 (Wed, 23 Dec 2009) $
|
||||
Last modified: $Date: 2010-01-11 20:35:55 +0100 (Mon, 11 Jan 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -94,6 +94,7 @@ option</a></li>
|
||||
<li><a href="#ds_bit">BitVector-like containers</a>
|
||||
<ul>
|
||||
<li><a href="#dss_bitvector">A dense bitvector</a></li>
|
||||
<li><a href="#dss_smallbitvector">A "small" dense bitvector</a></li>
|
||||
<li><a href="#dss_sparsebitvector">A sparse bitvector</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
@ -1584,7 +1585,7 @@ please don't use it.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p> The BitVector container provides a fixed size set of bits for manipulation.
|
||||
<p> The BitVector container provides a dynamic size set of bits for manipulation.
|
||||
It supports individual bit setting/testing, as well as set operations. The set
|
||||
operations take time O(size of bitvector), but operations are performed one word
|
||||
at a time, instead of one bit at a time. This makes the BitVector very fast for
|
||||
@ -1593,6 +1594,25 @@ the number of set bits to be high (IE a dense set).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="dss_smallbitvector">SmallBitVector</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p> The SmallBitVector container provides the same interface as BitVector, but
|
||||
it is optimized for the case where only a small number of bits, less than
|
||||
25 or so, are needed. It also transparently supports larger bit counts, but
|
||||
slightly less efficiently than a plain BitVector, so SmallBitVector should
|
||||
only be used when larger counts are rare.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
At this time, SmallBitVector does not support set operations (and, or, xor),
|
||||
and its operator[] does not provide an assignable lvalue.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="dss_sparsebitvector">SparseBitVector</a>
|
||||
@ -3872,7 +3892,7 @@ arguments. An argument has a pointer to the parent Function.</p>
|
||||
<a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-23 00:11:22 +0200 (Fri, 23 Oct 2009) $
|
||||
Last modified: $Date: 2010-01-05 19:24:00 +0100 (Tue, 05 Jan 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -58,6 +58,7 @@ Almost dead code.
|
||||
include/llvm/Analysis/LiveValues.h => Dan
|
||||
lib/Transforms/IPO/MergeFunctions.cpp => consider for 2.8.
|
||||
llvm/Analysis/PointerTracking.h => Edwin wants this, consider for 2.8.
|
||||
ABCD, SCCVN, GEPSplitterPass
|
||||
-->
|
||||
|
||||
|
||||
@ -1348,7 +1349,7 @@ lists</a>.</p>
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-11-03 22:50:09 +0100 (Tue, 03 Nov 2009) $
|
||||
Last modified: $Date: 2010-01-09 23:30:40 +0100 (Sat, 09 Jan 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -38,6 +38,7 @@
|
||||
<li><a href="#format_common_intrinsics">Debugger intrinsic functions</a>
|
||||
<ul>
|
||||
<li><a href="#format_common_declare">llvm.dbg.declare</a></li>
|
||||
<li><a href="#format_common_value">llvm.dbg.value</a></li>
|
||||
</ul></li>
|
||||
</ol></li>
|
||||
<li><a href="#format_common_lifetime">Object lifetimes and scoping</a></li>
|
||||
@ -774,6 +775,25 @@ DW_TAG_return_variable = 258
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_common_value">llvm.dbg.value</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<pre>
|
||||
void %<a href="#format_common_value">llvm.dbg.value</a>( metadata, i64, metadata )
|
||||
</pre>
|
||||
|
||||
<p>This intrinsic provides information when a user source variable is set to a
|
||||
new value. The first argument is the new value (wrapped as metadata). The
|
||||
second argument is the offset in the user source variable where the new value
|
||||
is written. The third argument is
|
||||
the <tt>%<a href="#format_variables">llvm.dbg.variable</a></tt> containing
|
||||
the description of the user source variable. </p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="format_common_lifetime">Object lifetimes and scoping</a>
|
||||
@ -1718,7 +1738,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: 2009-12-01 01:59:58 +0100 (Tue, 01 Dec 2009) $
|
||||
Last modified: $Date: 2010-01-11 23:53:48 +0100 (Mon, 11 Jan 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -423,6 +423,10 @@ class. This operation is analogous to $(foreach) in GNU make.</dd>
|
||||
<dd>An integer {0,1} indicating whether list 'a' is empty.</dd>
|
||||
<dt><tt>!if(a,b,c)</tt></dt>
|
||||
<dd>'b' if the result of integer operator 'a' is nonzero, 'c' otherwise.</dd>
|
||||
<dt><tt>!eq(a,b)</tt></dt>
|
||||
<dd>Integer one if string a is equal to string b, zero otherwise. This
|
||||
only operates on string objects. Use !cast<string> to compare other
|
||||
types of objects.</dd>
|
||||
</dl>
|
||||
|
||||
<p>Note that all of the values have rules specifying how they convert to values
|
||||
@ -794,7 +798,7 @@ This should highlight the APIs in <tt>TableGen/Record.h</tt>.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-29 19:10:34 +0100 (Thu, 29 Oct 2009) $
|
||||
Last modified: $Date: 2010-01-05 20:11:42 +0100 (Tue, 05 Jan 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -36,12 +36,12 @@ typedef enum {
|
||||
/* Verifies that a module is valid, taking the specified action if not.
|
||||
Optionally returns a human-readable description of any invalid constructs.
|
||||
OutMessage must be disposed with LLVMDisposeMessage. */
|
||||
int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
|
||||
char **OutMessage);
|
||||
LLVMBool LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
|
||||
char **OutMessage);
|
||||
|
||||
/* Verifies that a single function is valid, taking the specified action. Useful
|
||||
for debugging. */
|
||||
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
|
||||
LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
|
||||
|
||||
/* Open up a ghostview window that displays the CFG of the current function.
|
||||
Useful for debugging. */
|
||||
|
@ -29,24 +29,24 @@ extern "C" {
|
||||
/* Builds a module from the bitcode in the specified memory buffer, returning a
|
||||
reference to the module via the OutModule parameter. Returns 0 on success.
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage);
|
||||
LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage);
|
||||
|
||||
int LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage);
|
||||
LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage);
|
||||
|
||||
/* Reads a module from the specified path, returning via the OutMP parameter
|
||||
a module provider which performs lazy deserialization. Returns 0 on success.
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
|
||||
int LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -46,6 +46,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef int LLVMBool;
|
||||
|
||||
/* Opaque types. */
|
||||
|
||||
/**
|
||||
@ -292,7 +294,7 @@ const char *LLVMGetTarget(LLVMModuleRef M);
|
||||
void LLVMSetTarget(LLVMModuleRef M, const char *Triple);
|
||||
|
||||
/** See Module::addTypeName. */
|
||||
int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty);
|
||||
LLVMBool LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty);
|
||||
void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name);
|
||||
LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
|
||||
|
||||
@ -355,20 +357,20 @@ LLVMTypeRef LLVMPPCFP128Type(void);
|
||||
/* Operations on function types */
|
||||
LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType,
|
||||
LLVMTypeRef *ParamTypes, unsigned ParamCount,
|
||||
int IsVarArg);
|
||||
int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy);
|
||||
LLVMBool IsVarArg);
|
||||
LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy);
|
||||
LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy);
|
||||
unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy);
|
||||
void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest);
|
||||
|
||||
/* Operations on struct types */
|
||||
LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
|
||||
unsigned ElementCount, int Packed);
|
||||
unsigned ElementCount, LLVMBool Packed);
|
||||
LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount,
|
||||
int Packed);
|
||||
LLVMBool Packed);
|
||||
unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
|
||||
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
|
||||
int LLVMIsPackedStruct(LLVMTypeRef StructTy);
|
||||
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
|
||||
|
||||
/* Operations on array, pointer, and vector types (sequence types) */
|
||||
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
|
||||
@ -427,10 +429,6 @@ void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle);
|
||||
macro(IntrinsicInst) \
|
||||
macro(DbgInfoIntrinsic) \
|
||||
macro(DbgDeclareInst) \
|
||||
macro(DbgFuncStartInst) \
|
||||
macro(DbgRegionEndInst) \
|
||||
macro(DbgRegionStartInst) \
|
||||
macro(DbgStopPointInst) \
|
||||
macro(EHSelectorInst) \
|
||||
macro(MemIntrinsic) \
|
||||
macro(MemCpyInst) \
|
||||
@ -499,14 +497,14 @@ LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index);
|
||||
LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */
|
||||
LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty); /* only for int/vector */
|
||||
LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty);
|
||||
int LLVMIsConstant(LLVMValueRef Val);
|
||||
int LLVMIsNull(LLVMValueRef Val);
|
||||
int LLVMIsUndef(LLVMValueRef Val);
|
||||
LLVMBool LLVMIsConstant(LLVMValueRef Val);
|
||||
LLVMBool LLVMIsNull(LLVMValueRef Val);
|
||||
LLVMBool LLVMIsUndef(LLVMValueRef Val);
|
||||
LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty);
|
||||
|
||||
/* Operations on scalar constants */
|
||||
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
|
||||
int SignExtend);
|
||||
LLVMBool SignExtend);
|
||||
LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char *Text,
|
||||
uint8_t Radix);
|
||||
LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char *Text,
|
||||
@ -521,17 +519,17 @@ long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal);
|
||||
|
||||
/* Operations on composite constants */
|
||||
LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str,
|
||||
unsigned Length, int DontNullTerminate);
|
||||
unsigned Length, LLVMBool DontNullTerminate);
|
||||
LLVMValueRef LLVMConstStructInContext(LLVMContextRef C,
|
||||
LLVMValueRef *ConstantVals,
|
||||
unsigned Count, int Packed);
|
||||
unsigned Count, LLVMBool Packed);
|
||||
|
||||
LLVMValueRef LLVMConstString(const char *Str, unsigned Length,
|
||||
int DontNullTerminate);
|
||||
LLVMBool DontNullTerminate);
|
||||
LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
|
||||
LLVMValueRef *ConstantVals, unsigned Length);
|
||||
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
|
||||
int Packed);
|
||||
LLVMBool Packed);
|
||||
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
|
||||
|
||||
/* Constant expressions */
|
||||
@ -591,7 +589,7 @@ LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal,
|
||||
LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal,
|
||||
LLVMTypeRef ToType);
|
||||
LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType,
|
||||
unsigned isSigned);
|
||||
LLVMBool isSigned);
|
||||
LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
|
||||
LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition,
|
||||
LLVMValueRef ConstantIfTrue,
|
||||
@ -609,13 +607,13 @@ LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
|
||||
LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
|
||||
LLVMValueRef ElementValueConstant,
|
||||
unsigned *IdxList, unsigned NumIdx);
|
||||
LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty,
|
||||
LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty,
|
||||
const char *AsmString, const char *Constraints,
|
||||
int HasSideEffects);
|
||||
LLVMBool HasSideEffects, LLVMBool IsAlignStack);
|
||||
|
||||
/* Operations on global variables, functions, and aliases (globals) */
|
||||
LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global);
|
||||
int LLVMIsDeclaration(LLVMValueRef Global);
|
||||
LLVMBool LLVMIsDeclaration(LLVMValueRef Global);
|
||||
LLVMLinkage LLVMGetLinkage(LLVMValueRef Global);
|
||||
void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage);
|
||||
const char *LLVMGetSection(LLVMValueRef Global);
|
||||
@ -635,10 +633,10 @@ LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar);
|
||||
void LLVMDeleteGlobal(LLVMValueRef GlobalVar);
|
||||
LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar);
|
||||
void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal);
|
||||
int LLVMIsThreadLocal(LLVMValueRef GlobalVar);
|
||||
void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal);
|
||||
int LLVMIsGlobalConstant(LLVMValueRef GlobalVar);
|
||||
void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, int IsConstant);
|
||||
LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar);
|
||||
void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal);
|
||||
LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar);
|
||||
void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant);
|
||||
|
||||
/* Operations on aliases */
|
||||
LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
|
||||
@ -678,7 +676,7 @@ void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
|
||||
|
||||
/* Operations on basic blocks */
|
||||
LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB);
|
||||
int LLVMValueIsBasicBlock(LLVMValueRef Val);
|
||||
LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val);
|
||||
LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val);
|
||||
LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB);
|
||||
unsigned LLVMCountBasicBlocks(LLVMValueRef Fn);
|
||||
@ -718,8 +716,8 @@ void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
|
||||
unsigned align);
|
||||
|
||||
/* Operations on call instructions (only) */
|
||||
int LLVMIsTailCall(LLVMValueRef CallInst);
|
||||
void LLVMSetTailCall(LLVMValueRef CallInst, int IsTailCall);
|
||||
LLVMBool LLVMIsTailCall(LLVMValueRef CallInst);
|
||||
void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
|
||||
|
||||
/* Operations on phi nodes */
|
||||
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
|
||||
@ -932,11 +930,11 @@ void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP);
|
||||
|
||||
/*===-- Memory buffers ----------------------------------------------------===*/
|
||||
|
||||
int LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
|
||||
LLVMMemoryBufferRef *OutMemBuf,
|
||||
char **OutMessage);
|
||||
int LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
|
||||
char **OutMessage);
|
||||
LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
|
||||
LLVMMemoryBufferRef *OutMemBuf,
|
||||
char **OutMessage);
|
||||
LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
|
||||
char **OutMessage);
|
||||
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
|
||||
|
||||
|
||||
@ -956,23 +954,23 @@ LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP);
|
||||
/** Initializes, executes on the provided module, and finalizes all of the
|
||||
passes scheduled in the pass manager. Returns 1 if any of the passes
|
||||
modified the module, 0 otherwise. See llvm::PassManager::run(Module&). */
|
||||
int LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M);
|
||||
LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M);
|
||||
|
||||
/** Initializes all of the function passes scheduled in the function pass
|
||||
manager. Returns 1 if any of the passes modified the module, 0 otherwise.
|
||||
See llvm::FunctionPassManager::doInitialization. */
|
||||
int LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM);
|
||||
LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM);
|
||||
|
||||
/** Executes all of the function passes scheduled in the function pass manager
|
||||
on the provided function. Returns 1 if any of the passes modified the
|
||||
function, false otherwise.
|
||||
See llvm::FunctionPassManager::run(Function&). */
|
||||
int LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F);
|
||||
LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F);
|
||||
|
||||
/** Finalizes all of the function passes scheduled in in the function pass
|
||||
manager. Returns 1 if any of the passes modified the module, 0 otherwise.
|
||||
See llvm::FunctionPassManager::doFinalization. */
|
||||
int LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
|
||||
LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
|
||||
|
||||
/** Frees the memory of a pass pipeline. For function pipelines, does not free
|
||||
the module provider.
|
||||
|
@ -36,7 +36,7 @@ typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef;
|
||||
|
||||
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
|
||||
unsigned long long N,
|
||||
int IsSigned);
|
||||
LLVMBool IsSigned);
|
||||
|
||||
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P);
|
||||
|
||||
@ -45,7 +45,7 @@ LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef Ty, double N);
|
||||
unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef);
|
||||
|
||||
unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenVal,
|
||||
int IsSigned);
|
||||
LLVMBool IsSigned);
|
||||
|
||||
void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal);
|
||||
|
||||
@ -55,18 +55,18 @@ void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal);
|
||||
|
||||
/*===-- Operations on execution engines -----------------------------------===*/
|
||||
|
||||
int LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
|
||||
LLVMModuleProviderRef MP,
|
||||
char **OutError);
|
||||
LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
|
||||
LLVMModuleProviderRef MP,
|
||||
char **OutError);
|
||||
|
||||
int LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
|
||||
LLVMModuleProviderRef MP,
|
||||
char **OutError);
|
||||
LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
|
||||
LLVMModuleProviderRef MP,
|
||||
char **OutError);
|
||||
|
||||
int LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
|
||||
LLVMModuleProviderRef MP,
|
||||
unsigned OptLevel,
|
||||
char **OutError);
|
||||
LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
|
||||
LLVMModuleProviderRef MP,
|
||||
unsigned OptLevel,
|
||||
char **OutError);
|
||||
|
||||
void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE);
|
||||
|
||||
@ -86,12 +86,12 @@ void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F);
|
||||
|
||||
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP);
|
||||
|
||||
int LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
|
||||
LLVMModuleProviderRef MP,
|
||||
LLVMModuleRef *OutMod, char **OutError);
|
||||
LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
|
||||
LLVMModuleProviderRef MP,
|
||||
LLVMModuleRef *OutMod, char **OutError);
|
||||
|
||||
int LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
|
||||
LLVMValueRef *OutFn);
|
||||
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
|
||||
LLVMValueRef *OutFn);
|
||||
|
||||
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
|
||||
|
||||
|
@ -26,8 +26,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum { LLVMBigEndian, LLVMLittleEndian };
|
||||
typedef int LLVMByteOrdering;
|
||||
enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian };
|
||||
|
||||
typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
|
||||
typedef struct LLVMStructLayout *LLVMStructLayoutRef;
|
||||
@ -62,7 +61,7 @@ static inline void LLVMInitializeAllTargets() {
|
||||
/** LLVMInitializeNativeTarget - The main program should call this function to
|
||||
initialize the native target corresponding to the host. This is useful
|
||||
for JIT applications to ensure that the target gets linked in correctly. */
|
||||
static inline int LLVMInitializeNativeTarget() {
|
||||
static inline LLVMBool LLVMInitializeNativeTarget() {
|
||||
/* If we have a native target, initialize it to ensure it is linked in. */
|
||||
#ifdef LLVM_NATIVE_ARCH
|
||||
#define DoInit2(TARG) \
|
||||
@ -97,7 +96,7 @@ char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
|
||||
/** Returns the byte order of a target, either LLVMBigEndian or
|
||||
LLVMLittleEndian.
|
||||
See the method llvm::TargetData::isLittleEndian. */
|
||||
LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
|
||||
enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
|
||||
|
||||
/** Returns the pointer size in bytes for a target.
|
||||
See the method llvm::TargetData::getPointerSize. */
|
||||
|
@ -95,6 +95,9 @@ class BitVector {
|
||||
delete[] Bits;
|
||||
}
|
||||
|
||||
/// empty - Tests whether there are no bits in this bitvector.
|
||||
bool empty() const { return Size == 0; }
|
||||
|
||||
/// size - Returns the number of bits in this bitvector.
|
||||
unsigned size() const { return Size; }
|
||||
|
||||
@ -341,6 +344,12 @@ class BitVector {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(BitVector &RHS) {
|
||||
std::swap(Bits, RHS.Bits);
|
||||
std::swap(Size, RHS.Size);
|
||||
std::swap(Capacity, RHS.Capacity);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned NumBitWords(unsigned S) const {
|
||||
return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
|
||||
@ -406,4 +415,13 @@ inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
namespace std {
|
||||
/// Implement std::swap in terms of BitVector swap.
|
||||
inline void
|
||||
swap(llvm::BitVector &LHS, llvm::BitVector &RHS) {
|
||||
LHS.swap(RHS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
373
include/llvm/ADT/SmallBitVector.h
Normal file
373
include/llvm/ADT/SmallBitVector.h
Normal file
@ -0,0 +1,373 @@
|
||||
//===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the SmallBitVector class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_SMALLBITVECTOR_H
|
||||
#define LLVM_ADT_SMALLBITVECTOR_H
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array),
|
||||
/// optimized for the case when the array is small. It contains one
|
||||
/// pointer-sized field, which is directly used as a plain collection of bits
|
||||
/// when possible, or as a pointer to a larger heap-allocated array when
|
||||
/// necessary. This allows normal "small" cases to be fast without losing
|
||||
/// generality for large inputs.
|
||||
///
|
||||
class SmallBitVector {
|
||||
// TODO: In "large" mode, a pointer to a BitVector is used, leading to an
|
||||
// unnecessary level of indirection. It would be more efficient to use a
|
||||
// pointer to memory containing size, allocation size, and the array of bits.
|
||||
PointerIntPair<BitVector *, 1, uintptr_t> X;
|
||||
|
||||
// The number of bits in this class.
|
||||
static const size_t NumBaseBits = sizeof(uintptr_t) * CHAR_BIT;
|
||||
|
||||
// One bit is used to discriminate between small and large mode. The
|
||||
// remaining bits are used for the small-mode representation.
|
||||
static const size_t SmallNumRawBits = NumBaseBits - 1;
|
||||
|
||||
// A few more bits are used to store the size of the bit set in small mode.
|
||||
// Theoretically this is a ceil-log2. These bits are encoded in the most
|
||||
// significant bits of the raw bits.
|
||||
static const size_t SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
|
||||
NumBaseBits == 64 ? 6 :
|
||||
SmallNumRawBits);
|
||||
|
||||
// The remaining bits are used to store the actual set in small mode.
|
||||
static const size_t SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits;
|
||||
|
||||
bool isSmall() const {
|
||||
return X.getInt();
|
||||
}
|
||||
|
||||
void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) {
|
||||
X.setInt(true);
|
||||
setSmallSize(NewSize);
|
||||
setSmallBits(NewSmallBits);
|
||||
}
|
||||
|
||||
void switchToLarge(BitVector *BV) {
|
||||
X.setInt(false);
|
||||
X.setPointer(BV);
|
||||
}
|
||||
|
||||
// Return all the bits used for the "small" representation; this includes
|
||||
// bits for the size as well as the element bits.
|
||||
uintptr_t getSmallRawBits() const {
|
||||
return reinterpret_cast<uintptr_t>(X.getPointer()) >> 1;
|
||||
}
|
||||
|
||||
void setSmallRawBits(uintptr_t NewRawBits) {
|
||||
return X.setPointer(reinterpret_cast<BitVector *>(NewRawBits << 1));
|
||||
}
|
||||
|
||||
// Return the size.
|
||||
size_t getSmallSize() const {
|
||||
return getSmallRawBits() >> SmallNumDataBits;
|
||||
}
|
||||
|
||||
void setSmallSize(size_t Size) {
|
||||
setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
|
||||
}
|
||||
|
||||
// Return the element bits.
|
||||
uintptr_t getSmallBits() const {
|
||||
return getSmallRawBits() & ~(~uintptr_t(0) << SmallNumDataBits);
|
||||
}
|
||||
|
||||
void setSmallBits(uintptr_t NewBits) {
|
||||
setSmallRawBits((getSmallRawBits() & (~uintptr_t(0) << SmallNumDataBits)) |
|
||||
(NewBits & ~(~uintptr_t(0) << getSmallSize())));
|
||||
}
|
||||
|
||||
public:
|
||||
/// SmallBitVector default ctor - Creates an empty bitvector.
|
||||
SmallBitVector() : X(0, 1) {}
|
||||
|
||||
/// SmallBitVector ctor - Creates a bitvector of specified number of bits. All
|
||||
/// bits are initialized to the specified value.
|
||||
explicit SmallBitVector(unsigned s, bool t = false) : X(0, 1) {
|
||||
if (s <= SmallNumRawBits)
|
||||
switchToSmall(t ? ~uintptr_t(0) : 0, s);
|
||||
else
|
||||
switchToLarge(new BitVector(s, t));
|
||||
}
|
||||
|
||||
/// SmallBitVector copy ctor.
|
||||
SmallBitVector(const SmallBitVector &RHS) {
|
||||
if (RHS.isSmall())
|
||||
X = RHS.X;
|
||||
else
|
||||
switchToLarge(new BitVector(*RHS.X.getPointer()));
|
||||
}
|
||||
|
||||
~SmallBitVector() {
|
||||
if (!isSmall())
|
||||
delete X.getPointer();
|
||||
}
|
||||
|
||||
/// empty - Tests whether there are no bits in this bitvector.
|
||||
bool empty() const {
|
||||
return isSmall() ? getSmallSize() == 0 : X.getPointer()->empty();
|
||||
}
|
||||
|
||||
/// size - Returns the number of bits in this bitvector.
|
||||
size_t size() const {
|
||||
return isSmall() ? getSmallSize() : X.getPointer()->size();
|
||||
}
|
||||
|
||||
/// count - Returns the number of bits which are set.
|
||||
unsigned count() const {
|
||||
if (isSmall()) {
|
||||
uintptr_t Bits = getSmallBits();
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
return CountPopulation_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
return CountPopulation_64(Bits);
|
||||
assert(0 && "Unsupported!");
|
||||
}
|
||||
return X.getPointer()->count();
|
||||
}
|
||||
|
||||
/// any - Returns true if any bit is set.
|
||||
bool any() const {
|
||||
if (isSmall())
|
||||
return getSmallBits() != 0;
|
||||
return X.getPointer()->any();
|
||||
}
|
||||
|
||||
/// none - Returns true if none of the bits are set.
|
||||
bool none() const {
|
||||
if (isSmall())
|
||||
return getSmallBits() == 0;
|
||||
return X.getPointer()->none();
|
||||
}
|
||||
|
||||
/// find_first - Returns the index of the first set bit, -1 if none
|
||||
/// of the bits are set.
|
||||
int find_first() const {
|
||||
if (isSmall()) {
|
||||
uintptr_t Bits = getSmallBits();
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
return CountTrailingZeros_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
return CountTrailingZeros_64(Bits);
|
||||
assert(0 && "Unsupported!");
|
||||
}
|
||||
return X.getPointer()->find_first();
|
||||
}
|
||||
|
||||
/// find_next - Returns the index of the next set bit following the
|
||||
/// "Prev" bit. Returns -1 if the next set bit is not found.
|
||||
int find_next(unsigned Prev) const {
|
||||
if (isSmall()) {
|
||||
uintptr_t Bits = getSmallBits();
|
||||
// Mask off previous bits.
|
||||
Bits &= ~uintptr_t(0) << Prev;
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
return CountTrailingZeros_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
return CountTrailingZeros_64(Bits);
|
||||
assert(0 && "Unsupported!");
|
||||
}
|
||||
return X.getPointer()->find_next(Prev);
|
||||
}
|
||||
|
||||
/// clear - Clear all bits.
|
||||
void clear() {
|
||||
if (!isSmall())
|
||||
delete X.getPointer();
|
||||
switchToSmall(0, 0);
|
||||
}
|
||||
|
||||
/// resize - Grow or shrink the bitvector.
|
||||
void resize(unsigned N, bool t = false) {
|
||||
if (!isSmall()) {
|
||||
X.getPointer()->resize(N, t);
|
||||
} else if (getSmallSize() >= N) {
|
||||
setSmallSize(N);
|
||||
setSmallBits(getSmallBits());
|
||||
} else {
|
||||
BitVector *BV = new BitVector(N, t);
|
||||
uintptr_t OldBits = getSmallBits();
|
||||
for (size_t i = 0, e = getSmallSize(); i != e; ++i)
|
||||
(*BV)[i] = (OldBits >> i) & 1;
|
||||
switchToLarge(BV);
|
||||
}
|
||||
}
|
||||
|
||||
void reserve(unsigned N) {
|
||||
if (isSmall()) {
|
||||
if (N > SmallNumDataBits) {
|
||||
uintptr_t OldBits = getSmallRawBits();
|
||||
size_t SmallSize = getSmallSize();
|
||||
BitVector *BV = new BitVector(SmallSize);
|
||||
for (size_t i = 0; i < SmallSize; ++i)
|
||||
if ((OldBits >> i) & 1)
|
||||
BV->set(i);
|
||||
BV->reserve(N);
|
||||
switchToLarge(BV);
|
||||
}
|
||||
} else {
|
||||
X.getPointer()->reserve(N);
|
||||
}
|
||||
}
|
||||
|
||||
// Set, reset, flip
|
||||
SmallBitVector &set() {
|
||||
if (isSmall())
|
||||
setSmallBits(~uintptr_t(0));
|
||||
else
|
||||
X.getPointer()->set();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallBitVector &set(unsigned Idx) {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
|
||||
else
|
||||
X.getPointer()->set(Idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallBitVector &reset() {
|
||||
if (isSmall())
|
||||
setSmallBits(0);
|
||||
else
|
||||
X.getPointer()->reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallBitVector &reset(unsigned Idx) {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
|
||||
else
|
||||
X.getPointer()->reset(Idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallBitVector &flip() {
|
||||
if (isSmall())
|
||||
setSmallBits(~getSmallBits());
|
||||
else
|
||||
X.getPointer()->flip();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallBitVector &flip(unsigned Idx) {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
|
||||
else
|
||||
X.getPointer()->flip(Idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// No argument flip.
|
||||
SmallBitVector operator~() const {
|
||||
return SmallBitVector(*this).flip();
|
||||
}
|
||||
|
||||
// Indexing.
|
||||
// TODO: Add an index operator which returns a "reference" (proxy class).
|
||||
bool operator[](unsigned Idx) const {
|
||||
assert(Idx < size() && "Out-of-bounds Bit access.");
|
||||
if (isSmall())
|
||||
return ((getSmallBits() >> Idx) & 1) != 0;
|
||||
return X.getPointer()->operator[](Idx);
|
||||
}
|
||||
|
||||
bool test(unsigned Idx) const {
|
||||
return (*this)[Idx];
|
||||
}
|
||||
|
||||
// Comparison operators.
|
||||
bool operator==(const SmallBitVector &RHS) const {
|
||||
if (size() != RHS.size())
|
||||
return false;
|
||||
if (isSmall())
|
||||
return getSmallBits() == RHS.getSmallBits();
|
||||
else
|
||||
return *X.getPointer() == *RHS.X.getPointer();
|
||||
}
|
||||
|
||||
bool operator!=(const SmallBitVector &RHS) const {
|
||||
return !(*this == RHS);
|
||||
}
|
||||
|
||||
// Intersection, union, disjoint union.
|
||||
BitVector &operator&=(const SmallBitVector &RHS); // TODO: implement
|
||||
|
||||
BitVector &operator|=(const SmallBitVector &RHS); // TODO: implement
|
||||
|
||||
BitVector &operator^=(const SmallBitVector &RHS); // TODO: implement
|
||||
|
||||
// Assignment operator.
|
||||
const SmallBitVector &operator=(const SmallBitVector &RHS) {
|
||||
if (isSmall()) {
|
||||
if (RHS.isSmall())
|
||||
X = RHS.X;
|
||||
else
|
||||
switchToLarge(new BitVector(*RHS.X.getPointer()));
|
||||
} else {
|
||||
if (!RHS.isSmall())
|
||||
*X.getPointer() = *RHS.X.getPointer();
|
||||
else {
|
||||
delete X.getPointer();
|
||||
X = RHS.X;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(SmallBitVector &RHS) {
|
||||
std::swap(X, RHS.X);
|
||||
}
|
||||
};
|
||||
|
||||
inline SmallBitVector
|
||||
operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) {
|
||||
SmallBitVector Result(LHS);
|
||||
Result &= RHS;
|
||||
return Result;
|
||||
}
|
||||
|
||||
inline SmallBitVector
|
||||
operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) {
|
||||
SmallBitVector Result(LHS);
|
||||
Result |= RHS;
|
||||
return Result;
|
||||
}
|
||||
|
||||
inline SmallBitVector
|
||||
operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
|
||||
SmallBitVector Result(LHS);
|
||||
Result ^= RHS;
|
||||
return Result;
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
namespace std {
|
||||
/// Implement std::swap in terms of BitVector swap.
|
||||
inline void
|
||||
swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
|
||||
LHS.swap(RHS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -23,6 +23,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
template<typename T> class SmallVectorImpl;
|
||||
|
||||
/// hexdigit - Return the (uppercase) hexadecimal character for the
|
||||
/// given number \arg X (which should be less than 16).
|
||||
@ -136,86 +137,25 @@ static inline std::string UppercaseString(const std::string &S) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
|
||||
/// case.
|
||||
static inline bool StringsEqualNoCase(const std::string &LHS,
|
||||
const std::string &RHS) {
|
||||
if (LHS.size() != RHS.size()) return false;
|
||||
for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i)
|
||||
if (tolower(LHS[i]) != tolower(RHS[i])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
|
||||
/// case.
|
||||
static inline bool StringsEqualNoCase(const std::string &LHS,
|
||||
const char *RHS) {
|
||||
for (unsigned i = 0, e = static_cast<unsigned>(LHS.size()); i != e; ++i) {
|
||||
if (RHS[i] == 0) return false; // RHS too short.
|
||||
if (tolower(LHS[i]) != tolower(RHS[i])) return false;
|
||||
}
|
||||
return RHS[LHS.size()] == 0; // Not too long?
|
||||
}
|
||||
|
||||
/// StringsEqualNoCase - Return true if the two null-terminated C strings are
|
||||
/// equal, ignoring
|
||||
|
||||
static inline bool StringsEqualNoCase(const char *LHS, const char *RHS,
|
||||
unsigned len) {
|
||||
|
||||
for (unsigned i = 0; i < len; ++i) {
|
||||
if (tolower(LHS[i]) != tolower(RHS[i]))
|
||||
return false;
|
||||
|
||||
// If RHS[i] == 0 then LHS[i] == 0 or otherwise we would have returned
|
||||
// at the previous branch as tolower('\0') == '\0'.
|
||||
if (RHS[i] == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// CStrInCStrNoCase - Portable version of strcasestr. Locates the first
|
||||
/// occurance of c-string 's2' in string 's1', ignoring case. Returns
|
||||
/// NULL if 's2' cannot be found.
|
||||
static inline const char* CStrInCStrNoCase(const char *s1, const char *s2) {
|
||||
|
||||
// Are either strings NULL or empty?
|
||||
if (!s1 || !s2 || s1[0] == '\0' || s2[0] == '\0')
|
||||
return 0;
|
||||
|
||||
if (s1 == s2)
|
||||
return s1;
|
||||
|
||||
const char *I1=s1, *I2=s2;
|
||||
|
||||
while (*I1 != '\0' && *I2 != '\0' )
|
||||
if (tolower(*I1) != tolower(*I2)) { // No match. Start over.
|
||||
++s1; I1 = s1; I2 = s2;
|
||||
}
|
||||
else { // Character match. Advance to the next character.
|
||||
++I1; ++I2;
|
||||
}
|
||||
|
||||
// If we exhausted all of the characters in 's2', then 's2' appears in 's1'.
|
||||
return *I2 == '\0' ? s1 : 0;
|
||||
}
|
||||
/// StrInStrNoCase - Portable version of strcasestr. Locates the first
|
||||
/// occurrence of string 's1' in string 's2', ignoring case. Returns
|
||||
/// the offset of s2 in s1 or npos if s2 cannot be found.
|
||||
StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
|
||||
|
||||
/// getToken - This function extracts one token from source, ignoring any
|
||||
/// leading characters that appear in the Delimiters string, and ending the
|
||||
/// token at any of the characters that appear in the Delimiters string. If
|
||||
/// there are no tokens in the source string, an empty string is returned.
|
||||
/// The Source source string is updated in place to remove the returned string
|
||||
/// and any delimiter prefix from it.
|
||||
std::string getToken(std::string &Source,
|
||||
const char *Delimiters = " \t\n\v\f\r");
|
||||
/// The function returns a pair containing the extracted token and the
|
||||
/// remaining tail string.
|
||||
std::pair<StringRef, StringRef> getToken(StringRef Source,
|
||||
StringRef Delimiters = " \t\n\v\f\r");
|
||||
|
||||
/// SplitString - Split up the specified string according to the specified
|
||||
/// delimiters, appending the result fragments to the output list.
|
||||
void SplitString(const std::string &Source,
|
||||
std::vector<std::string> &OutFragments,
|
||||
const char *Delimiters = " \t\n\v\f\r");
|
||||
void SplitString(StringRef Source,
|
||||
SmallVectorImpl<StringRef> &OutFragments,
|
||||
StringRef Delimiters = " \t\n\v\f\r");
|
||||
|
||||
/// HashString - Hash funtion for strings.
|
||||
///
|
||||
|
@ -29,6 +29,7 @@ namespace llvm {
|
||||
class StringRef {
|
||||
public:
|
||||
typedef const char *iterator;
|
||||
typedef const char *const_iterator;
|
||||
static const size_t npos = ~size_t(0);
|
||||
typedef size_t size_type;
|
||||
|
||||
@ -42,15 +43,8 @@ namespace llvm {
|
||||
// Workaround PR5482: nearly all gcc 4.x miscompile StringRef and std::min()
|
||||
// Changing the arg of min to be an integer, instead of a reference to an
|
||||
// integer works around this bug.
|
||||
size_t min(size_t a, size_t b) const
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
size_t max(size_t a, size_t b) const
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
size_t min(size_t a, size_t b) const { return a < b ? a : b; }
|
||||
size_t max(size_t a, size_t b) const { return a > b ? a : b; }
|
||||
|
||||
public:
|
||||
/// @name Constructors
|
||||
@ -191,7 +185,7 @@ namespace llvm {
|
||||
|
||||
/// find - Search for the first character \arg C in the string.
|
||||
///
|
||||
/// \return - The index of the first occurence of \arg C, or npos if not
|
||||
/// \return - The index of the first occurrence of \arg C, or npos if not
|
||||
/// found.
|
||||
size_t find(char C, size_t From = 0) const {
|
||||
for (size_t i = min(From, Length), e = Length; i != e; ++i)
|
||||
@ -202,13 +196,13 @@ namespace llvm {
|
||||
|
||||
/// find - Search for the first string \arg Str in the string.
|
||||
///
|
||||
/// \return - The index of the first occurence of \arg Str, or npos if not
|
||||
/// \return - The index of the first occurrence of \arg Str, or npos if not
|
||||
/// found.
|
||||
size_t find(StringRef Str, size_t From = 0) const;
|
||||
|
||||
/// rfind - Search for the last character \arg C in the string.
|
||||
///
|
||||
/// \return - The index of the last occurence of \arg C, or npos if not
|
||||
/// \return - The index of the last occurrence of \arg C, or npos if not
|
||||
/// found.
|
||||
size_t rfind(char C, size_t From = npos) const {
|
||||
From = min(From, Length);
|
||||
@ -223,7 +217,7 @@ namespace llvm {
|
||||
|
||||
/// rfind - Search for the last string \arg Str in the string.
|
||||
///
|
||||
/// \return - The index of the last occurence of \arg Str, or npos if not
|
||||
/// \return - The index of the last occurrence of \arg Str, or npos if not
|
||||
/// found.
|
||||
size_t rfind(StringRef Str) const;
|
||||
|
||||
@ -313,7 +307,7 @@ namespace llvm {
|
||||
return StringRef(Data + Start, End - Start);
|
||||
}
|
||||
|
||||
/// split - Split into two substrings around the first occurence of a
|
||||
/// split - Split into two substrings around the first occurrence of a
|
||||
/// separator character.
|
||||
///
|
||||
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
|
||||
@ -330,7 +324,7 @@ namespace llvm {
|
||||
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
|
||||
}
|
||||
|
||||
/// split - Split into two substrings around the first occurence of a
|
||||
/// split - Split into two substrings around the first occurrence of a
|
||||
/// separator string.
|
||||
///
|
||||
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
|
||||
@ -347,7 +341,7 @@ namespace llvm {
|
||||
return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
|
||||
}
|
||||
|
||||
/// split - Split into substrings around the occurences of a separator
|
||||
/// split - Split into substrings around the occurrences of a separator
|
||||
/// string.
|
||||
///
|
||||
/// Each substring is stored in \arg A. If \arg MaxSplit is >= 0, at most
|
||||
@ -366,7 +360,7 @@ namespace llvm {
|
||||
StringRef Separator, int MaxSplit = -1,
|
||||
bool KeepEmpty = true) const;
|
||||
|
||||
/// rsplit - Split into two substrings around the last occurence of a
|
||||
/// rsplit - Split into two substrings around the last occurrence of a
|
||||
/// separator character.
|
||||
///
|
||||
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
|
||||
|
@ -329,6 +329,22 @@ namespace llvm {
|
||||
bool isTriviallyEmpty() const {
|
||||
return isNullary();
|
||||
}
|
||||
|
||||
/// isSingleStringRef - Return true if this twine can be dynamically
|
||||
/// accessed as a single StringRef value with getSingleStringRef().
|
||||
bool isSingleStringRef() const {
|
||||
if (getRHSKind() != EmptyKind) return false;
|
||||
|
||||
switch (getLHSKind()) {
|
||||
case EmptyKind:
|
||||
case CStringKind:
|
||||
case StdStringKind:
|
||||
case StringRefKind:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name String Operations
|
||||
@ -347,6 +363,24 @@ namespace llvm {
|
||||
/// SmallVector.
|
||||
void toVector(SmallVectorImpl<char> &Out) const;
|
||||
|
||||
/// getSingleStringRef - This returns the twine as a single StringRef. This
|
||||
/// method is only valid if isSingleStringRef() is true.
|
||||
StringRef getSingleStringRef() const {
|
||||
assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
|
||||
switch (getLHSKind()) {
|
||||
default: assert(0 && "Out of sync with isSingleStringRef");
|
||||
case EmptyKind: return StringRef();
|
||||
case CStringKind: return StringRef((const char*)LHS);
|
||||
case StdStringKind: return StringRef(*(const std::string*)LHS);
|
||||
case StringRefKind: return *(const StringRef*)LHS;
|
||||
}
|
||||
}
|
||||
|
||||
/// toStringRef - This returns the twine as a single StringRef if it can be
|
||||
/// represented as such. Otherwise the twine is written into the given
|
||||
/// SmallVector and a StringRef to the SmallVector's data is returned.
|
||||
StringRef toStringRef(SmallVectorImpl<char> &Out) const;
|
||||
|
||||
/// print - Write the concatenated string represented by this twine to the
|
||||
/// stream \arg OS.
|
||||
void print(raw_ostream &OS) const;
|
||||
|
@ -197,6 +197,10 @@ class AliasAnalysis {
|
||||
virtual ModRefBehavior getModRefBehavior(Function *F,
|
||||
std::vector<PointerAccessInfo> *Info = 0);
|
||||
|
||||
/// getModRefBehavior - Return the modref behavior of the intrinsic with the
|
||||
/// given id.
|
||||
static ModRefBehavior getModRefBehavior(unsigned iid);
|
||||
|
||||
/// doesNotAccessMemory - If the specified call is known to never read or
|
||||
/// write memory, return true. If the call only reads from known-constant
|
||||
/// memory, it is also legal to return true. Calls that unwind the stack
|
||||
|
@ -30,11 +30,7 @@ namespace llvm {
|
||||
class Module;
|
||||
class Type;
|
||||
class Value;
|
||||
struct DbgStopPointInst;
|
||||
struct DbgDeclareInst;
|
||||
struct DbgFuncStartInst;
|
||||
struct DbgRegionStartInst;
|
||||
struct DbgRegionEndInst;
|
||||
class DbgDeclareInst;
|
||||
class DebugLoc;
|
||||
struct DebugLocTracker;
|
||||
class Instruction;
|
||||
@ -495,7 +491,6 @@ namespace llvm {
|
||||
Module &M;
|
||||
LLVMContext& VMContext;
|
||||
|
||||
const Type *EmptyStructPtr; // "{}*".
|
||||
Function *DeclareFn; // llvm.dbg.declare
|
||||
Function *ValueFn; // llvm.dbg.value
|
||||
|
||||
@ -651,27 +646,19 @@ namespace llvm {
|
||||
Instruction *InsertBefore);
|
||||
|
||||
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
|
||||
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset,
|
||||
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
|
||||
DIVariable D, BasicBlock *InsertAtEnd);
|
||||
|
||||
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
|
||||
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, llvm::Value *Offset,
|
||||
Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset,
|
||||
DIVariable D, Instruction *InsertBefore);
|
||||
private:
|
||||
Constant *GetTagConstant(unsigned TAG);
|
||||
};
|
||||
|
||||
/// Finds the stoppoint coressponding to this instruction, that is the
|
||||
/// stoppoint that dominates this instruction
|
||||
const DbgStopPointInst *findStopPoint(const Instruction *Inst);
|
||||
|
||||
/// Finds the stoppoint corresponding to first real (non-debug intrinsic)
|
||||
/// instruction in this Basic Block, and returns the stoppoint for it.
|
||||
const DbgStopPointInst *findBBStopPoint(const BasicBlock *BB);
|
||||
|
||||
/// Finds the dbg.declare intrinsic corresponding to this value if any.
|
||||
/// It looks through pointer casts too.
|
||||
const DbgDeclareInst *findDbgDeclare(const Value *V, bool stripCasts = true);
|
||||
const DbgDeclareInst *findDbgDeclare(const Value *V);
|
||||
|
||||
/// Find the debug info descriptor corresponding to this global variable.
|
||||
Value *findDbgGlobalDeclare(GlobalVariable *V);
|
||||
@ -680,21 +667,11 @@ namespace llvm {
|
||||
std::string &Type, unsigned &LineNo, std::string &File,
|
||||
std::string &Dir);
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.stoppoint intrinsic.
|
||||
DebugLoc ExtractDebugLocation(DbgStopPointInst &SPI,
|
||||
DebugLocTracker &DebugLocInfo);
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from DILocation.
|
||||
DebugLoc ExtractDebugLocation(DILocation &Loc,
|
||||
DebugLocTracker &DebugLocInfo);
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.func_start intrinsic.
|
||||
DebugLoc ExtractDebugLocation(DbgFuncStartInst &FSI,
|
||||
DebugLocTracker &DebugLocInfo);
|
||||
|
||||
/// getDISubprogram - Find subprogram that is enclosing this scope.
|
||||
DISubprogram getDISubprogram(MDNode *Scope);
|
||||
|
||||
|
@ -347,15 +347,8 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
|
||||
DT.IDoms.clear();
|
||||
DT.Info.clear();
|
||||
std::vector<typename GraphT::NodeType*>().swap(DT.Vertex);
|
||||
|
||||
// FIXME: This does not work on PostDomTrees. It seems likely that this is
|
||||
// due to an error in the algorithm for post-dominators. This really should
|
||||
// be investigated and fixed at some point.
|
||||
// DT.updateDFSNumbers();
|
||||
|
||||
// Start out with the DFS numbers being invalid. Let them be computed if
|
||||
// demanded.
|
||||
DT.DFSInfoValid = false;
|
||||
DT.updateDFSNumbers();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -390,6 +390,13 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
|
||||
if (A == 0 || B == 0)
|
||||
return false;
|
||||
|
||||
// Compare the result of the tree walk and the dfs numbers, if expensive
|
||||
// checks are enabled.
|
||||
#ifdef XDEBUG
|
||||
assert(!DFSInfoValid
|
||||
|| (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A)));
|
||||
#endif
|
||||
|
||||
if (DFSInfoValid)
|
||||
return B->DominatedBy(A);
|
||||
|
||||
@ -585,29 +592,35 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
|
||||
SmallVector<std::pair<DomTreeNodeBase<NodeT>*,
|
||||
typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;
|
||||
|
||||
for (unsigned i = 0, e = (unsigned)this->Roots.size(); i != e; ++i) {
|
||||
DomTreeNodeBase<NodeT> *ThisRoot = getNode(this->Roots[i]);
|
||||
WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
|
||||
ThisRoot->DFSNumIn = DFSNum++;
|
||||
DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
|
||||
|
||||
while (!WorkStack.empty()) {
|
||||
DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
|
||||
typename DomTreeNodeBase<NodeT>::iterator ChildIt =
|
||||
WorkStack.back().second;
|
||||
if (!ThisRoot)
|
||||
return;
|
||||
|
||||
// If we visited all of the children of this node, "recurse" back up the
|
||||
// stack setting the DFOutNum.
|
||||
if (ChildIt == Node->end()) {
|
||||
Node->DFSNumOut = DFSNum++;
|
||||
WorkStack.pop_back();
|
||||
} else {
|
||||
// Otherwise, recursively visit this child.
|
||||
DomTreeNodeBase<NodeT> *Child = *ChildIt;
|
||||
++WorkStack.back().second;
|
||||
// Even in the case of multiple exits that form the post dominator root
|
||||
// nodes, do not iterate over all exits, but start from the virtual root
|
||||
// node. Otherwise bbs, that are not post dominated by any exit but by the
|
||||
// virtual root node, will never be assigned a DFS number.
|
||||
WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
|
||||
ThisRoot->DFSNumIn = DFSNum++;
|
||||
|
||||
WorkStack.push_back(std::make_pair(Child, Child->begin()));
|
||||
Child->DFSNumIn = DFSNum++;
|
||||
}
|
||||
while (!WorkStack.empty()) {
|
||||
DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
|
||||
typename DomTreeNodeBase<NodeT>::iterator ChildIt =
|
||||
WorkStack.back().second;
|
||||
|
||||
// If we visited all of the children of this node, "recurse" back up the
|
||||
// stack setting the DFOutNum.
|
||||
if (ChildIt == Node->end()) {
|
||||
Node->DFSNumOut = DFSNum++;
|
||||
WorkStack.pop_back();
|
||||
} else {
|
||||
// Otherwise, recursively visit this child.
|
||||
DomTreeNodeBase<NodeT> *Child = *ChildIt;
|
||||
++WorkStack.back().second;
|
||||
|
||||
WorkStack.push_back(std::make_pair(Child, Child->begin()));
|
||||
Child->DFSNumIn = DFSNum++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -646,21 +659,17 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
|
||||
/// recalculate - compute a dominator tree for the given function
|
||||
template<class FT>
|
||||
void recalculate(FT& F) {
|
||||
if (!this->IsPostDominators) {
|
||||
reset();
|
||||
reset();
|
||||
this->Vertex.push_back(0);
|
||||
|
||||
// Initialize roots
|
||||
if (!this->IsPostDominators) {
|
||||
// Initialize root
|
||||
this->Roots.push_back(&F.front());
|
||||
this->IDoms[&F.front()] = 0;
|
||||
this->DomTreeNodes[&F.front()] = 0;
|
||||
this->Vertex.push_back(0);
|
||||
|
||||
Calculate<FT, NodeT*>(*this, F);
|
||||
|
||||
updateDFSNumbers();
|
||||
} else {
|
||||
reset(); // Reset from the last time we were run...
|
||||
|
||||
// Initialize the roots list
|
||||
for (typename FT::iterator I = F.begin(), E = F.end(); I != E; ++I) {
|
||||
if (std::distance(GraphTraits<FT*>::child_begin(I),
|
||||
@ -672,8 +681,6 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
|
||||
this->DomTreeNodes[I] = 0;
|
||||
}
|
||||
|
||||
this->Vertex.push_back(0);
|
||||
|
||||
Calculate<FT, Inverse<NodeT*> >(*this, F);
|
||||
}
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ class LoopBase {
|
||||
for (iterator I = begin(), E = end(); I != E; ++I)
|
||||
(*I)->print(OS, Depth+2);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
friend class LoopInfoBase<BlockT, LoopT>;
|
||||
explicit LoopBase(BlockT *BB) : ParentLoop(0) {
|
||||
@ -588,6 +588,8 @@ class Loop : public LoopBase<BasicBlock, Loop> {
|
||||
/// block, return that block. Otherwise return null.
|
||||
BasicBlock *getUniqueExitBlock() const;
|
||||
|
||||
void dump() const;
|
||||
|
||||
private:
|
||||
friend class LoopInfoBase<BasicBlock, Loop>;
|
||||
explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {}
|
||||
|
@ -36,19 +36,23 @@ struct PostDominatorTree : public FunctionPass {
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
|
||||
inline const std::vector<BasicBlock*> &getRoots() const {
|
||||
return DT->getRoots();
|
||||
}
|
||||
|
||||
|
||||
inline DomTreeNode *getRootNode() const {
|
||||
return DT->getRootNode();
|
||||
}
|
||||
|
||||
|
||||
inline DomTreeNode *operator[](BasicBlock *BB) const {
|
||||
return DT->getNode(BB);
|
||||
}
|
||||
|
||||
|
||||
inline DomTreeNode *getNode(BasicBlock *BB) const {
|
||||
return DT->getNode(BB);
|
||||
}
|
||||
|
||||
inline bool dominates(DomTreeNode* A, DomTreeNode* B) const {
|
||||
return DT->dominates(A, B);
|
||||
}
|
||||
@ -60,7 +64,7 @@ struct PostDominatorTree : public FunctionPass {
|
||||
inline bool properlyDominates(const DomTreeNode* A, DomTreeNode* B) const {
|
||||
return DT->properlyDominates(A, B);
|
||||
}
|
||||
|
||||
|
||||
inline bool properlyDominates(BasicBlock* A, BasicBlock* B) const {
|
||||
return DT->properlyDominates(A, B);
|
||||
}
|
||||
@ -97,7 +101,7 @@ template <> struct GraphTraits<PostDominatorTree*>
|
||||
///
|
||||
struct PostDominanceFrontier : public DominanceFrontierBase {
|
||||
static char ID;
|
||||
PostDominanceFrontier()
|
||||
PostDominanceFrontier()
|
||||
: DominanceFrontierBase(&ID, true) {}
|
||||
|
||||
virtual bool runOnFunction(Function &) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Attributes.h - Container for Attributes ---*---------- C++ -*-===//
|
||||
//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -27,9 +27,9 @@ typedef unsigned Attributes;
|
||||
|
||||
namespace Attribute {
|
||||
|
||||
/// Function parameters and results can have attributes to indicate how they
|
||||
/// should be treated by optimizations and code generation. This enumeration
|
||||
/// lists the attributes that can be associated with parameters, function
|
||||
/// Function parameters and results can have attributes to indicate how they
|
||||
/// should be treated by optimizations and code generation. This enumeration
|
||||
/// lists the attributes that can be associated with parameters, function
|
||||
/// results or the function itself.
|
||||
/// @brief Function attributes.
|
||||
|
||||
@ -45,7 +45,7 @@ const Attributes ByVal = 1<<7; ///< Pass structure by value
|
||||
const Attributes Nest = 1<<8; ///< Nested function static chain
|
||||
const Attributes ReadNone = 1<<9; ///< Function does not access memory
|
||||
const Attributes ReadOnly = 1<<10; ///< Function only reads from memory
|
||||
const Attributes NoInline = 1<<11; ///< inline=never
|
||||
const Attributes NoInline = 1<<11; ///< inline=never
|
||||
const Attributes AlwaysInline = 1<<12; ///< inline=always
|
||||
const Attributes OptimizeForSize = 1<<13; ///< opt_size
|
||||
const Attributes StackProtect = 1<<14; ///< Stack protection.
|
||||
@ -58,14 +58,15 @@ const Attributes NoRedZone = 1<<22; /// disable redzone
|
||||
const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
|
||||
/// instructions.
|
||||
const Attributes Naked = 1<<24; ///< Naked function
|
||||
const Attributes InlineHint = 1<<25; ///< source said inlining was desirable
|
||||
const Attributes InlineHint = 1<<25; ///< source said inlining was
|
||||
///desirable
|
||||
|
||||
/// @brief Attributes that only apply to function parameters.
|
||||
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
||||
|
||||
/// @brief Attributes that may be applied to the function itself. These cannot
|
||||
/// be used on return values or function parameters.
|
||||
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
||||
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
||||
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
|
||||
NoRedZone | NoImplicitFloat | Naked | InlineHint;
|
||||
|
||||
@ -100,26 +101,26 @@ inline unsigned getAlignmentFromAttrs(Attributes A) {
|
||||
Attributes Align = A & Attribute::Alignment;
|
||||
if (Align == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
return 1U << ((Align >> 16) - 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// The set of Attributes set in Attributes is converted to a
|
||||
/// string of equivalent mnemonics. This is, presumably, for writing out
|
||||
/// the mnemonics for the assembly writer.
|
||||
/// the mnemonics for the assembly writer.
|
||||
/// @brief Convert attribute bits to text
|
||||
std::string getAsString(Attributes Attrs);
|
||||
} // end namespace Attribute
|
||||
|
||||
/// This is just a pair of values to associate a set of attributes
|
||||
/// with an index.
|
||||
/// with an index.
|
||||
struct AttributeWithIndex {
|
||||
Attributes Attrs; ///< The attributes that are set, or'd together.
|
||||
unsigned Index; ///< Index of the parameter for which the attributes apply.
|
||||
///< Index 0 is used for return value attributes.
|
||||
///< Index ~0U is used for function attributes.
|
||||
|
||||
|
||||
static AttributeWithIndex get(unsigned Idx, Attributes Attrs) {
|
||||
AttributeWithIndex P;
|
||||
P.Index = Idx;
|
||||
@ -127,14 +128,14 @@ struct AttributeWithIndex {
|
||||
return P;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// AttrListPtr Smart Pointer
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class AttributeListImpl;
|
||||
|
||||
/// AttrListPtr - This class manages the ref count for the opaque
|
||||
|
||||
/// AttrListPtr - This class manages the ref count for the opaque
|
||||
/// AttributeListImpl object and provides accessors for it.
|
||||
class AttrListPtr {
|
||||
/// AttrList - The attributes that we are managing. This can be null
|
||||
@ -145,14 +146,14 @@ class AttrListPtr {
|
||||
AttrListPtr(const AttrListPtr &P);
|
||||
const AttrListPtr &operator=(const AttrListPtr &RHS);
|
||||
~AttrListPtr();
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Attribute List Construction and Mutation
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/// get - Return a Attributes list with the specified parameter in it.
|
||||
static AttrListPtr get(const AttributeWithIndex *Attr, unsigned NumAttrs);
|
||||
|
||||
|
||||
/// get - Return a Attribute list with the parameters specified by the
|
||||
/// consecutive random access iterator range.
|
||||
template <typename Iter>
|
||||
@ -165,24 +166,24 @@ class AttrListPtr {
|
||||
/// attribute list. Since attribute lists are immutable, this
|
||||
/// returns the new list.
|
||||
AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const;
|
||||
|
||||
|
||||
/// removeAttr - Remove the specified attribute at the specified index from
|
||||
/// this attribute list. Since attribute lists are immutable, this
|
||||
/// returns the new list.
|
||||
AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const;
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Attribute List Accessors
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// getParamAttributes - The attributes for the specified index are
|
||||
/// returned.
|
||||
/// returned.
|
||||
Attributes getParamAttributes(unsigned Idx) const {
|
||||
assert (Idx && Idx != ~0U && "Invalid parameter index!");
|
||||
return getAttributes(Idx);
|
||||
}
|
||||
|
||||
/// getRetAttributes - The attributes for the ret value are
|
||||
/// returned.
|
||||
/// returned.
|
||||
Attributes getRetAttributes() const {
|
||||
return getAttributes(0);
|
||||
}
|
||||
@ -191,58 +192,60 @@ class AttrListPtr {
|
||||
Attributes getFnAttributes() const {
|
||||
return getAttributes(~0U);
|
||||
}
|
||||
|
||||
|
||||
/// paramHasAttr - Return true if the specified parameter index has the
|
||||
/// specified attribute set.
|
||||
bool paramHasAttr(unsigned Idx, Attributes Attr) const {
|
||||
return getAttributes(Idx) & Attr;
|
||||
}
|
||||
|
||||
|
||||
/// getParamAlignment - Return the alignment for the specified function
|
||||
/// parameter.
|
||||
unsigned getParamAlignment(unsigned Idx) const {
|
||||
return Attribute::getAlignmentFromAttrs(getAttributes(Idx));
|
||||
}
|
||||
|
||||
|
||||
/// hasAttrSomewhere - Return true if the specified attribute is set for at
|
||||
/// least one parameter or for the return value.
|
||||
bool hasAttrSomewhere(Attributes Attr) const;
|
||||
|
||||
/// operator==/!= - Provide equality predicates.
|
||||
bool operator==(const AttrListPtr &RHS) const { return AttrList == RHS.AttrList; }
|
||||
bool operator!=(const AttrListPtr &RHS) const { return AttrList != RHS.AttrList; }
|
||||
|
||||
bool operator==(const AttrListPtr &RHS) const
|
||||
{ return AttrList == RHS.AttrList; }
|
||||
bool operator!=(const AttrListPtr &RHS) const
|
||||
{ return AttrList != RHS.AttrList; }
|
||||
|
||||
void dump() const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Attribute List Introspection
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/// getRawPointer - Return a raw pointer that uniquely identifies this
|
||||
/// attribute list.
|
||||
/// attribute list.
|
||||
void *getRawPointer() const {
|
||||
return AttrList;
|
||||
}
|
||||
|
||||
|
||||
// Attributes are stored as a dense set of slots, where there is one
|
||||
// slot for each argument that has an attribute. This allows walking over the
|
||||
// dense set instead of walking the sparse list of attributes.
|
||||
|
||||
|
||||
/// isEmpty - Return true if there are no attributes.
|
||||
///
|
||||
bool isEmpty() const {
|
||||
return AttrList == 0;
|
||||
}
|
||||
|
||||
/// getNumSlots - Return the number of slots used in this attribute list.
|
||||
|
||||
/// getNumSlots - Return the number of slots used in this attribute list.
|
||||
/// This is the number of arguments that have an attribute set on them
|
||||
/// (including the function itself).
|
||||
unsigned getNumSlots() const;
|
||||
|
||||
|
||||
/// getSlot - Return the AttributeWithIndex at the specified slot. This
|
||||
/// holds a index number plus a set of attributes.
|
||||
const AttributeWithIndex &getSlot(unsigned Slot) const;
|
||||
|
||||
|
||||
private:
|
||||
explicit AttrListPtr(AttributeListImpl *L);
|
||||
|
||||
|
@ -111,10 +111,11 @@ namespace bitc {
|
||||
enum MetadataCodes {
|
||||
METADATA_STRING = 1, // MDSTRING: [values]
|
||||
METADATA_NODE = 2, // MDNODE: [n x (type num, value num)]
|
||||
METADATA_NAME = 3, // STRING: [values]
|
||||
METADATA_NAMED_NODE = 4, // NAMEDMDNODE: [n x mdnodes]
|
||||
METADATA_KIND = 5, // [n x [id, name]]
|
||||
METADATA_ATTACHMENT = 6 // [m x [value, [n x [id, mdnode]]]
|
||||
METADATA_FN_NODE = 3, // FN_MDNODE: [n x (type num, value num)]
|
||||
METADATA_NAME = 4, // STRING: [values]
|
||||
METADATA_NAMED_NODE = 5, // NAMEDMDNODE: [n x mdnodes]
|
||||
METADATA_KIND = 6, // [n x [id, name]]
|
||||
METADATA_ATTACHMENT = 7 // [m x [value, [n x [id, mdnode]]]
|
||||
};
|
||||
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
|
||||
// constant and maintains an implicit current type value.
|
||||
|
@ -109,7 +109,7 @@ void SelectRoot(SelectionDAG &DAG) {
|
||||
#if 0
|
||||
DAG.setSubgraphColor(Node, "red");
|
||||
#endif
|
||||
SDNode *ResNode = Select(SDValue(Node, 0));
|
||||
SDNode *ResNode = Select(Node);
|
||||
// If node should not be replaced, continue with the next one.
|
||||
if (ResNode == Node)
|
||||
continue;
|
||||
|
@ -139,7 +139,7 @@ class FastISel {
|
||||
/// be emitted.
|
||||
virtual unsigned FastEmit_(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode);
|
||||
unsigned Opcode);
|
||||
|
||||
/// FastEmit_r - This method is called by target-independent code
|
||||
/// to request that an instruction with the given type, opcode, and
|
||||
@ -147,7 +147,7 @@ class FastISel {
|
||||
///
|
||||
virtual unsigned FastEmit_r(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode, unsigned Op0);
|
||||
unsigned Opcode, unsigned Op0);
|
||||
|
||||
/// FastEmit_rr - This method is called by target-independent code
|
||||
/// to request that an instruction with the given type, opcode, and
|
||||
@ -155,7 +155,7 @@ class FastISel {
|
||||
///
|
||||
virtual unsigned FastEmit_rr(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, unsigned Op1);
|
||||
|
||||
/// FastEmit_ri - This method is called by target-independent code
|
||||
@ -164,7 +164,7 @@ class FastISel {
|
||||
///
|
||||
virtual unsigned FastEmit_ri(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, uint64_t Imm);
|
||||
|
||||
/// FastEmit_rf - This method is called by target-independent code
|
||||
@ -173,7 +173,7 @@ class FastISel {
|
||||
///
|
||||
virtual unsigned FastEmit_rf(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, ConstantFP *FPImm);
|
||||
|
||||
/// FastEmit_rri - This method is called by target-independent code
|
||||
@ -182,7 +182,7 @@ class FastISel {
|
||||
///
|
||||
virtual unsigned FastEmit_rri(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, unsigned Op1, uint64_t Imm);
|
||||
|
||||
/// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries
|
||||
@ -190,7 +190,7 @@ class FastISel {
|
||||
/// If that fails, it materializes the immediate into a register and try
|
||||
/// FastEmit_rr instead.
|
||||
unsigned FastEmit_ri_(MVT VT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, uint64_t Imm,
|
||||
MVT ImmType);
|
||||
|
||||
@ -199,7 +199,7 @@ class FastISel {
|
||||
/// If that fails, it materializes the immediate into a register and try
|
||||
/// FastEmit_rr instead.
|
||||
unsigned FastEmit_rf_(MVT VT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, ConstantFP *FPImm,
|
||||
MVT ImmType);
|
||||
|
||||
@ -208,7 +208,7 @@ class FastISel {
|
||||
/// immediate operand be emitted.
|
||||
virtual unsigned FastEmit_i(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
uint64_t Imm);
|
||||
|
||||
/// FastEmit_f - This method is called by target-independent code
|
||||
@ -216,7 +216,7 @@ class FastISel {
|
||||
/// floating-point immediate operand be emitted.
|
||||
virtual unsigned FastEmit_f(MVT VT,
|
||||
MVT RetVT,
|
||||
ISD::NodeType Opcode,
|
||||
unsigned Opcode,
|
||||
ConstantFP *FPImm);
|
||||
|
||||
/// FastEmitInst_ - Emit a MachineInstr with no operands and a
|
||||
@ -298,7 +298,7 @@ class FastISel {
|
||||
}
|
||||
|
||||
private:
|
||||
bool SelectBinaryOp(User *I, ISD::NodeType ISDOpcode);
|
||||
bool SelectBinaryOp(User *I, unsigned ISDOpcode);
|
||||
|
||||
bool SelectFNeg(User *I);
|
||||
|
||||
@ -308,7 +308,7 @@ class FastISel {
|
||||
|
||||
bool SelectBitCast(User *I);
|
||||
|
||||
bool SelectCast(User *I, ISD::NodeType Opcode);
|
||||
bool SelectCast(User *I, unsigned Opcode);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -315,6 +315,8 @@ class MachineFunction {
|
||||
/// 'Orig' instruction, identical in all ways except the the instruction
|
||||
/// has no parent, prev, or next.
|
||||
///
|
||||
/// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned
|
||||
/// instructions.
|
||||
MachineInstr *CloneMachineInstr(const MachineInstr *Orig);
|
||||
|
||||
/// DeleteMachineInstr - Delete the given MachineInstr.
|
||||
|
@ -288,7 +288,7 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
bool addRegisterKilled(unsigned IncomingReg,
|
||||
const TargetRegisterInfo *RegInfo,
|
||||
bool AddIfNotFound = false);
|
||||
|
||||
|
||||
/// addRegisterDead - We have determined MI defined a register without a use.
|
||||
/// Look for the operand that defines it and mark it as IsDead. If
|
||||
/// AddIfNotFound is true, add a implicit operand if it's not found. Returns
|
||||
@ -296,6 +296,11 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
bool addRegisterDead(unsigned IncomingReg, const TargetRegisterInfo *RegInfo,
|
||||
bool AddIfNotFound = false);
|
||||
|
||||
/// addRegisterDefined - We have determined MI defines a register. Make sure
|
||||
/// there is an operand defining Reg.
|
||||
void addRegisterDefined(unsigned IncomingReg,
|
||||
const TargetRegisterInfo *RegInfo);
|
||||
|
||||
/// isSafeToMove - Return true if it is safe to move this instruction. If
|
||||
/// SawStore is set to true, it means that there is a store (or call) between
|
||||
/// the instruction's location and its intended destination.
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace llvm {
|
||||
|
||||
class TargetInstrDesc;
|
||||
class MDNode;
|
||||
|
||||
namespace RegState {
|
||||
enum {
|
||||
@ -123,6 +124,11 @@ class MachineInstrBuilder {
|
||||
MI->addOperand(MO);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addMetadata(MDNode *MD) const {
|
||||
MI->addOperand(MachineOperand::CreateMetadata(MD));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// BuildMI - Builder interface. Specify how to create the initial instruction
|
||||
|
@ -49,6 +49,8 @@ class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
|
||||
/// contiguous with the part the contains the header.
|
||||
MachineBasicBlock *getBottomBlock();
|
||||
|
||||
void dump() const;
|
||||
|
||||
private:
|
||||
friend class LoopInfoBase<MachineBasicBlock, MachineLoop>;
|
||||
explicit MachineLoop(MachineBasicBlock *MBB)
|
||||
|
@ -26,6 +26,7 @@ class GlobalValue;
|
||||
class MachineInstr;
|
||||
class TargetMachine;
|
||||
class MachineRegisterInfo;
|
||||
class MDNode;
|
||||
class raw_ostream;
|
||||
|
||||
/// MachineOperand class - Representation of each machine instruction operand.
|
||||
@ -42,7 +43,8 @@ class MachineOperand {
|
||||
MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
|
||||
MO_ExternalSymbol, ///< Name of external global symbol
|
||||
MO_GlobalAddress, ///< Address of a global value
|
||||
MO_BlockAddress ///< Address of a basic block
|
||||
MO_BlockAddress, ///< Address of a basic block
|
||||
MO_Metadata ///< Metadata reference (for debug info)
|
||||
};
|
||||
|
||||
private:
|
||||
@ -94,6 +96,7 @@ class MachineOperand {
|
||||
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
|
||||
const ConstantFP *CFP; // For MO_FPImmediate.
|
||||
int64_t ImmVal; // For MO_Immediate.
|
||||
MDNode *MD; // For MO_Metadata.
|
||||
|
||||
struct { // For MO_Register.
|
||||
unsigned RegNo;
|
||||
@ -158,6 +161,8 @@ class MachineOperand {
|
||||
bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
|
||||
/// isBlockAddress - Tests if this is a MO_BlockAddress operand.
|
||||
bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
|
||||
/// isMetadata - Tests if this is a MO_Metadata operand.
|
||||
bool isMetadata() const { return OpKind == MO_Metadata; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Accessors for Register Operands
|
||||
@ -311,6 +316,11 @@ class MachineOperand {
|
||||
assert(isSymbol() && "Wrong MachineOperand accessor");
|
||||
return Contents.OffsetedInfo.Val.SymbolName;
|
||||
}
|
||||
|
||||
const MDNode *getMetadata() const {
|
||||
assert(isMetadata() && "Wrong MachineOperand accessor");
|
||||
return Contents.MD;
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Mutators for various operand types.
|
||||
@ -443,6 +453,13 @@ class MachineOperand {
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateMetadata(MDNode *Meta,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_Metadata);
|
||||
Op.Contents.MD = Meta;
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
|
||||
friend class MachineInstr;
|
||||
friend class MachineRegisterInfo;
|
||||
|
@ -170,6 +170,10 @@ namespace llvm {
|
||||
/// instructions.
|
||||
FunctionPass *createMachineSinkingPass();
|
||||
|
||||
/// createOptimizeExtsPass - This pass performs sign / zero extension
|
||||
/// optimization by increasing uses of extended values.
|
||||
FunctionPass *createOptimizeExtsPass();
|
||||
|
||||
/// createStackSlotColoringPass - This pass performs stack slot coloring.
|
||||
FunctionPass *createStackSlotColoringPass(bool);
|
||||
|
||||
|
@ -111,11 +111,11 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
int64_t DesiredMaskS) const;
|
||||
|
||||
// Calls to these functions are generated by tblgen.
|
||||
SDNode *Select_INLINEASM(SDValue N);
|
||||
SDNode *Select_UNDEF(const SDValue &N);
|
||||
SDNode *Select_EH_LABEL(const SDValue &N);
|
||||
void CannotYetSelect(SDValue N);
|
||||
void CannotYetSelectIntrinsic(SDValue N);
|
||||
SDNode *Select_INLINEASM(SDNode *N);
|
||||
SDNode *Select_UNDEF(SDNode *N);
|
||||
SDNode *Select_EH_LABEL(SDNode *N);
|
||||
void CannotYetSelect(SDNode *N);
|
||||
void CannotYetSelectIntrinsic(SDNode *N);
|
||||
|
||||
private:
|
||||
void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
|
||||
@ -131,6 +131,7 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
void CodeGenAndEmitDAG();
|
||||
void LowerArguments(BasicBlock *BB);
|
||||
|
||||
void ShrinkDemandedOps();
|
||||
void ComputeLiveOutVRegInfo();
|
||||
|
||||
void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB);
|
||||
|
@ -149,7 +149,7 @@ namespace llvm {
|
||||
SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
|
||||
}
|
||||
|
||||
/// isPow2VectorType - Retuns true if the given vector is a power of 2.
|
||||
/// isPow2VectorType - Returns true if the given vector is a power of 2.
|
||||
bool isPow2VectorType() const {
|
||||
unsigned NElts = getVectorNumElements();
|
||||
return !(NElts & (NElts - 1));
|
||||
@ -437,25 +437,17 @@ namespace llvm {
|
||||
|
||||
/// isFloatingPoint - Return true if this is a FP, or a vector FP type.
|
||||
bool isFloatingPoint() const {
|
||||
return isSimple() ?
|
||||
((V >= MVT::f32 && V <= MVT::ppcf128) ||
|
||||
(V >= MVT::v2f32 && V <= MVT::v4f64)) : isExtendedFloatingPoint();
|
||||
return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
|
||||
}
|
||||
|
||||
/// isInteger - Return true if this is an integer, or a vector integer type.
|
||||
bool isInteger() const {
|
||||
return isSimple() ?
|
||||
((V >= MVT::FIRST_INTEGER_VALUETYPE &&
|
||||
V <= MVT::LAST_INTEGER_VALUETYPE) ||
|
||||
(V >= MVT::v2i8 && V <= MVT::v4i64)) : isExtendedInteger();
|
||||
return isSimple() ? V.isInteger() : isExtendedInteger();
|
||||
}
|
||||
|
||||
/// isVector - Return true if this is a vector value type.
|
||||
bool isVector() const {
|
||||
return isSimple() ?
|
||||
(V >= MVT::FIRST_VECTOR_VALUETYPE && V <=
|
||||
MVT::LAST_VECTOR_VALUETYPE) :
|
||||
isExtendedVector();
|
||||
return isSimple() ? V.isVector() : isExtendedVector();
|
||||
}
|
||||
|
||||
/// is64BitVector - Return true if this is a 64-bit vector type.
|
||||
@ -641,7 +633,7 @@ namespace llvm {
|
||||
static EVT getEVT(const Type *Ty, bool HandleUnknown = false);
|
||||
|
||||
intptr_t getRawBits() {
|
||||
if (V.SimpleTy <= MVT::LastSimpleValueType)
|
||||
if (isSimple())
|
||||
return V.SimpleTy;
|
||||
else
|
||||
return (intptr_t)(LLVMTy);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define LLVM_INTRINSICINST_H
|
||||
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Metadata.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
@ -58,16 +59,13 @@ namespace llvm {
|
||||
|
||||
/// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
|
||||
///
|
||||
struct DbgInfoIntrinsic : public IntrinsicInst {
|
||||
class DbgInfoIntrinsic : public IntrinsicInst {
|
||||
public:
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const DbgInfoIntrinsic *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
switch (I->getIntrinsicID()) {
|
||||
case Intrinsic::dbg_stoppoint:
|
||||
case Intrinsic::dbg_func_start:
|
||||
case Intrinsic::dbg_region_start:
|
||||
case Intrinsic::dbg_region_end:
|
||||
case Intrinsic::dbg_declare:
|
||||
case Intrinsic::dbg_value:
|
||||
return true;
|
||||
@ -81,84 +79,16 @@ namespace llvm {
|
||||
static Value *StripCast(Value *C);
|
||||
};
|
||||
|
||||
/// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction.
|
||||
///
|
||||
struct DbgStopPointInst : public DbgInfoIntrinsic {
|
||||
Value *getLineValue() const { return const_cast<Value*>(getOperand(1)); }
|
||||
Value *getColumnValue() const { return const_cast<Value*>(getOperand(2)); }
|
||||
MDNode *getContext() const {
|
||||
return cast<MDNode>(getOperand(3));
|
||||
}
|
||||
|
||||
unsigned getLine() const {
|
||||
return unsigned(cast<ConstantInt>(getOperand(1))->getZExtValue());
|
||||
}
|
||||
unsigned getColumn() const {
|
||||
return unsigned(cast<ConstantInt>(getOperand(2))->getZExtValue());
|
||||
}
|
||||
|
||||
Value *getFileName() const;
|
||||
Value *getDirectory() const;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const DbgStopPointInst *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
return I->getIntrinsicID() == Intrinsic::dbg_stoppoint;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
};
|
||||
|
||||
/// DbgFuncStartInst - This represents the llvm.dbg.func.start instruction.
|
||||
///
|
||||
struct DbgFuncStartInst : public DbgInfoIntrinsic {
|
||||
MDNode *getSubprogram() const { return cast<MDNode>(getOperand(1)); }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const DbgFuncStartInst *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
return I->getIntrinsicID() == Intrinsic::dbg_func_start;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
};
|
||||
|
||||
/// DbgRegionStartInst - This represents the llvm.dbg.region.start
|
||||
/// instruction.
|
||||
struct DbgRegionStartInst : public DbgInfoIntrinsic {
|
||||
MDNode *getContext() const { return cast<MDNode>(getOperand(1)); }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const DbgRegionStartInst *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
return I->getIntrinsicID() == Intrinsic::dbg_region_start;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
};
|
||||
|
||||
/// DbgRegionEndInst - This represents the llvm.dbg.region.end instruction.
|
||||
///
|
||||
struct DbgRegionEndInst : public DbgInfoIntrinsic {
|
||||
MDNode *getContext() const { return cast<MDNode>(getOperand(1)); }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const DbgRegionEndInst *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
return I->getIntrinsicID() == Intrinsic::dbg_region_end;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
};
|
||||
|
||||
/// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
|
||||
///
|
||||
struct DbgDeclareInst : public DbgInfoIntrinsic {
|
||||
Value *getAddress() const { return getOperand(1); }
|
||||
class DbgDeclareInst : public DbgInfoIntrinsic {
|
||||
public:
|
||||
Value *getAddress() const {
|
||||
if (MDNode* MD = dyn_cast<MDNode>(getOperand(1)))
|
||||
return MD->getOperand(0);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
MDNode *getVariable() const { return cast<MDNode>(getOperand(2)); }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
@ -173,10 +103,16 @@ namespace llvm {
|
||||
|
||||
/// DbgValueInst - This represents the llvm.dbg.value instruction.
|
||||
///
|
||||
struct DbgValueInst : public DbgInfoIntrinsic {
|
||||
Value *getValue() const;
|
||||
Value *getOffset() const { return getOperand(2); }
|
||||
MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); }
|
||||
class DbgValueInst : public DbgInfoIntrinsic {
|
||||
public:
|
||||
const Value *getValue() const;
|
||||
Value *getValue();
|
||||
uint64_t getOffset() const {
|
||||
return cast<ConstantInt>(
|
||||
const_cast<Value*>(getOperand(2)))->getZExtValue();
|
||||
}
|
||||
const MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); }
|
||||
MDNode *getVariable() { return cast<MDNode>(getOperand(3)); }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const DbgValueInst *) { return true; }
|
||||
@ -190,7 +126,8 @@ namespace llvm {
|
||||
|
||||
/// MemIntrinsic - This is the common base class for memset/memcpy/memmove.
|
||||
///
|
||||
struct MemIntrinsic : public IntrinsicInst {
|
||||
class MemIntrinsic : public IntrinsicInst {
|
||||
public:
|
||||
Value *getRawDest() const { return const_cast<Value*>(getOperand(1)); }
|
||||
|
||||
Value *getLength() const { return const_cast<Value*>(getOperand(3)); }
|
||||
@ -247,7 +184,8 @@ namespace llvm {
|
||||
|
||||
/// MemSetInst - This class wraps the llvm.memset intrinsic.
|
||||
///
|
||||
struct MemSetInst : public MemIntrinsic {
|
||||
class MemSetInst : public MemIntrinsic {
|
||||
public:
|
||||
/// get* - Return the arguments to the instruction.
|
||||
///
|
||||
Value *getValue() const { return const_cast<Value*>(getOperand(2)); }
|
||||
@ -270,7 +208,8 @@ namespace llvm {
|
||||
|
||||
/// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics.
|
||||
///
|
||||
struct MemTransferInst : public MemIntrinsic {
|
||||
class MemTransferInst : public MemIntrinsic {
|
||||
public:
|
||||
/// get* - Return the arguments to the instruction.
|
||||
///
|
||||
Value *getRawSource() const { return const_cast<Value*>(getOperand(2)); }
|
||||
@ -300,7 +239,8 @@ namespace llvm {
|
||||
|
||||
/// MemCpyInst - This class wraps the llvm.memcpy intrinsic.
|
||||
///
|
||||
struct MemCpyInst : public MemTransferInst {
|
||||
class MemCpyInst : public MemTransferInst {
|
||||
public:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const MemCpyInst *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
@ -313,7 +253,8 @@ namespace llvm {
|
||||
|
||||
/// MemMoveInst - This class wraps the llvm.memmove intrinsic.
|
||||
///
|
||||
struct MemMoveInst : public MemTransferInst {
|
||||
class MemMoveInst : public MemTransferInst {
|
||||
public:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const MemMoveInst *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
@ -326,7 +267,8 @@ namespace llvm {
|
||||
|
||||
/// EHSelectorInst - This represents the llvm.eh.selector instruction.
|
||||
///
|
||||
struct EHSelectorInst : public IntrinsicInst {
|
||||
class EHSelectorInst : public IntrinsicInst {
|
||||
public:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const EHSelectorInst *) { return true; }
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
@ -340,7 +282,8 @@ namespace llvm {
|
||||
/// MemoryUseIntrinsic - This is the common base class for the memory use
|
||||
/// marker intrinsics.
|
||||
///
|
||||
struct MemoryUseIntrinsic : public IntrinsicInst {
|
||||
class MemoryUseIntrinsic : public IntrinsicInst {
|
||||
public:
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const MemoryUseIntrinsic *) { return true; }
|
||||
|
@ -282,14 +282,8 @@ let Properties = [IntrNoMem] in {
|
||||
// optimizers can change them aggressively. Special handling needed in a few
|
||||
// places.
|
||||
let Properties = [IntrNoMem] in {
|
||||
def int_dbg_stoppoint : Intrinsic<[llvm_void_ty],
|
||||
[llvm_i32_ty, llvm_i32_ty,
|
||||
llvm_metadata_ty]>;
|
||||
def int_dbg_region_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>;
|
||||
def int_dbg_region_end : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>;
|
||||
def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>;
|
||||
def int_dbg_declare : Intrinsic<[llvm_void_ty],
|
||||
[llvm_descriptor_ty, llvm_metadata_ty]>;
|
||||
[llvm_metadata_ty, llvm_metadata_ty]>;
|
||||
def int_dbg_value : Intrinsic<[llvm_void_ty],
|
||||
[llvm_metadata_ty, llvm_i64_ty,
|
||||
llvm_metadata_ty]>;
|
||||
|
@ -53,7 +53,6 @@ namespace {
|
||||
(void) llvm::createLibCallAliasAnalysisPass(0);
|
||||
(void) llvm::createScalarEvolutionAliasAnalysisPass();
|
||||
(void) llvm::createBlockPlacementPass();
|
||||
(void) llvm::createBlockProfilerPass();
|
||||
(void) llvm::createBreakCriticalEdgesPass();
|
||||
(void) llvm::createCFGSimplificationPass();
|
||||
(void) llvm::createConstantMergePass();
|
||||
@ -71,7 +70,6 @@ namespace {
|
||||
(void) llvm::createOptimalEdgeProfilerPass();
|
||||
(void) llvm::createFunctionInliningPass();
|
||||
(void) llvm::createAlwaysInlinerPass();
|
||||
(void) llvm::createFunctionProfilerPass();
|
||||
(void) llvm::createGlobalDCEPass();
|
||||
(void) llvm::createGlobalOptimizerPass();
|
||||
(void) llvm::createGlobalsModRefPass();
|
||||
@ -120,8 +118,6 @@ namespace {
|
||||
(void) llvm::createTailDuplicationPass();
|
||||
(void) llvm::createJumpThreadingPass();
|
||||
(void) llvm::createUnifyFunctionExitNodesPass();
|
||||
(void) llvm::createNullProfilerRSPass();
|
||||
(void) llvm::createRSProfilingPass();
|
||||
(void) llvm::createInstCountPass();
|
||||
(void) llvm::createCodeGenPreparePass();
|
||||
(void) llvm::createGVNPass();
|
||||
|
@ -20,7 +20,8 @@ class SMLoc;
|
||||
class Target;
|
||||
|
||||
/// AsmToken - Target independent representation for an assembler token.
|
||||
struct AsmToken {
|
||||
class AsmToken {
|
||||
public:
|
||||
enum TokenKind {
|
||||
// Markers
|
||||
Eof, Error,
|
||||
|
33
include/llvm/MC/MCParsedAsmOperand.h
Normal file
33
include/llvm/MC/MCParsedAsmOperand.h
Normal file
@ -0,0 +1,33 @@
|
||||
//===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCASMOPERAND_H
|
||||
#define LLVM_MC_MCASMOPERAND_H
|
||||
|
||||
namespace llvm {
|
||||
class SMLoc;
|
||||
|
||||
/// MCParsedAsmOperand - This abstract class represents a source-level assembly
|
||||
/// instruction operand. It should be subclassed by target-specific code. This
|
||||
/// base class is used by target-independent clients and is the interface
|
||||
/// between parsing an asm instruction and recognizing it.
|
||||
class MCParsedAsmOperand {
|
||||
public:
|
||||
MCParsedAsmOperand() {}
|
||||
virtual ~MCParsedAsmOperand() {}
|
||||
|
||||
/// getStartLoc - Get the location of the first token of this operand.
|
||||
virtual SMLoc getStartLoc() const;
|
||||
/// getEndLoc - Get the location of the last token of this operand.
|
||||
virtual SMLoc getEndLoc() const;
|
||||
};
|
||||
|
||||
} // end namespace llvm.
|
||||
|
||||
#endif
|
@ -136,6 +136,11 @@ namespace llvm {
|
||||
|
||||
/// dump - Print the value to stderr.
|
||||
void dump() const;
|
||||
|
||||
/// printMangledName - Print the specified string in mangled form if it uses
|
||||
/// any unusual characters.
|
||||
static void printMangledName(StringRef Str, raw_ostream &OS,
|
||||
const MCAsmInfo *MAI);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -31,7 +31,7 @@ template<typename ValueSubClass, typename ItemParentClass>
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MetadataBase - A base class for MDNode, MDString and NamedMDNode.
|
||||
// MetadataBase - A base class for MDNode and MDString.
|
||||
class MetadataBase : public Value {
|
||||
protected:
|
||||
MetadataBase(const Type *Ty, unsigned scid)
|
||||
@ -42,8 +42,7 @@ class MetadataBase : public Value {
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const MetadataBase *) { return true; }
|
||||
static bool classof(const Value *V) {
|
||||
return V->getValueID() == MDStringVal || V->getValueID() == MDNodeVal
|
||||
|| V->getValueID() == NamedMDNodeVal;
|
||||
return V->getValueID() == MDStringVal || V->getValueID() == MDNodeVal;
|
||||
}
|
||||
};
|
||||
|
||||
@ -113,6 +112,13 @@ class MDNode : public MetadataBase, public FoldingSetNode {
|
||||
DestroyFlag = 1 << 2
|
||||
};
|
||||
|
||||
// FunctionLocal enums.
|
||||
enum FunctionLocalness {
|
||||
FL_Unknown = -1,
|
||||
FL_No = 0,
|
||||
FL_Yes = 1
|
||||
};
|
||||
|
||||
// Replace each instance of F from the operand list of this node with T.
|
||||
void replaceOperand(MDNodeOperand *Op, Value *NewVal);
|
||||
~MDNode();
|
||||
@ -120,10 +126,17 @@ class MDNode : public MetadataBase, public FoldingSetNode {
|
||||
protected:
|
||||
explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
|
||||
bool isFunctionLocal);
|
||||
|
||||
static MDNode *getMDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
|
||||
FunctionLocalness FL);
|
||||
public:
|
||||
// Constructors and destructors.
|
||||
static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals,
|
||||
bool isFunctionLocal = false);
|
||||
static MDNode *get(LLVMContext &Context, Value *const *Vals,
|
||||
unsigned NumVals);
|
||||
// getWhenValsUnresolved - Construct MDNode determining function-localness
|
||||
// from isFunctionLocal argument, not by analyzing Vals.
|
||||
static MDNode *getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals,
|
||||
unsigned NumVals, bool isFunctionLocal);
|
||||
|
||||
/// getOperand - Return specified operand.
|
||||
Value *getOperand(unsigned i) const;
|
||||
@ -138,6 +151,11 @@ class MDNode : public MetadataBase, public FoldingSetNode {
|
||||
bool isFunctionLocal() const {
|
||||
return (getSubclassDataFromValue() & FunctionLocalBit) != 0;
|
||||
}
|
||||
|
||||
// getFunction - If this metadata is function-local and recursively has a
|
||||
// function-local operand, return the first such operand's parent function.
|
||||
// Otherwise, return null.
|
||||
Function *getFunction() const;
|
||||
|
||||
// destroy - Delete this node. Only when there are no uses.
|
||||
void destroy();
|
||||
@ -167,24 +185,25 @@ class MDNode : public MetadataBase, public FoldingSetNode {
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// NamedMDNode - a tuple of other metadata.
|
||||
/// NamedMDNode - a tuple of MDNodes.
|
||||
/// NamedMDNode is always named. All NamedMDNode operand has a type of metadata.
|
||||
class NamedMDNode : public MetadataBase, public ilist_node<NamedMDNode> {
|
||||
class NamedMDNode : public Value, public ilist_node<NamedMDNode> {
|
||||
friend class SymbolTableListTraits<NamedMDNode, Module>;
|
||||
friend struct ilist_traits<NamedMDNode>;
|
||||
friend class LLVMContextImpl;
|
||||
|
||||
NamedMDNode(const NamedMDNode &); // DO NOT IMPLEMENT
|
||||
|
||||
std::string Name;
|
||||
Module *Parent;
|
||||
void *Operands; // SmallVector<TrackingVH<MetadataBase>, 4>
|
||||
void *Operands; // SmallVector<WeakVH<MDNode>, 4>
|
||||
|
||||
void setParent(Module *M) { Parent = M; }
|
||||
protected:
|
||||
explicit NamedMDNode(LLVMContext &C, const Twine &N, MetadataBase*const *Vals,
|
||||
explicit NamedMDNode(LLVMContext &C, const Twine &N, MDNode*const *Vals,
|
||||
unsigned NumVals, Module *M = 0);
|
||||
public:
|
||||
static NamedMDNode *Create(LLVMContext &C, const Twine &N,
|
||||
MetadataBase *const *MDs,
|
||||
static NamedMDNode *Create(LLVMContext &C, const Twine &N,
|
||||
MDNode *const *MDs,
|
||||
unsigned NumMDs, Module *M = 0) {
|
||||
return new NamedMDNode(C, N, MDs, NumMDs, M);
|
||||
}
|
||||
@ -206,14 +225,20 @@ class NamedMDNode : public MetadataBase, public ilist_node<NamedMDNode> {
|
||||
inline const Module *getParent() const { return Parent; }
|
||||
|
||||
/// getOperand - Return specified operand.
|
||||
MetadataBase *getOperand(unsigned i) const;
|
||||
MDNode *getOperand(unsigned i) const;
|
||||
|
||||
/// getNumOperands - Return the number of NamedMDNode operands.
|
||||
unsigned getNumOperands() const;
|
||||
|
||||
/// addOperand - Add metadata operand.
|
||||
void addOperand(MetadataBase *M);
|
||||
|
||||
void addOperand(MDNode *M);
|
||||
|
||||
/// setName - Set the name of this named metadata.
|
||||
void setName(const Twine &NewName);
|
||||
|
||||
/// getName - Return a constant reference to this named metadata's name.
|
||||
StringRef getName() const;
|
||||
|
||||
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const NamedMDNode *) { return true; }
|
||||
static bool classof(const Value *V) {
|
||||
|
@ -26,6 +26,7 @@ namespace llvm {
|
||||
|
||||
class FunctionType;
|
||||
class LLVMContext;
|
||||
class MDSymbolTable;
|
||||
|
||||
template<> struct ilist_traits<Function>
|
||||
: public SymbolTableListTraits<Function, Module> {
|
||||
@ -56,6 +57,7 @@ template<> struct ilist_traits<GlobalAlias>
|
||||
static GlobalAlias *createSentinel();
|
||||
static void destroySentinel(GlobalAlias *GA) { delete GA; }
|
||||
};
|
||||
|
||||
template<> struct ilist_traits<NamedMDNode>
|
||||
: public SymbolTableListTraits<NamedMDNode, Module> {
|
||||
// createSentinel is used to get hold of a node that marks the end of
|
||||
@ -68,6 +70,8 @@ template<> struct ilist_traits<NamedMDNode>
|
||||
NamedMDNode *provideInitialHead() const { return createSentinel(); }
|
||||
NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); }
|
||||
static void noteHead(NamedMDNode*, NamedMDNode*) {}
|
||||
void addNodeToList(NamedMDNode *N);
|
||||
void removeNodeFromList(NamedMDNode *N);
|
||||
private:
|
||||
mutable ilist_node<NamedMDNode> Sentinel;
|
||||
};
|
||||
@ -131,19 +135,20 @@ class Module {
|
||||
/// @name Member Variables
|
||||
/// @{
|
||||
private:
|
||||
LLVMContext &Context; ///< The LLVMContext from which types and
|
||||
///< constants are allocated.
|
||||
GlobalListType GlobalList; ///< The Global Variables in the module
|
||||
FunctionListType FunctionList; ///< The Functions in the module
|
||||
AliasListType AliasList; ///< The Aliases in the module
|
||||
LibraryListType LibraryList; ///< The Libraries needed by the module
|
||||
NamedMDListType NamedMDList; ///< The named metadata in the module
|
||||
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
|
||||
ValueSymbolTable *ValSymTab; ///< Symbol table for values
|
||||
TypeSymbolTable *TypeSymTab; ///< Symbol table for types
|
||||
std::string ModuleID; ///< Human readable identifier for the module
|
||||
std::string TargetTriple; ///< Platform target triple Module compiled on
|
||||
std::string DataLayout; ///< Target data description
|
||||
LLVMContext &Context; ///< The LLVMContext from which types and
|
||||
///< constants are allocated.
|
||||
GlobalListType GlobalList; ///< The Global Variables in the module
|
||||
FunctionListType FunctionList; ///< The Functions in the module
|
||||
AliasListType AliasList; ///< The Aliases in the module
|
||||
LibraryListType LibraryList; ///< The Libraries needed by the module
|
||||
NamedMDListType NamedMDList; ///< The named metadata in the module
|
||||
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
|
||||
ValueSymbolTable *ValSymTab; ///< Symbol table for values
|
||||
TypeSymbolTable *TypeSymTab; ///< Symbol table for types
|
||||
std::string ModuleID; ///< Human readable identifier for the module
|
||||
std::string TargetTriple; ///< Platform target triple Module compiled on
|
||||
std::string DataLayout; ///< Target data description
|
||||
MDSymbolTable *NamedMDSymTab; ///< NamedMDNode names.
|
||||
|
||||
friend class Constant;
|
||||
|
||||
@ -379,6 +384,10 @@ class Module {
|
||||
const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; }
|
||||
/// Get the Module's symbol table of types
|
||||
TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; }
|
||||
/// Get the symbol table of named metadata
|
||||
const MDSymbolTable &getMDSymbolTable() const { return *NamedMDSymTab; }
|
||||
/// Get the Module's symbol table of named metadata
|
||||
MDSymbolTable &getMDSymbolTable() { return *NamedMDSymTab; }
|
||||
|
||||
/// @}
|
||||
/// @name Global Variable Iteration
|
||||
|
@ -93,7 +93,7 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
public:
|
||||
typedef SuccIterator<Term_, BB_> _Self;
|
||||
typedef typename super::pointer pointer;
|
||||
// TODO: This can be random access iterator, need operator+ and stuff tho
|
||||
// TODO: This can be random access iterator, only operator[] missing.
|
||||
|
||||
inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator
|
||||
assert(T && "getTerminator returned null!");
|
||||
@ -109,6 +109,10 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool index_is_valid (int idx) {
|
||||
return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
|
||||
}
|
||||
|
||||
/// getSuccessorIndex - This is used to interface between code that wants to
|
||||
/// operate on terminator instructions directly.
|
||||
unsigned getSuccessorIndex() const { return idx; }
|
||||
@ -120,6 +124,7 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
inline pointer operator->() const { return operator*(); }
|
||||
|
||||
inline _Self& operator++() { ++idx; return *this; } // Preincrement
|
||||
|
||||
inline _Self operator++(int) { // Postincrement
|
||||
_Self tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
@ -128,6 +133,67 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
inline _Self operator--(int) { // Postdecrement
|
||||
_Self tmp = *this; --*this; return tmp;
|
||||
}
|
||||
|
||||
inline bool operator<(const _Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx < x.idx;
|
||||
}
|
||||
|
||||
inline bool operator<=(const _Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx <= x.idx;
|
||||
}
|
||||
inline bool operator>=(const _Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx >= x.idx;
|
||||
}
|
||||
|
||||
inline bool operator>(const _Self& x) const {
|
||||
return idx > x.idx;
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
}
|
||||
|
||||
inline _Self& operator+=(int Right) {
|
||||
unsigned new_idx = idx + Right;
|
||||
assert(index_is_valid(new_idx) && "Iterator index out of bound");
|
||||
idx = new_idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline _Self operator+(int Right) {
|
||||
_Self tmp = *this;
|
||||
tmp += Right;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline _Self& operator-=(int Right) {
|
||||
return operator+=(-Right);
|
||||
}
|
||||
|
||||
inline _Self operator-(int Right) {
|
||||
return operator+(-Right);
|
||||
}
|
||||
|
||||
inline int operator-(const _Self& x) {
|
||||
assert(Term == x.Term && "Cannot work on iterators of different blocks!");
|
||||
int distance = idx - x.idx;
|
||||
return distance;
|
||||
}
|
||||
|
||||
// This works for read access, however write access is difficult as changes
|
||||
// to Term are only possible with Term->setSuccessor(idx). Pointers that can
|
||||
// be modified are not available.
|
||||
//
|
||||
// inline pointer operator[](int offset) {
|
||||
// _Self tmp = *this;
|
||||
// tmp += offset;
|
||||
// return tmp.operator*();
|
||||
// }
|
||||
|
||||
/// Get the source BB of this iterator.
|
||||
inline BB_ *getSource() {
|
||||
return Term->getParent();
|
||||
}
|
||||
};
|
||||
|
||||
typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
|
||||
|
@ -144,6 +144,10 @@ formatted_raw_ostream &fouts();
|
||||
/// standard error. Use it like: ferrs() << "foo" << "bar";
|
||||
formatted_raw_ostream &ferrs();
|
||||
|
||||
/// fdbgs() - This returns a reference to a formatted_raw_ostream for
|
||||
/// debug output. Use it like: fdbgs() << "foo" << "bar";
|
||||
formatted_raw_ostream &fdbgs();
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class Twine;
|
||||
class Type;
|
||||
class Module;
|
||||
class Value;
|
||||
@ -101,9 +102,25 @@ class Mangler {
|
||||
/// specified suffix. If 'ForcePrivate' is specified, the label is specified
|
||||
/// to have a private label prefix.
|
||||
///
|
||||
/// FIXME: This is deprecated, new code should use getNameWithPrefix and use
|
||||
/// MCSymbol printing to handle quotes or not etc.
|
||||
///
|
||||
std::string getMangledName(const GlobalValue *V, const char *Suffix = "",
|
||||
bool ForcePrivate = false);
|
||||
|
||||
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
|
||||
/// and the specified global variable's name. If the global variable doesn't
|
||||
/// have a name, this fills in a unique name for the global.
|
||||
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
|
||||
bool isImplicitlyPrivate);
|
||||
|
||||
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
|
||||
/// and the specified name as the global variable name. GVName must not be
|
||||
/// empty.
|
||||
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
|
||||
ManglerPrefixTy PrefixTy = Mangler::Default);
|
||||
|
||||
private:
|
||||
/// makeNameProper - We don't want identifier names with ., space, or
|
||||
/// - in them, so we mangle these characters into the strings "d_",
|
||||
/// "s_", and "D_", respectively. This is a very simple mangling that
|
||||
@ -111,14 +128,13 @@ class Mangler {
|
||||
/// does this for you, so there's no point calling it on the result
|
||||
/// from getValueName.
|
||||
///
|
||||
std::string makeNameProper(const std::string &x,
|
||||
ManglerPrefixTy PrefixTy = Mangler::Default);
|
||||
/// FIXME: This is deprecated, new code should use getNameWithPrefix and use
|
||||
/// MCSymbol printing to handle quotes or not etc.
|
||||
///
|
||||
void makeNameProper(SmallVectorImpl<char> &OutName,
|
||||
const Twine &Name,
|
||||
ManglerPrefixTy PrefixTy = Mangler::Default);
|
||||
|
||||
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
|
||||
/// and the specified global variable's name. If the global variable doesn't
|
||||
/// have a name, this fills in a unique name for the global.
|
||||
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
|
||||
bool isImplicitlyPrivate);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -160,7 +160,7 @@ inline unsigned CountLeadingZeros_32(uint32_t Value) {
|
||||
#else
|
||||
if (!Value) return 32;
|
||||
Count = 0;
|
||||
// bisecton method for count leading zeros
|
||||
// bisection method for count leading zeros
|
||||
for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) {
|
||||
uint32_t Tmp = Value >> Shift;
|
||||
if (Tmp) {
|
||||
@ -197,7 +197,7 @@ inline unsigned CountLeadingZeros_64(uint64_t Value) {
|
||||
if (sizeof(long) == sizeof(int64_t)) {
|
||||
if (!Value) return 64;
|
||||
Count = 0;
|
||||
// bisecton method for count leading zeros
|
||||
// bisection method for count leading zeros
|
||||
for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) {
|
||||
uint64_t Tmp = Value >> Shift;
|
||||
if (Tmp) {
|
||||
|
@ -437,7 +437,7 @@ m_SelectCst(const Cond &C) {
|
||||
// Matchers for CastInst classes
|
||||
//
|
||||
|
||||
template<typename Op_t, typename Class>
|
||||
template<typename Op_t, unsigned Opcode>
|
||||
struct CastClass_match {
|
||||
Op_t Op;
|
||||
|
||||
@ -445,17 +445,28 @@ struct CastClass_match {
|
||||
|
||||
template<typename OpTy>
|
||||
bool match(OpTy *V) {
|
||||
if (Class *I = dyn_cast<Class>(V))
|
||||
return Op.match(I->getOperand(0));
|
||||
if (CastInst *I = dyn_cast<CastInst>(V))
|
||||
return I->getOpcode() == Opcode && Op.match(I->getOperand(0));
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
|
||||
return CE->getOpcode() == Opcode && Op.match(CE->getOperand(0));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Class, typename OpTy>
|
||||
inline CastClass_match<OpTy, Class> m_Cast(const OpTy &Op) {
|
||||
return CastClass_match<OpTy, Class>(Op);
|
||||
/// m_PtrToInt
|
||||
template<typename OpTy>
|
||||
inline CastClass_match<OpTy, Instruction::PtrToInt>
|
||||
m_PtrToInt(const OpTy &Op) {
|
||||
return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
|
||||
}
|
||||
|
||||
/// m_Trunc
|
||||
template<typename OpTy>
|
||||
inline CastClass_match<OpTy, Instruction::Trunc>
|
||||
m_Trunc(const OpTy &Op) {
|
||||
return CastClass_match<OpTy, Instruction::Trunc>(Op);
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Matchers for unary operators
|
||||
|
@ -477,6 +477,13 @@ def COPY_TO_REGCLASS : Instruction {
|
||||
let neverHasSideEffects = 1;
|
||||
let isAsCheapAsAMove = 1;
|
||||
}
|
||||
def DEBUG_VALUE : Instruction {
|
||||
let OutOperandList = (ops);
|
||||
let InOperandList = (ops unknown:$value, i64imm:$offset, unknown:$meta);
|
||||
let AsmString = "DEBUG_VALUE";
|
||||
let Namespace = "TargetInstrInfo";
|
||||
let isAsCheapAsAMove = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -10,13 +10,15 @@
|
||||
#ifndef LLVM_TARGET_TARGETPARSER_H
|
||||
#define LLVM_TARGET_TARGETPARSER_H
|
||||
|
||||
#include "llvm/MC/MCAsmLexer.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCAsmParser;
|
||||
class MCInst;
|
||||
class StringRef;
|
||||
class Target;
|
||||
class SMLoc;
|
||||
class AsmToken;
|
||||
class MCParsedAsmOperand;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
|
||||
/// TargetAsmParser - Generic interface to target specific assembly parsers.
|
||||
class TargetAsmParser {
|
||||
@ -43,9 +45,11 @@ class TargetAsmParser {
|
||||
//
|
||||
/// \param AP - The current parser object.
|
||||
/// \param Name - The instruction name.
|
||||
/// \param Inst [out] - On success, the parsed instruction.
|
||||
/// \param Operands [out] - The list of parsed operands, this returns
|
||||
/// ownership of them to the caller.
|
||||
/// \return True on failure.
|
||||
virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst) = 0;
|
||||
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
|
||||
|
||||
/// ParseDirective - Parse a target specific assembler directive
|
||||
///
|
||||
@ -58,6 +62,14 @@ class TargetAsmParser {
|
||||
///
|
||||
/// \param ID - the identifier token of the directive.
|
||||
virtual bool ParseDirective(AsmToken DirectiveID) = 0;
|
||||
|
||||
/// MatchInstruction - Recognize a series of operands of a parsed instruction
|
||||
/// as an actual MCInst. This returns false and fills in Inst on success and
|
||||
/// returns true on failure to match.
|
||||
virtual bool
|
||||
MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
MCInst &Inst) = 0;
|
||||
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -88,7 +88,10 @@ class TargetInstrInfo {
|
||||
/// only needed in cases where the register classes implied by the
|
||||
/// instructions are insufficient. The actual MachineInstrs to perform
|
||||
/// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
|
||||
COPY_TO_REGCLASS = 10
|
||||
COPY_TO_REGCLASS = 10,
|
||||
|
||||
// DEBUG_VALUE - a mapping of the llvm.dbg.value intrinsic
|
||||
DEBUG_VALUE = 11
|
||||
};
|
||||
|
||||
unsigned getNumOpcodes() const { return NumOpcodes; }
|
||||
@ -143,6 +146,18 @@ class TargetInstrInfo {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
|
||||
/// extension instruction. That is, it's like a copy where it's legal for the
|
||||
/// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
|
||||
/// true, then it's expected the pre-extension value is available as a subreg
|
||||
/// of the result register. This also returns the sub-register index in
|
||||
/// SubIdx.
|
||||
virtual bool isCoalescableExtInstr(const MachineInstr &MI,
|
||||
unsigned &SrcReg, unsigned &DstReg,
|
||||
unsigned &SubIdx) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isIdentityCopy - Return true if the instruction is a copy (or
|
||||
/// extract_subreg, insert_subreg, subreg_to_reg) where the source and
|
||||
/// destination registers are the same.
|
||||
@ -232,6 +247,14 @@ class TargetInstrInfo {
|
||||
const MachineInstr *Orig,
|
||||
const TargetRegisterInfo *TRI) const = 0;
|
||||
|
||||
/// duplicate - Create a duplicate of the Orig instruction in MF. This is like
|
||||
/// MachineFunction::CloneMachineInstr(), but the target may update operands
|
||||
/// that are required to be unique.
|
||||
///
|
||||
/// The instruction must be duplicable as indicated by isNotDuplicable().
|
||||
virtual MachineInstr *duplicate(MachineInstr *Orig,
|
||||
MachineFunction &MF) const = 0;
|
||||
|
||||
/// convertToThreeAddress - This method must be implemented by targets that
|
||||
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
|
||||
/// may be able to convert a two-address instruction into one or more true
|
||||
@ -560,6 +583,8 @@ class TargetInstrInfoImpl : public TargetInstrInfo {
|
||||
unsigned DestReg, unsigned SubReg,
|
||||
const MachineInstr *Orig,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
virtual MachineInstr *duplicate(MachineInstr *Orig,
|
||||
MachineFunction &MF) const;
|
||||
virtual bool isIdentical(const MachineInstr *MI,
|
||||
const MachineInstr *Other,
|
||||
const MachineRegisterInfo *MRI) const;
|
||||
|
@ -774,10 +774,12 @@ class TargetLowering {
|
||||
/// that want to combine
|
||||
struct TargetLoweringOpt {
|
||||
SelectionDAG &DAG;
|
||||
bool ShrinkOps;
|
||||
SDValue Old;
|
||||
SDValue New;
|
||||
|
||||
explicit TargetLoweringOpt(SelectionDAG &InDAG) : DAG(InDAG) {}
|
||||
explicit TargetLoweringOpt(SelectionDAG &InDAG, bool Shrink = false) :
|
||||
DAG(InDAG), ShrinkOps(Shrink) {}
|
||||
|
||||
bool CombineTo(SDValue O, SDValue N) {
|
||||
Old = O;
|
||||
@ -1478,7 +1480,7 @@ class TargetLowering {
|
||||
}
|
||||
|
||||
/// isZExtFree - Return true if any actual instruction that defines a
|
||||
/// value of type Ty1 implicit zero-extends the value to Ty2 in the result
|
||||
/// value of type Ty1 implicitly zero-extends the value to Ty2 in the result
|
||||
/// register. This does not necessarily include registers defined in
|
||||
/// unknown ways, such as incoming arguments, or copies from unknown
|
||||
/// virtual registers. Also, if isTruncateFree(Ty2, Ty1) is true, this
|
||||
|
@ -352,7 +352,7 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
|
||||
|
||||
/// getCOFFSection - Return the MCSection for the specified COFF section.
|
||||
/// FIXME: Switch this to a semantic view eventually.
|
||||
const MCSection *getCOFFSection(const char *Name, bool isDirective,
|
||||
const MCSection *getCOFFSection(StringRef Name, bool isDirective,
|
||||
SectionKind K) const;
|
||||
};
|
||||
|
||||
|
@ -664,7 +664,7 @@ class TargetRegisterInfo {
|
||||
/// frame indices from instructions which may use them. The instruction
|
||||
/// referenced by the iterator contains an MO_FrameIndex operand which must be
|
||||
/// eliminated by this method. This method may modify or replace the
|
||||
/// specified instruction, as long as it keeps the iterator pointing the the
|
||||
/// specified instruction, as long as it keeps the iterator pointing at the
|
||||
/// finished product. SPAdj is the SP adjustment due to call frame setup
|
||||
/// instruction.
|
||||
///
|
||||
|
@ -843,11 +843,6 @@ class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
|
||||
// Complex pattern definitions.
|
||||
//
|
||||
|
||||
class CPAttribute;
|
||||
// Pass the parent Operand as root to CP function rather
|
||||
// than the root of the sub-DAG
|
||||
def CPAttrParentAsRoot : CPAttribute;
|
||||
|
||||
// Complex patterns, e.g. X86 addressing mode, requires pattern matching code
|
||||
// in C++. NumOperands is the number of operands returned by the select function;
|
||||
// SelectFunc is the name of the function used to pattern match the max. pattern;
|
||||
@ -855,12 +850,10 @@ def CPAttrParentAsRoot : CPAttribute;
|
||||
// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>;
|
||||
//
|
||||
class ComplexPattern<ValueType ty, int numops, string fn,
|
||||
list<SDNode> roots = [], list<SDNodeProperty> props = [],
|
||||
list<CPAttribute> attrs = []> {
|
||||
list<SDNode> roots = [], list<SDNodeProperty> props = []> {
|
||||
ValueType Ty = ty;
|
||||
int NumOperands = numops;
|
||||
string SelectFunc = fn;
|
||||
list<SDNode> RootNodes = roots;
|
||||
list<SDNodeProperty> Properties = props;
|
||||
list<CPAttribute> Attributes = attrs;
|
||||
}
|
||||
|
@ -19,22 +19,12 @@ namespace llvm {
|
||||
class ModulePass;
|
||||
class FunctionPass;
|
||||
|
||||
// Insert function profiling instrumentation
|
||||
ModulePass *createFunctionProfilerPass();
|
||||
|
||||
// Insert block profiling instrumentation
|
||||
ModulePass *createBlockProfilerPass();
|
||||
|
||||
// Insert edge profiling instrumentation
|
||||
ModulePass *createEdgeProfilerPass();
|
||||
|
||||
// Insert optimal edge profiling instrumentation
|
||||
ModulePass *createOptimalEdgeProfilerPass();
|
||||
|
||||
// Random Sampling Profiling Framework
|
||||
ModulePass* createNullProfilerRSPass();
|
||||
FunctionPass* createRSProfilingPass();
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -40,8 +40,9 @@ void FoldSingleEntryPHINodes(BasicBlock *BB);
|
||||
/// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
|
||||
/// is dead. Also recursively delete any operands that become dead as
|
||||
/// a result. This includes tracing the def-use list from the PHI to see if
|
||||
/// it is ultimately unused or if it reaches an unused cycle.
|
||||
void DeleteDeadPHIs(BasicBlock *BB);
|
||||
/// it is ultimately unused or if it reaches an unused cycle. Return true
|
||||
/// if any PHIs were deleted.
|
||||
bool DeleteDeadPHIs(BasicBlock *BB);
|
||||
|
||||
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
|
||||
/// if possible. The return value indicates success or failure.
|
||||
@ -65,11 +66,6 @@ void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
|
||||
//
|
||||
void ReplaceInstWithInst(Instruction *From, Instruction *To);
|
||||
|
||||
/// CopyPrecedingStopPoint - If I is immediately preceded by a StopPoint,
|
||||
/// make a copy of the stoppoint before InsertPos (presumably before copying
|
||||
/// or moving I).
|
||||
void CopyPrecedingStopPoint(Instruction *I, BasicBlock::iterator InsertPos);
|
||||
|
||||
/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at the
|
||||
/// instruction before ScanFrom) checking to see if we have the value at the
|
||||
/// memory address *Ptr locally available within a small number of instructions.
|
||||
|
@ -27,7 +27,7 @@ class PHINode;
|
||||
class AllocaInst;
|
||||
class ConstantExpr;
|
||||
class TargetData;
|
||||
struct DbgInfoIntrinsic;
|
||||
class DbgInfoIntrinsic;
|
||||
|
||||
template<typename T> class SmallVectorImpl;
|
||||
|
||||
@ -63,16 +63,25 @@ bool isInstructionTriviallyDead(Instruction *I);
|
||||
|
||||
/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
|
||||
/// trivially dead instruction, delete it. If that makes any of its operands
|
||||
/// trivially dead, delete them too, recursively.
|
||||
void RecursivelyDeleteTriviallyDeadInstructions(Value *V);
|
||||
/// trivially dead, delete them too, recursively. Return true if any
|
||||
/// instructions were deleted.
|
||||
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V);
|
||||
|
||||
/// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
|
||||
/// dead PHI node, due to being a def-use chain of single-use nodes that
|
||||
/// either forms a cycle or is terminated by a trivially dead instruction,
|
||||
/// delete it. If that makes any of its operands trivially dead, delete them
|
||||
/// too, recursively.
|
||||
void RecursivelyDeleteDeadPHINode(PHINode *PN);
|
||||
/// too, recursively. Return true if the PHI node is actually deleted.
|
||||
bool RecursivelyDeleteDeadPHINode(PHINode *PN);
|
||||
|
||||
|
||||
/// SimplifyInstructionsInBlock - Scan the specified basic block and try to
|
||||
/// simplify any instructions in it and recursively delete dead instructions.
|
||||
///
|
||||
/// This returns true if it changed the code, note that it can delete
|
||||
/// instructions in other blocks as well in this block.
|
||||
bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Control Flow Graph Restructuring.
|
||||
//
|
||||
|
@ -217,6 +217,9 @@ class Type : public AbstractTypeUser {
|
||||
///
|
||||
bool isInteger() const { return ID == IntegerTyID; }
|
||||
|
||||
/// isInteger - Return true if this is an IntegerType of the specified width.
|
||||
bool isInteger(unsigned Bitwidth) const;
|
||||
|
||||
/// isIntOrIntVector - Return true if this is an integer type or a vector of
|
||||
/// integer types.
|
||||
///
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "llvm/Value.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
|
||||
namespace llvm {
|
||||
template<typename ValueSubClass, typename ItemParentClass>
|
||||
@ -26,7 +27,7 @@ namespace llvm {
|
||||
class NamedMDNode;
|
||||
class Module;
|
||||
class StringRef;
|
||||
|
||||
|
||||
/// This class provides a symbol table of name/value pairs. It is essentially
|
||||
/// a std::map<std::string,Value*> but has a controlled interface provided by
|
||||
/// LLVM as well as ensuring uniqueness of names.
|
||||
@ -39,7 +40,6 @@ class ValueSymbolTable {
|
||||
friend class SymbolTableListTraits<Function, Module>;
|
||||
friend class SymbolTableListTraits<GlobalVariable, Module>;
|
||||
friend class SymbolTableListTraits<GlobalAlias, Module>;
|
||||
friend class SymbolTableListTraits<NamedMDNode, Module>;
|
||||
/// @name Types
|
||||
/// @{
|
||||
public:
|
||||
@ -129,6 +129,88 @@ class ValueSymbolTable {
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// This class provides a symbol table of name/NamedMDNode pairs. It is
|
||||
/// essentially a StringMap wrapper.
|
||||
|
||||
class MDSymbolTable {
|
||||
friend class SymbolTableListTraits<NamedMDNode, Module>;
|
||||
/// @name Types
|
||||
/// @{
|
||||
private:
|
||||
/// @brief A mapping of names to metadata
|
||||
typedef StringMap<NamedMDNode*> MDMap;
|
||||
|
||||
public:
|
||||
/// @brief An iterator over a ValueMap.
|
||||
typedef MDMap::iterator iterator;
|
||||
|
||||
/// @brief A const_iterator over a ValueMap.
|
||||
typedef MDMap::const_iterator const_iterator;
|
||||
|
||||
/// @}
|
||||
/// @name Constructors
|
||||
/// @{
|
||||
public:
|
||||
|
||||
MDSymbolTable(const MDNode &); // DO NOT IMPLEMENT
|
||||
void operator=(const MDSymbolTable &); // DO NOT IMPLEMENT
|
||||
MDSymbolTable() : mmap(0) {}
|
||||
~MDSymbolTable();
|
||||
|
||||
/// @}
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
public:
|
||||
|
||||
/// This method finds the value with the given \p Name in the
|
||||
/// the symbol table.
|
||||
/// @returns the NamedMDNode associated with the \p Name
|
||||
/// @brief Lookup a named Value.
|
||||
NamedMDNode *lookup(StringRef Name) const { return mmap.lookup(Name); }
|
||||
|
||||
/// @returns true iff the symbol table is empty
|
||||
/// @brief Determine if the symbol table is empty
|
||||
inline bool empty() const { return mmap.empty(); }
|
||||
|
||||
/// @brief The number of name/type pairs is returned.
|
||||
inline unsigned size() const { return unsigned(mmap.size()); }
|
||||
|
||||
/// @}
|
||||
/// @name Iteration
|
||||
/// @{
|
||||
public:
|
||||
/// @brief Get an iterator that from the beginning of the symbol table.
|
||||
inline iterator begin() { return mmap.begin(); }
|
||||
|
||||
/// @brief Get a const_iterator that from the beginning of the symbol table.
|
||||
inline const_iterator begin() const { return mmap.begin(); }
|
||||
|
||||
/// @brief Get an iterator to the end of the symbol table.
|
||||
inline iterator end() { return mmap.end(); }
|
||||
|
||||
/// @brief Get a const_iterator to the end of the symbol table.
|
||||
inline const_iterator end() const { return mmap.end(); }
|
||||
|
||||
/// @}
|
||||
/// @name Mutators
|
||||
/// @{
|
||||
public:
|
||||
/// insert - The method inserts a new entry into the stringmap.
|
||||
void insert(StringRef Name, NamedMDNode *Node) {
|
||||
(void) mmap.GetOrCreateValue(Name, Node);
|
||||
}
|
||||
|
||||
/// This method removes a NamedMDNode from the symbol table.
|
||||
void remove(StringRef Name) { mmap.erase(Name); }
|
||||
|
||||
/// @}
|
||||
/// @name Internal Data
|
||||
/// @{
|
||||
private:
|
||||
MDMap mmap; ///< The map that holds the symbol table.
|
||||
/// @}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -116,13 +116,16 @@ AliasAnalysis::getModRefBehavior(Function *F,
|
||||
return DoesNotAccessMemory;
|
||||
if (F->onlyReadsMemory())
|
||||
return OnlyReadsMemory;
|
||||
if (unsigned id = F->getIntrinsicID()) {
|
||||
if (unsigned id = F->getIntrinsicID())
|
||||
return getModRefBehavior(id);
|
||||
}
|
||||
return UnknownModRefBehavior;
|
||||
}
|
||||
|
||||
AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(unsigned iid) {
|
||||
#define GET_INTRINSIC_MODREF_BEHAVIOR
|
||||
#include "llvm/Intrinsics.gen"
|
||||
#undef GET_INTRINSIC_MODREF_BEHAVIOR
|
||||
}
|
||||
}
|
||||
return UnknownModRefBehavior;
|
||||
}
|
||||
|
||||
AliasAnalysis::ModRefResult
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
|
||||
char **OutMessages) {
|
||||
LLVMBool LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
|
||||
char **OutMessages) {
|
||||
std::string Messages;
|
||||
|
||||
int Result = verifyModule(*unwrap(M),
|
||||
LLVMBool Result = verifyModule(*unwrap(M),
|
||||
static_cast<VerifierFailureAction>(Action),
|
||||
OutMessages? &Messages : 0);
|
||||
|
||||
@ -27,7 +27,7 @@ int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
|
||||
return Result;
|
||||
}
|
||||
|
||||
int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action) {
|
||||
LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action) {
|
||||
return verifyFunction(*unwrap<Function>(Fn),
|
||||
static_cast<VerifierFailureAction>(Action));
|
||||
}
|
||||
|
@ -398,8 +398,8 @@ static Constant *FoldReinterpretLoadFromConstPtr(Constant *C,
|
||||
BytesLoaded, TD))
|
||||
return 0;
|
||||
|
||||
APInt ResultVal(IntType->getBitWidth(), 0);
|
||||
for (unsigned i = 0; i != BytesLoaded; ++i) {
|
||||
APInt ResultVal = APInt(IntType->getBitWidth(), RawBytes[BytesLoaded-1]);
|
||||
for (unsigned i = 1; i != BytesLoaded; ++i) {
|
||||
ResultVal <<= 8;
|
||||
ResultVal |= APInt(IntType->getBitWidth(), RawBytes[BytesLoaded-1-i]);
|
||||
}
|
||||
@ -718,14 +718,13 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
|
||||
|
||||
switch (Opcode) {
|
||||
default: return 0;
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp: assert(0 && "Invalid for compares");
|
||||
case Instruction::Call:
|
||||
if (Function *F = dyn_cast<Function>(Ops[0]))
|
||||
if (canConstantFoldCallTo(F))
|
||||
return ConstantFoldCall(F, Ops+1, NumOps-1);
|
||||
return 0;
|
||||
case Instruction::ICmp:
|
||||
case Instruction::FCmp:
|
||||
llvm_unreachable("This function is invalid for compares: no predicate specified");
|
||||
case Instruction::PtrToInt:
|
||||
// If the input is a inttoptr, eliminate the pair. This requires knowing
|
||||
// the width of a pointer, so it can't be done in ConstantExpr::getCast.
|
||||
@ -877,6 +876,20 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
|
||||
CE1->getOperand(0), TD);
|
||||
}
|
||||
}
|
||||
|
||||
// icmp eq (or x, y), 0 -> (icmp eq x, 0) & (icmp eq y, 0)
|
||||
// icmp ne (or x, y), 0 -> (icmp ne x, 0) | (icmp ne y, 0)
|
||||
if ((Predicate == ICmpInst::ICMP_EQ || Predicate == ICmpInst::ICMP_NE) &&
|
||||
CE0->getOpcode() == Instruction::Or && Ops1->isNullValue()) {
|
||||
Constant *LHS =
|
||||
ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(0), Ops1,TD);
|
||||
Constant *RHS =
|
||||
ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(1), Ops1,TD);
|
||||
unsigned OpC =
|
||||
Predicate == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
|
||||
Constant *Ops[] = { LHS, RHS };
|
||||
return ConstantFoldInstOperands(OpC, LHS->getType(), Ops, 2, TD);
|
||||
}
|
||||
}
|
||||
|
||||
return ConstantExpr::getCompare(Predicate, Ops0, Ops1);
|
||||
|
@ -37,8 +37,6 @@ PrintDirectory("print-fullpath",
|
||||
namespace {
|
||||
class PrintDbgInfo : public FunctionPass {
|
||||
raw_ostream &Out;
|
||||
void printStopPoint(const DbgStopPointInst *DSI);
|
||||
void printFuncStart(const DbgFuncStartInst *FS);
|
||||
void printVariableDeclaration(const Value *V);
|
||||
public:
|
||||
static char ID; // Pass identification
|
||||
@ -74,27 +72,6 @@ void PrintDbgInfo::printVariableDeclaration(const Value *V) {
|
||||
Out << File << ":" << LineNo << "\n";
|
||||
}
|
||||
|
||||
void PrintDbgInfo::printStopPoint(const DbgStopPointInst *DSI) {
|
||||
if (PrintDirectory)
|
||||
if (MDString *Str = dyn_cast<MDString>(DSI->getDirectory()))
|
||||
Out << Str->getString() << '/';
|
||||
|
||||
if (MDString *Str = dyn_cast<MDString>(DSI->getFileName()))
|
||||
Out << Str->getString();
|
||||
Out << ':' << DSI->getLine();
|
||||
|
||||
if (unsigned Col = DSI->getColumn())
|
||||
Out << ':' << Col;
|
||||
}
|
||||
|
||||
void PrintDbgInfo::printFuncStart(const DbgFuncStartInst *FS) {
|
||||
DISubprogram Subprogram(FS->getSubprogram());
|
||||
Out << "; fully qualified function name: " << Subprogram.getDisplayName()
|
||||
<< " return type: " << Subprogram.getReturnTypeName()
|
||||
<< " at line " << Subprogram.getLineNumber()
|
||||
<< "\n\n";
|
||||
}
|
||||
|
||||
bool PrintDbgInfo::runOnFunction(Function &F) {
|
||||
if (F.isDeclaration())
|
||||
return false;
|
||||
@ -108,57 +85,21 @@ bool PrintDbgInfo::runOnFunction(Function &F) {
|
||||
// Skip dead blocks.
|
||||
continue;
|
||||
|
||||
const DbgStopPointInst *DSI = findBBStopPoint(BB);
|
||||
Out << BB->getName();
|
||||
Out << ":";
|
||||
|
||||
if (DSI) {
|
||||
Out << "; (";
|
||||
printStopPoint(DSI);
|
||||
Out << ")";
|
||||
}
|
||||
|
||||
Out << "\n";
|
||||
|
||||
// A dbgstoppoint's information is valid until we encounter a new one.
|
||||
const DbgStopPointInst *LastDSP = DSI;
|
||||
bool Printed = DSI != 0;
|
||||
for (BasicBlock::const_iterator i = BB->begin(), e = BB->end();
|
||||
i != e; ++i) {
|
||||
if (isa<DbgInfoIntrinsic>(i)) {
|
||||
if ((DSI = dyn_cast<DbgStopPointInst>(i))) {
|
||||
if (DSI->getContext() == LastDSP->getContext() &&
|
||||
DSI->getLineValue() == LastDSP->getLineValue() &&
|
||||
DSI->getColumnValue() == LastDSP->getColumnValue())
|
||||
// Don't print same location twice.
|
||||
continue;
|
||||
|
||||
LastDSP = cast<DbgStopPointInst>(i);
|
||||
|
||||
// Don't print consecutive stoppoints, use a flag to know which one we
|
||||
// printed.
|
||||
Printed = false;
|
||||
} else if (const DbgFuncStartInst *FS = dyn_cast<DbgFuncStartInst>(i)) {
|
||||
printFuncStart(FS);
|
||||
}
|
||||
} else {
|
||||
if (!Printed && LastDSP) {
|
||||
Out << "; ";
|
||||
printStopPoint(LastDSP);
|
||||
Out << "\n";
|
||||
Printed = true;
|
||||
}
|
||||
|
||||
Out << *i << '\n';
|
||||
printVariableDeclaration(i);
|
||||
|
||||
if (const User *U = dyn_cast<User>(i)) {
|
||||
for(unsigned i=0;i<U->getNumOperands();i++)
|
||||
printVariableDeclaration(U->getOperand(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -599,9 +599,7 @@ void DIVariable::dump() const {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
DIFactory::DIFactory(Module &m)
|
||||
: M(m), VMContext(M.getContext()), DeclareFn(0) {
|
||||
EmptyStructPtr = PointerType::getUnqual(StructType::get(VMContext));
|
||||
}
|
||||
: M(m), VMContext(M.getContext()), DeclareFn(0) {}
|
||||
|
||||
Constant *DIFactory::GetTagConstant(unsigned TAG) {
|
||||
assert((TAG & LLVMDebugVersionMask) == 0 &&
|
||||
@ -1033,58 +1031,52 @@ DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo,
|
||||
|
||||
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
|
||||
Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
|
||||
Instruction *InsertBefore) {
|
||||
// Cast the storage to a {}* for the call to llvm.dbg.declare.
|
||||
Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertBefore);
|
||||
|
||||
Instruction *InsertBefore) {
|
||||
if (!DeclareFn)
|
||||
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
|
||||
|
||||
Value *Args[] = { Storage, D.getNode() };
|
||||
Value *Elts[] = { Storage };
|
||||
Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() };
|
||||
return CallInst::Create(DeclareFn, Args, Args+2, "", InsertBefore);
|
||||
}
|
||||
|
||||
/// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call.
|
||||
Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
// Cast the storage to a {}* for the call to llvm.dbg.declare.
|
||||
Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertAtEnd);
|
||||
|
||||
BasicBlock *InsertAtEnd) {
|
||||
if (!DeclareFn)
|
||||
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
|
||||
|
||||
Value *Args[] = { Storage, D.getNode() };
|
||||
Value *Elts[] = { Storage };
|
||||
Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() };
|
||||
return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd);
|
||||
}
|
||||
|
||||
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
|
||||
Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset,
|
||||
Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset,
|
||||
DIVariable D,
|
||||
Instruction *InsertBefore) {
|
||||
assert(V && "no value passed to dbg.value");
|
||||
assert(Offset->getType() == Type::getInt64Ty(V->getContext()) &&
|
||||
"offset must be i64");
|
||||
if (!ValueFn)
|
||||
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
|
||||
|
||||
Value *Elts[] = { V };
|
||||
Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset,
|
||||
Value *Args[] = { MDNode::get(V->getContext(), Elts, 1),
|
||||
ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
|
||||
D.getNode() };
|
||||
return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore);
|
||||
}
|
||||
|
||||
/// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
|
||||
Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset,
|
||||
Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset,
|
||||
DIVariable D,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
assert(V && "no value passed to dbg.value");
|
||||
assert(Offset->getType() == Type::getInt64Ty(V->getContext()) &&
|
||||
"offset must be i64");
|
||||
if (!ValueFn)
|
||||
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
|
||||
|
||||
Value *Elts[] = { V };
|
||||
Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset,
|
||||
Value *Args[] = { MDNode::get(V->getContext(), Elts, 1),
|
||||
ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
|
||||
D.getNode() };
|
||||
return CallInst::Create(ValueFn, Args, Args+3, "", InsertAtEnd);
|
||||
}
|
||||
@ -1242,52 +1234,6 @@ bool DebugInfoFinder::addSubprogram(DISubprogram SP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// findStopPoint - Find the stoppoint coressponding to this instruction, that
|
||||
/// is the stoppoint that dominates this instruction.
|
||||
const DbgStopPointInst *llvm::findStopPoint(const Instruction *Inst) {
|
||||
if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(Inst))
|
||||
return DSI;
|
||||
|
||||
const BasicBlock *BB = Inst->getParent();
|
||||
BasicBlock::const_iterator I = Inst, B;
|
||||
while (BB) {
|
||||
B = BB->begin();
|
||||
|
||||
// A BB consisting only of a terminator can't have a stoppoint.
|
||||
while (I != B) {
|
||||
--I;
|
||||
if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I))
|
||||
return DSI;
|
||||
}
|
||||
|
||||
// This BB didn't have a stoppoint: if there is only one predecessor, look
|
||||
// for a stoppoint there. We could use getIDom(), but that would require
|
||||
// dominator info.
|
||||
BB = I->getParent()->getUniquePredecessor();
|
||||
if (BB)
|
||||
I = BB->getTerminator();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// findBBStopPoint - Find the stoppoint corresponding to first real
|
||||
/// (non-debug intrinsic) instruction in this Basic Block, and return the
|
||||
/// stoppoint for it.
|
||||
const DbgStopPointInst *llvm::findBBStopPoint(const BasicBlock *BB) {
|
||||
for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
||||
if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I))
|
||||
return DSI;
|
||||
|
||||
// Fallback to looking for stoppoint of unique predecessor. Useful if this
|
||||
// BB contains no stoppoints, but unique predecessor does.
|
||||
BB = BB->getUniquePredecessor();
|
||||
if (BB)
|
||||
return findStopPoint(BB->getTerminator());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) {
|
||||
const Module *M = V->getParent();
|
||||
NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
|
||||
@ -1306,25 +1252,24 @@ Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) {
|
||||
|
||||
/// Finds the llvm.dbg.declare intrinsic corresponding to this value if any.
|
||||
/// It looks through pointer casts too.
|
||||
const DbgDeclareInst *llvm::findDbgDeclare(const Value *V, bool stripCasts) {
|
||||
if (stripCasts) {
|
||||
V = V->stripPointerCasts();
|
||||
|
||||
// Look for the bitcast.
|
||||
for (Value::use_const_iterator I = V->use_begin(), E =V->use_end();
|
||||
I != E; ++I)
|
||||
if (isa<BitCastInst>(I)) {
|
||||
const DbgDeclareInst *DDI = findDbgDeclare(*I, false);
|
||||
if (DDI) return DDI;
|
||||
}
|
||||
const DbgDeclareInst *llvm::findDbgDeclare(const Value *V) {
|
||||
V = V->stripPointerCasts();
|
||||
|
||||
if (!isa<Instruction>(V) && !isa<Argument>(V))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find llvm.dbg.declare among uses of the instruction.
|
||||
for (Value::use_const_iterator I = V->use_begin(), E =V->use_end();
|
||||
I != E; ++I)
|
||||
if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I))
|
||||
return DDI;
|
||||
|
||||
const Function *F = NULL;
|
||||
if (const Instruction *I = dyn_cast<Instruction>(V))
|
||||
F = I->getParent()->getParent();
|
||||
else if (const Argument *A = dyn_cast<Argument>(V))
|
||||
F = A->getParent();
|
||||
|
||||
for (Function::const_iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
|
||||
for (BasicBlock::const_iterator BI = (*FI).begin(), BE = (*FI).end();
|
||||
BI != BE; ++BI)
|
||||
if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
|
||||
if (DDI->getAddress() == V)
|
||||
return DDI;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1371,29 +1316,6 @@ bool llvm::getLocationInfo(const Value *V, std::string &DisplayName,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.stoppoint intrinsic.
|
||||
DebugLoc llvm::ExtractDebugLocation(DbgStopPointInst &SPI,
|
||||
DebugLocTracker &DebugLocInfo) {
|
||||
DebugLoc DL;
|
||||
Value *Context = SPI.getContext();
|
||||
|
||||
// If this location is already tracked then use it.
|
||||
DebugLocTuple Tuple(cast<MDNode>(Context), NULL, SPI.getLine(),
|
||||
SPI.getColumn());
|
||||
DenseMap<DebugLocTuple, unsigned>::iterator II
|
||||
= DebugLocInfo.DebugIdMap.find(Tuple);
|
||||
if (II != DebugLocInfo.DebugIdMap.end())
|
||||
return DebugLoc::get(II->second);
|
||||
|
||||
// Add a new location entry.
|
||||
unsigned Id = DebugLocInfo.DebugLocations.size();
|
||||
DebugLocInfo.DebugLocations.push_back(Tuple);
|
||||
DebugLocInfo.DebugIdMap[Tuple] = Id;
|
||||
|
||||
return DebugLoc::get(Id);
|
||||
}
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from DILocation.
|
||||
DebugLoc llvm::ExtractDebugLocation(DILocation &Loc,
|
||||
@ -1419,32 +1341,6 @@ DebugLoc llvm::ExtractDebugLocation(DILocation &Loc,
|
||||
return DebugLoc::get(Id);
|
||||
}
|
||||
|
||||
/// ExtractDebugLocation - Extract debug location information
|
||||
/// from llvm.dbg.func_start intrinsic.
|
||||
DebugLoc llvm::ExtractDebugLocation(DbgFuncStartInst &FSI,
|
||||
DebugLocTracker &DebugLocInfo) {
|
||||
DebugLoc DL;
|
||||
Value *SP = FSI.getSubprogram();
|
||||
|
||||
DISubprogram Subprogram(cast<MDNode>(SP));
|
||||
unsigned Line = Subprogram.getLineNumber();
|
||||
DICompileUnit CU(Subprogram.getCompileUnit());
|
||||
|
||||
// If this location is already tracked then use it.
|
||||
DebugLocTuple Tuple(CU.getNode(), NULL, Line, /* Column */ 0);
|
||||
DenseMap<DebugLocTuple, unsigned>::iterator II
|
||||
= DebugLocInfo.DebugIdMap.find(Tuple);
|
||||
if (II != DebugLocInfo.DebugIdMap.end())
|
||||
return DebugLoc::get(II->second);
|
||||
|
||||
// Add a new location entry.
|
||||
unsigned Id = DebugLocInfo.DebugLocations.size();
|
||||
DebugLocInfo.DebugLocations.push_back(Tuple);
|
||||
DebugLocInfo.DebugIdMap[Tuple] = Id;
|
||||
|
||||
return DebugLoc::get(Id);
|
||||
}
|
||||
|
||||
/// getDISubprogram - Find subprogram that is enclosing this scope.
|
||||
DISubprogram llvm::getDISubprogram(MDNode *Scope) {
|
||||
DIDescriptor D(Scope);
|
||||
|
@ -128,8 +128,9 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop,
|
||||
if (!AddRecStride->properlyDominates(Header, DT))
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "[" << L->getHeader()->getName()
|
||||
<< "] Variable stride: " << *AddRec << "\n");
|
||||
DEBUG(dbgs() << "[";
|
||||
WriteAsOperand(dbgs(), L->getHeader(), /*PrintType=*/false);
|
||||
dbgs() << "] Variable stride: " << *AddRec << "\n");
|
||||
}
|
||||
|
||||
Stride = AddRecStride;
|
||||
|
@ -102,6 +102,37 @@ unsigned InlineCostAnalyzer::FunctionInfo::
|
||||
return Reduction;
|
||||
}
|
||||
|
||||
// callIsSmall - If a call is likely to lower to a single target instruction, or
|
||||
// is otherwise deemed small return true.
|
||||
// TODO: Perhaps calls like memcpy, strcpy, etc?
|
||||
static bool callIsSmall(const Function *F) {
|
||||
if (!F) return false;
|
||||
|
||||
if (F->hasLocalLinkage()) return false;
|
||||
|
||||
if (!F->hasName()) return false;
|
||||
|
||||
StringRef Name = F->getName();
|
||||
|
||||
// These will all likely lower to a single selection DAG node.
|
||||
if (Name == "copysign" || Name == "copysignf" ||
|
||||
Name == "fabs" || Name == "fabsf" || Name == "fabsl" ||
|
||||
Name == "sin" || Name == "sinf" || Name == "sinl" ||
|
||||
Name == "cos" || Name == "cosf" || Name == "cosl" ||
|
||||
Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl" )
|
||||
return true;
|
||||
|
||||
// These are all likely to be optimized into something smaller.
|
||||
if (Name == "pow" || Name == "powf" || Name == "powl" ||
|
||||
Name == "exp2" || Name == "exp2l" || Name == "exp2f" ||
|
||||
Name == "floor" || Name == "floorf" || Name == "ceil" ||
|
||||
Name == "round" || Name == "ffs" || Name == "ffsl" ||
|
||||
Name == "abs" || Name == "labs" || Name == "llabs")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// analyzeBasicBlock - Fill in the current structure with information gleaned
|
||||
/// from the specified block.
|
||||
void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
|
||||
@ -129,7 +160,7 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
|
||||
|
||||
// Calls often compile into many machine instructions. Bump up their
|
||||
// cost to reflect this.
|
||||
if (!isa<IntrinsicInst>(II))
|
||||
if (!isa<IntrinsicInst>(II) && !callIsSmall(CS.getCalledFunction()))
|
||||
NumInsts += InlineConstants::CallPenalty;
|
||||
}
|
||||
|
||||
@ -141,11 +172,16 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
|
||||
if (isa<ExtractElementInst>(II) || isa<VectorType>(II->getType()))
|
||||
++NumVectorInsts;
|
||||
|
||||
// Noop casts, including ptr <-> int, don't count.
|
||||
if (const CastInst *CI = dyn_cast<CastInst>(II)) {
|
||||
// Noop casts, including ptr <-> int, don't count.
|
||||
if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) ||
|
||||
isa<PtrToIntInst>(CI))
|
||||
continue;
|
||||
// Result of a cmp instruction is often extended (to be used by other
|
||||
// cmp instructions, logical or return instructions). These are usually
|
||||
// nop on most sane targets.
|
||||
if (isa<CmpInst>(CI->getOperand(0)))
|
||||
continue;
|
||||
} else if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(II)){
|
||||
// If a GEP has all constant indices, it will probably be folded with
|
||||
// a load/store.
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include <algorithm>
|
||||
@ -385,6 +386,10 @@ BasicBlock *Loop::getUniqueExitBlock() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Loop::dump() const {
|
||||
print(dbgs());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LoopInfo implementation
|
||||
//
|
||||
|
@ -316,7 +316,9 @@ void SCEVAddRecExpr::print(raw_ostream &OS) const {
|
||||
OS << "{" << *Operands[0];
|
||||
for (unsigned i = 1, e = Operands.size(); i != e; ++i)
|
||||
OS << ",+," << *Operands[i];
|
||||
OS << "}<" << L->getHeader()->getName() + ">";
|
||||
OS << "}<";
|
||||
WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false);
|
||||
OS << ">";
|
||||
}
|
||||
|
||||
void SCEVFieldOffsetExpr::print(raw_ostream &OS) const {
|
||||
@ -5193,7 +5195,9 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE,
|
||||
for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
|
||||
PrintLoopInfo(OS, SE, *I);
|
||||
|
||||
OS << "Loop " << L->getHeader()->getName() << ": ";
|
||||
OS << "Loop ";
|
||||
WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false);
|
||||
OS << ": ";
|
||||
|
||||
SmallVector<BasicBlock *, 8> ExitBlocks;
|
||||
L->getExitBlocks(ExitBlocks);
|
||||
@ -5206,8 +5210,10 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE,
|
||||
OS << "Unpredictable backedge-taken count. ";
|
||||
}
|
||||
|
||||
OS << "\n";
|
||||
OS << "Loop " << L->getHeader()->getName() << ": ";
|
||||
OS << "\n"
|
||||
"Loop ";
|
||||
WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false);
|
||||
OS << ": ";
|
||||
|
||||
if (!isa<SCEVCouldNotCompute>(SE->getMaxBackedgeTakenCount(L))) {
|
||||
OS << "max backedge-taken count is " << *SE->getMaxBackedgeTakenCount(L);
|
||||
@ -5227,7 +5233,9 @@ void ScalarEvolution::print(raw_ostream &OS, const Module *) const {
|
||||
// const isn't dangerous.
|
||||
ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this);
|
||||
|
||||
OS << "Classifying expressions for: " << F->getName() << "\n";
|
||||
OS << "Classifying expressions for: ";
|
||||
WriteAsOperand(OS, F, /*PrintType=*/false);
|
||||
OS << "\n";
|
||||
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
|
||||
if (isSCEVable(I->getType())) {
|
||||
OS << *I << '\n';
|
||||
@ -5256,7 +5264,9 @@ void ScalarEvolution::print(raw_ostream &OS, const Module *) const {
|
||||
OS << "\n";
|
||||
}
|
||||
|
||||
OS << "Determining loop execution counts for: " << F->getName() << "\n";
|
||||
OS << "Determining loop execution counts for: ";
|
||||
WriteAsOperand(OS, F, /*PrintType=*/false);
|
||||
OS << "\n";
|
||||
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
|
||||
PrintLoopInfo(OS, &SE, *I);
|
||||
}
|
||||
|
@ -726,8 +726,7 @@ unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD,
|
||||
|
||||
Tmp2 = ComputeNumSignBits(U->getOperand(1), TD, Depth+1);
|
||||
if (Tmp2 == 1) return 1;
|
||||
return std::min(Tmp, Tmp2)-1;
|
||||
break;
|
||||
return std::min(Tmp, Tmp2)-1;
|
||||
|
||||
case Instruction::Sub:
|
||||
Tmp2 = ComputeNumSignBits(U->getOperand(1), TD, Depth+1);
|
||||
@ -757,8 +756,24 @@ unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD,
|
||||
// is, at worst, one more bit than the inputs.
|
||||
Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1);
|
||||
if (Tmp == 1) return 1; // Early out.
|
||||
return std::min(Tmp, Tmp2)-1;
|
||||
break;
|
||||
return std::min(Tmp, Tmp2)-1;
|
||||
|
||||
case Instruction::PHI: {
|
||||
PHINode *PN = cast<PHINode>(U);
|
||||
// Don't analyze large in-degree PHIs.
|
||||
if (PN->getNumIncomingValues() > 4) break;
|
||||
|
||||
// Take the minimum of all incoming values. This can't infinitely loop
|
||||
// because of our depth threshold.
|
||||
Tmp = ComputeNumSignBits(PN->getIncomingValue(0), TD, Depth+1);
|
||||
for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) {
|
||||
if (Tmp == 1) return Tmp;
|
||||
Tmp = std::min(Tmp,
|
||||
ComputeNumSignBits(PN->getIncomingValue(1), TD, Depth+1));
|
||||
}
|
||||
return Tmp;
|
||||
}
|
||||
|
||||
case Instruction::Trunc:
|
||||
// FIXME: it's tricky to do anything useful for this, but it is an important
|
||||
// case for targets like X86.
|
||||
@ -1348,7 +1363,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
|
||||
// Make sure the index-ee is a pointer to array of i8.
|
||||
const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
|
||||
const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
|
||||
if (AT == 0 || AT->getElementType() != Type::getInt8Ty(V->getContext()))
|
||||
if (AT == 0 || !AT->getElementType()->isInteger(8))
|
||||
return false;
|
||||
|
||||
// Check to make sure that the first operand of the GEP is an integer and
|
||||
@ -1387,8 +1402,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
|
||||
|
||||
// Must be a Constant Array
|
||||
ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
|
||||
if (Array == 0 ||
|
||||
Array->getType()->getElementType() != Type::getInt8Ty(V->getContext()))
|
||||
if (Array == 0 || !Array->getType()->getElementType()->isInteger(8))
|
||||
return false;
|
||||
|
||||
// Get the number of elements in the array
|
||||
|
@ -510,12 +510,17 @@ bool LLParser::ParseNamedMetadata() {
|
||||
ParseToken(lltok::lbrace, "Expected '{' here"))
|
||||
return true;
|
||||
|
||||
SmallVector<MetadataBase *, 8> Elts;
|
||||
SmallVector<MDNode *, 8> Elts;
|
||||
do {
|
||||
// Null is a special case since it is typeless.
|
||||
if (EatIfPresent(lltok::kw_null)) {
|
||||
Elts.push_back(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ParseToken(lltok::exclaim, "Expected '!' here"))
|
||||
return true;
|
||||
|
||||
// FIXME: This rejects MDStrings. Are they legal in an named MDNode or not?
|
||||
MDNode *N = 0;
|
||||
if (ParseMDNodeID(N)) return true;
|
||||
Elts.push_back(N);
|
||||
@ -543,7 +548,7 @@ bool LLParser::ParseStandaloneMetadata() {
|
||||
ParseType(Ty, TyLoc) ||
|
||||
ParseToken(lltok::exclaim, "Expected '!' here") ||
|
||||
ParseToken(lltok::lbrace, "Expected '{' here") ||
|
||||
ParseMDNodeVector(Elts) ||
|
||||
ParseMDNodeVector(Elts, NULL) ||
|
||||
ParseToken(lltok::rbrace, "expected end of metadata node"))
|
||||
return true;
|
||||
|
||||
@ -1715,8 +1720,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
|
||||
}
|
||||
|
||||
// Don't make placeholders with invalid type.
|
||||
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) &&
|
||||
Ty != Type::getLabelTy(F.getContext())) {
|
||||
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) && !Ty->isLabelTy()) {
|
||||
P.Error(Loc, "invalid use of a non-first-class type");
|
||||
return 0;
|
||||
}
|
||||
@ -1757,8 +1761,7 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) &&
|
||||
Ty != Type::getLabelTy(F.getContext())) {
|
||||
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) && !Ty->isLabelTy()) {
|
||||
P.Error(Loc, "invalid use of a non-first-class type");
|
||||
return 0;
|
||||
}
|
||||
@ -1881,8 +1884,10 @@ BasicBlock *LLParser::PerFunctionState::DefineBB(const std::string &Name,
|
||||
/// ParseValID - Parse an abstract value that doesn't necessarily have a
|
||||
/// type implied. For example, if we parse "4" we don't know what integer type
|
||||
/// it has. The value will later be combined with its type and checked for
|
||||
/// sanity.
|
||||
bool LLParser::ParseValID(ValID &ID) {
|
||||
/// sanity. PFS is used to convert function-local operands of metadata (since
|
||||
/// metadata operands are not just parsed here but also converted to values).
|
||||
/// PFS can be null when we are not parsing metadata values inside a function.
|
||||
bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
|
||||
ID.Loc = Lex.getLoc();
|
||||
switch (Lex.getKind()) {
|
||||
default: return TokError("expected value token");
|
||||
@ -1908,7 +1913,7 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
|
||||
if (EatIfPresent(lltok::lbrace)) {
|
||||
SmallVector<Value*, 16> Elts;
|
||||
if (ParseMDNodeVector(Elts) ||
|
||||
if (ParseMDNodeVector(Elts, PFS) ||
|
||||
ParseToken(lltok::rbrace, "expected end of metadata node"))
|
||||
return true;
|
||||
|
||||
@ -2353,30 +2358,85 @@ bool LLParser::ParseValID(ValID &ID) {
|
||||
}
|
||||
|
||||
/// ParseGlobalValue - Parse a global value with the specified type.
|
||||
bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&V) {
|
||||
V = 0;
|
||||
bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&C) {
|
||||
C = 0;
|
||||
ValID ID;
|
||||
return ParseValID(ID) ||
|
||||
ConvertGlobalValIDToValue(Ty, ID, V);
|
||||
Value *V = NULL;
|
||||
bool Parsed = ParseValID(ID) ||
|
||||
ConvertValIDToValue(Ty, ID, V, NULL);
|
||||
if (V && !(C = dyn_cast<Constant>(V)))
|
||||
return Error(ID.Loc, "global values must be constants");
|
||||
return Parsed;
|
||||
}
|
||||
|
||||
/// ConvertGlobalValIDToValue - Apply a type to a ValID to get a fully resolved
|
||||
/// constant.
|
||||
bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID,
|
||||
Constant *&V) {
|
||||
bool LLParser::ParseGlobalTypeAndValue(Constant *&V) {
|
||||
PATypeHolder Type(Type::getVoidTy(Context));
|
||||
return ParseType(Type) ||
|
||||
ParseGlobalValue(Type, V);
|
||||
}
|
||||
|
||||
/// ParseGlobalValueVector
|
||||
/// ::= /*empty*/
|
||||
/// ::= TypeAndValue (',' TypeAndValue)*
|
||||
bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
|
||||
// Empty list.
|
||||
if (Lex.getKind() == lltok::rbrace ||
|
||||
Lex.getKind() == lltok::rsquare ||
|
||||
Lex.getKind() == lltok::greater ||
|
||||
Lex.getKind() == lltok::rparen)
|
||||
return false;
|
||||
|
||||
Constant *C;
|
||||
if (ParseGlobalTypeAndValue(C)) return true;
|
||||
Elts.push_back(C);
|
||||
|
||||
while (EatIfPresent(lltok::comma)) {
|
||||
if (ParseGlobalTypeAndValue(C)) return true;
|
||||
Elts.push_back(C);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Function Parsing.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
|
||||
PerFunctionState *PFS) {
|
||||
if (isa<FunctionType>(Ty))
|
||||
return Error(ID.Loc, "functions are not values, refer to them as pointers");
|
||||
|
||||
switch (ID.Kind) {
|
||||
default: llvm_unreachable("Unknown ValID!");
|
||||
case ValID::t_MDNode:
|
||||
case ValID::t_MDString:
|
||||
return Error(ID.Loc, "invalid use of metadata");
|
||||
case ValID::t_LocalID:
|
||||
if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
|
||||
V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc);
|
||||
return (V == 0);
|
||||
case ValID::t_LocalName:
|
||||
return Error(ID.Loc, "invalid use of function-local name");
|
||||
case ValID::t_InlineAsm:
|
||||
return Error(ID.Loc, "inline asm can only be an operand of call/invoke");
|
||||
if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
|
||||
V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
|
||||
return (V == 0);
|
||||
case ValID::t_InlineAsm: {
|
||||
const PointerType *PTy = dyn_cast<PointerType>(Ty);
|
||||
const FunctionType *FTy =
|
||||
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
|
||||
if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
|
||||
return Error(ID.Loc, "invalid type for inline asm constraint string");
|
||||
V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, ID.UIntVal>>1);
|
||||
return false;
|
||||
}
|
||||
case ValID::t_MDNode:
|
||||
if (!Ty->isMetadataTy())
|
||||
return Error(ID.Loc, "metadata value must have metadata type");
|
||||
V = ID.MDNodeVal;
|
||||
return false;
|
||||
case ValID::t_MDString:
|
||||
if (!Ty->isMetadataTy())
|
||||
return Error(ID.Loc, "metadata value must have metadata type");
|
||||
V = ID.MDStringVal;
|
||||
return false;
|
||||
case ValID::t_GlobalName:
|
||||
V = GetGlobalVal(ID.StrVal, Ty, ID.Loc);
|
||||
return V == 0;
|
||||
@ -2440,90 +2500,11 @@ bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID,
|
||||
}
|
||||
}
|
||||
|
||||
/// ConvertGlobalOrMetadataValIDToValue - Apply a type to a ValID to get a fully
|
||||
/// resolved constant or metadata value.
|
||||
bool LLParser::ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
|
||||
Value *&V) {
|
||||
switch (ID.Kind) {
|
||||
case ValID::t_MDNode:
|
||||
if (!Ty->isMetadataTy())
|
||||
return Error(ID.Loc, "metadata value must have metadata type");
|
||||
V = ID.MDNodeVal;
|
||||
return false;
|
||||
case ValID::t_MDString:
|
||||
if (!Ty->isMetadataTy())
|
||||
return Error(ID.Loc, "metadata value must have metadata type");
|
||||
V = ID.MDStringVal;
|
||||
return false;
|
||||
default:
|
||||
Constant *C;
|
||||
if (ConvertGlobalValIDToValue(Ty, ID, C)) return true;
|
||||
V = C;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLParser::ParseGlobalTypeAndValue(Constant *&V) {
|
||||
PATypeHolder Type(Type::getVoidTy(Context));
|
||||
return ParseType(Type) ||
|
||||
ParseGlobalValue(Type, V);
|
||||
}
|
||||
|
||||
/// ParseGlobalValueVector
|
||||
/// ::= /*empty*/
|
||||
/// ::= TypeAndValue (',' TypeAndValue)*
|
||||
bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
|
||||
// Empty list.
|
||||
if (Lex.getKind() == lltok::rbrace ||
|
||||
Lex.getKind() == lltok::rsquare ||
|
||||
Lex.getKind() == lltok::greater ||
|
||||
Lex.getKind() == lltok::rparen)
|
||||
return false;
|
||||
|
||||
Constant *C;
|
||||
if (ParseGlobalTypeAndValue(C)) return true;
|
||||
Elts.push_back(C);
|
||||
|
||||
while (EatIfPresent(lltok::comma)) {
|
||||
if (ParseGlobalTypeAndValue(C)) return true;
|
||||
Elts.push_back(C);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Function Parsing.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
|
||||
PerFunctionState &PFS) {
|
||||
switch (ID.Kind) {
|
||||
case ValID::t_LocalID: V = PFS.GetVal(ID.UIntVal, Ty, ID.Loc); break;
|
||||
case ValID::t_LocalName: V = PFS.GetVal(ID.StrVal, Ty, ID.Loc); break;
|
||||
case ValID::t_InlineAsm: {
|
||||
const PointerType *PTy = dyn_cast<PointerType>(Ty);
|
||||
const FunctionType *FTy =
|
||||
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
|
||||
if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
|
||||
return Error(ID.Loc, "invalid type for inline asm constraint string");
|
||||
V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, ID.UIntVal>>1);
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return ConvertGlobalOrMetadataValIDToValue(Ty, ID, V);
|
||||
}
|
||||
|
||||
return V == 0;
|
||||
}
|
||||
|
||||
bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
|
||||
V = 0;
|
||||
ValID ID;
|
||||
return ParseValID(ID) ||
|
||||
ConvertValIDToValue(Ty, ID, V, PFS);
|
||||
return ParseValID(ID, &PFS) ||
|
||||
ConvertValIDToValue(Ty, ID, V, &PFS);
|
||||
}
|
||||
|
||||
bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) {
|
||||
@ -2663,8 +2644,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
||||
|
||||
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
||||
|
||||
if (PAL.paramHasAttr(1, Attribute::StructRet) &&
|
||||
RetType != Type::getVoidTy(Context))
|
||||
if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy())
|
||||
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
|
||||
|
||||
const FunctionType *FT =
|
||||
@ -2766,6 +2746,10 @@ bool LLParser::ParseFunctionBody(Function &Fn) {
|
||||
|
||||
PerFunctionState PFS(*this, Fn, FunctionNumber);
|
||||
|
||||
// We need at least one basic block.
|
||||
if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_end)
|
||||
return TokError("function body requires at least one basic block");
|
||||
|
||||
while (Lex.getKind() != lltok::rbrace && Lex.getKind() != lltok::kw_end)
|
||||
if (ParseBasicBlock(PFS)) return true;
|
||||
|
||||
@ -3232,7 +3216,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
|
||||
// Look up the callee.
|
||||
Value *Callee;
|
||||
if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
|
||||
if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
|
||||
|
||||
// FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
|
||||
// function attributes.
|
||||
@ -3578,7 +3562,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
||||
|
||||
// Look up the callee.
|
||||
Value *Callee;
|
||||
if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
|
||||
if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
|
||||
|
||||
// FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
|
||||
// function attributes.
|
||||
@ -3660,7 +3644,7 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
|
||||
}
|
||||
}
|
||||
|
||||
if (Size && Size->getType() != Type::getInt32Ty(Context))
|
||||
if (Size && !Size->getType()->isInteger(32))
|
||||
return Error(SizeLoc, "element count must be i32");
|
||||
|
||||
if (isAlloca) {
|
||||
@ -3840,7 +3824,8 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
/// ::= Element (',' Element)*
|
||||
/// Element
|
||||
/// ::= 'null' | TypeAndValue
|
||||
bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts) {
|
||||
bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
|
||||
PerFunctionState *PFS) {
|
||||
do {
|
||||
// Null is a special case since it is typeless.
|
||||
if (EatIfPresent(lltok::kw_null)) {
|
||||
@ -3851,8 +3836,8 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts) {
|
||||
Value *V = 0;
|
||||
PATypeHolder Ty(Type::getVoidTy(Context));
|
||||
ValID ID;
|
||||
if (ParseType(Ty) || ParseValID(ID) ||
|
||||
ConvertGlobalOrMetadataValIDToValue(Ty, ID, V))
|
||||
if (ParseType(Ty) || ParseValID(ID, PFS) ||
|
||||
ConvertValIDToValue(Ty, ID, V, PFS))
|
||||
return true;
|
||||
|
||||
Elts.push_back(V);
|
||||
|
@ -216,17 +216,6 @@ namespace llvm {
|
||||
bool ParseFunctionType(PATypeHolder &Result);
|
||||
PATypeHolder HandleUpRefs(const Type *Ty);
|
||||
|
||||
// Constants.
|
||||
bool ParseValID(ValID &ID);
|
||||
bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V);
|
||||
bool ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
|
||||
Value *&V);
|
||||
bool ParseGlobalValue(const Type *Ty, Constant *&V);
|
||||
bool ParseGlobalTypeAndValue(Constant *&V);
|
||||
bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
|
||||
bool ParseMDNodeVector(SmallVectorImpl<Value*> &);
|
||||
|
||||
|
||||
// Function Semantic Analysis.
|
||||
class PerFunctionState {
|
||||
LLParser &P;
|
||||
@ -270,7 +259,7 @@ namespace llvm {
|
||||
};
|
||||
|
||||
bool ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
|
||||
PerFunctionState &PFS);
|
||||
PerFunctionState *PFS);
|
||||
|
||||
bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS);
|
||||
bool ParseValue(const Type *Ty, Value *&V, LocTy &Loc,
|
||||
@ -301,6 +290,13 @@ namespace llvm {
|
||||
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
||||
PerFunctionState &PFS);
|
||||
|
||||
// Constant Parsing.
|
||||
bool ParseValID(ValID &ID, PerFunctionState *PFS = NULL);
|
||||
bool ParseGlobalValue(const Type *Ty, Constant *&V);
|
||||
bool ParseGlobalTypeAndValue(Constant *&V);
|
||||
bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
|
||||
bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS);
|
||||
|
||||
// Function Parsing.
|
||||
struct ArgInfo {
|
||||
LocTy Loc;
|
||||
|
@ -18,9 +18,9 @@ using namespace llvm;
|
||||
|
||||
/* Builds a module from the bitcode in the specified memory buffer, returning a
|
||||
reference to the module via the OutModule parameter. Returns 0 on success.
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage) {
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), getGlobalContext(),
|
||||
@ -34,9 +34,10 @@ int LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage) {
|
||||
LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule,
|
||||
char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutModule = wrap(ParseBitcodeFile(unwrap(MemBuf), *unwrap(ContextRef),
|
||||
@ -53,9 +54,9 @@ int LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
|
||||
/* Reads a module from the specified path, returning via the OutModule parameter
|
||||
a module provider which performs lazy deserialization. Returns 0 on success.
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage) {
|
||||
LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), getGlobalContext(),
|
||||
@ -70,10 +71,10 @@ int LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage) {
|
||||
LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage) {
|
||||
std::string Message;
|
||||
|
||||
*OutMP = wrap(getBitcodeModuleProvider(unwrap(MemBuf), *unwrap(ContextRef),
|
||||
|
@ -737,7 +737,7 @@ bool BitcodeReader::ParseValueSymbolTable() {
|
||||
}
|
||||
|
||||
bool BitcodeReader::ParseMetadata() {
|
||||
unsigned NextValueNo = MDValueList.size();
|
||||
unsigned NextMDValueNo = MDValueList.size();
|
||||
|
||||
if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
|
||||
return Error("Malformed block record");
|
||||
@ -766,6 +766,7 @@ bool BitcodeReader::ParseMetadata() {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool IsFunctionLocal = false;
|
||||
// Read a record.
|
||||
Record.clear();
|
||||
switch (Stream.ReadRecord(Code, Record)) {
|
||||
@ -787,17 +788,25 @@ bool BitcodeReader::ParseMetadata() {
|
||||
|
||||
// Read named metadata elements.
|
||||
unsigned Size = Record.size();
|
||||
SmallVector<MetadataBase*, 8> Elts;
|
||||
SmallVector<MDNode *, 8> Elts;
|
||||
for (unsigned i = 0; i != Size; ++i) {
|
||||
Value *MD = MDValueList.getValueFwdRef(Record[i]);
|
||||
if (MetadataBase *B = dyn_cast<MetadataBase>(MD))
|
||||
Elts.push_back(B);
|
||||
if (Record[i] == ~0U) {
|
||||
Elts.push_back(NULL);
|
||||
continue;
|
||||
}
|
||||
MDNode *MD = dyn_cast<MDNode>(MDValueList.getValueFwdRef(Record[i]));
|
||||
if (MD == 0)
|
||||
return Error("Malformed metadata record");
|
||||
Elts.push_back(MD);
|
||||
}
|
||||
Value *V = NamedMDNode::Create(Context, Name.str(), Elts.data(),
|
||||
Elts.size(), TheModule);
|
||||
MDValueList.AssignValue(V, NextValueNo++);
|
||||
MDValueList.AssignValue(V, NextMDValueNo++);
|
||||
break;
|
||||
}
|
||||
case bitc::METADATA_FN_NODE:
|
||||
IsFunctionLocal = true;
|
||||
// fall-through
|
||||
case bitc::METADATA_NODE: {
|
||||
if (Record.empty() || Record.size() % 2 == 1)
|
||||
return Error("Invalid METADATA_NODE record");
|
||||
@ -808,13 +817,15 @@ bool BitcodeReader::ParseMetadata() {
|
||||
const Type *Ty = getTypeByID(Record[i], false);
|
||||
if (Ty->isMetadataTy())
|
||||
Elts.push_back(MDValueList.getValueFwdRef(Record[i+1]));
|
||||
else if (Ty != Type::getVoidTy(Context))
|
||||
else if (!Ty->isVoidTy())
|
||||
Elts.push_back(ValueList.getValueFwdRef(Record[i+1], Ty));
|
||||
else
|
||||
Elts.push_back(NULL);
|
||||
}
|
||||
Value *V = MDNode::get(Context, &Elts[0], Elts.size());
|
||||
MDValueList.AssignValue(V, NextValueNo++);
|
||||
Value *V = MDNode::getWhenValsUnresolved(Context, &Elts[0], Elts.size(),
|
||||
IsFunctionLocal);
|
||||
IsFunctionLocal = false;
|
||||
MDValueList.AssignValue(V, NextMDValueNo++);
|
||||
break;
|
||||
}
|
||||
case bitc::METADATA_STRING: {
|
||||
@ -825,7 +836,7 @@ bool BitcodeReader::ParseMetadata() {
|
||||
String[i] = Record[i];
|
||||
Value *V = MDString::get(Context,
|
||||
StringRef(String.data(), String.size()));
|
||||
MDValueList.AssignValue(V, NextValueNo++);
|
||||
MDValueList.AssignValue(V, NextMDValueNo++);
|
||||
break;
|
||||
}
|
||||
case bitc::METADATA_KIND: {
|
||||
@ -1646,6 +1657,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
case bitc::METADATA_ATTACHMENT_ID:
|
||||
if (ParseMetadataAttachment()) return true;
|
||||
break;
|
||||
case bitc::METADATA_BLOCK_ID:
|
||||
if (ParseMetadata()) return true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -2238,7 +2252,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
}
|
||||
|
||||
// Non-void values get registered in the value table for future use.
|
||||
if (I && I->getType() != Type::getVoidTy(Context))
|
||||
if (I && !I->getType()->isVoidTy())
|
||||
ValueList.AssignValue(I, NextValueNo++);
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,9 @@ static void WriteMDNode(const MDNode *N,
|
||||
Record.push_back(0);
|
||||
}
|
||||
}
|
||||
Stream.EmitRecord(bitc::METADATA_NODE, Record, 0);
|
||||
unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE :
|
||||
bitc::METADATA_NODE;
|
||||
Stream.EmitRecord(MDCode, Record, 0);
|
||||
Record.clear();
|
||||
}
|
||||
|
||||
@ -497,11 +499,13 @@ static void WriteModuleMetadata(const ValueEnumerator &VE,
|
||||
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
|
||||
|
||||
if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first)) {
|
||||
if (!StartedMetadataBlock) {
|
||||
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
||||
StartedMetadataBlock = true;
|
||||
if (!N->isFunctionLocal()) {
|
||||
if (!StartedMetadataBlock) {
|
||||
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
||||
StartedMetadataBlock = true;
|
||||
}
|
||||
WriteMDNode(N, VE, Stream, Record);
|
||||
}
|
||||
WriteMDNode(N, VE, Stream, Record);
|
||||
} else if (const MDString *MDS = dyn_cast<MDString>(Vals[i].first)) {
|
||||
if (!StartedMetadataBlock) {
|
||||
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
||||
@ -528,10 +532,9 @@ static void WriteModuleMetadata(const ValueEnumerator &VE,
|
||||
}
|
||||
|
||||
// Write name.
|
||||
std::string Str = NMD->getNameStr();
|
||||
const char *StrBegin = Str.c_str();
|
||||
for (unsigned i = 0, e = Str.length(); i != e; ++i)
|
||||
Record.push_back(StrBegin[i]);
|
||||
StringRef Str = NMD->getName();
|
||||
for (unsigned i = 0, e = Str.size(); i != e; ++i)
|
||||
Record.push_back(Str[i]);
|
||||
Stream.EmitRecord(bitc::METADATA_NAME, Record, 0/*TODO*/);
|
||||
Record.clear();
|
||||
|
||||
@ -540,7 +543,7 @@ static void WriteModuleMetadata(const ValueEnumerator &VE,
|
||||
if (NMD->getOperand(i))
|
||||
Record.push_back(VE.getValueID(NMD->getOperand(i)));
|
||||
else
|
||||
Record.push_back(0);
|
||||
Record.push_back(~0U);
|
||||
}
|
||||
Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0);
|
||||
Record.clear();
|
||||
@ -551,6 +554,27 @@ static void WriteModuleMetadata(const ValueEnumerator &VE,
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
static void WriteFunctionLocalMetadata(const Function &F,
|
||||
const ValueEnumerator &VE,
|
||||
BitstreamWriter &Stream) {
|
||||
bool StartedMetadataBlock = false;
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
const ValueEnumerator::ValueList &Vals = VE.getMDValues();
|
||||
|
||||
for (unsigned i = 0, e = Vals.size(); i != e; ++i)
|
||||
if (const MDNode *N = dyn_cast<MDNode>(Vals[i].first))
|
||||
if (N->getFunction() == &F) {
|
||||
if (!StartedMetadataBlock) {
|
||||
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
|
||||
StartedMetadataBlock = true;
|
||||
}
|
||||
WriteMDNode(N, VE, Stream, Record);
|
||||
}
|
||||
|
||||
if (StartedMetadataBlock)
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
static void WriteMetadataAttachment(const Function &F,
|
||||
const ValueEnumerator &VE,
|
||||
BitstreamWriter &Stream) {
|
||||
@ -1194,6 +1218,9 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE,
|
||||
VE.getFunctionConstantRange(CstStart, CstEnd);
|
||||
WriteConstants(CstStart, CstEnd, VE, Stream, false);
|
||||
|
||||
// If there is function-local metadata, emit it now.
|
||||
WriteFunctionLocalMetadata(F, VE, Stream);
|
||||
|
||||
// Keep a running idea of what the instruction ID is.
|
||||
unsigned InstID = CstEnd;
|
||||
|
||||
|
@ -74,9 +74,10 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
|
||||
// Enumerate types used by the type symbol table.
|
||||
EnumerateTypeSymbolTable(M->getTypeSymbolTable());
|
||||
|
||||
// Insert constants that are named at module level into the slot pool so that
|
||||
// the module symbol table can refer to them...
|
||||
// Insert constants and metadata that are named at module level into the slot
|
||||
// pool so that the module symbol table can refer to them...
|
||||
EnumerateValueSymbolTable(M->getValueSymbolTable());
|
||||
EnumerateMDSymbolTable(M->getMDSymbolTable());
|
||||
|
||||
SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;
|
||||
|
||||
@ -90,8 +91,13 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
|
||||
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
||||
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;++I){
|
||||
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
|
||||
OI != E; ++OI)
|
||||
OI != E; ++OI) {
|
||||
if (MDNode *MD = dyn_cast<MDNode>(*OI))
|
||||
if (MD->isFunctionLocal())
|
||||
// These will get enumerated during function-incorporation.
|
||||
continue;
|
||||
EnumerateOperandType(*OI);
|
||||
}
|
||||
EnumerateType(I->getType());
|
||||
if (const CallInst *CI = dyn_cast<CallInst>(I))
|
||||
EnumerateAttributes(CI->getAttributes());
|
||||
@ -196,6 +202,33 @@ void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
|
||||
EnumerateValue(VI->getValue());
|
||||
}
|
||||
|
||||
/// EnumerateMDSymbolTable - Insert all of the values in the specified metadata
|
||||
/// table.
|
||||
void ValueEnumerator::EnumerateMDSymbolTable(const MDSymbolTable &MST) {
|
||||
for (MDSymbolTable::const_iterator MI = MST.begin(), ME = MST.end();
|
||||
MI != ME; ++MI)
|
||||
EnumerateValue(MI->getValue());
|
||||
}
|
||||
|
||||
void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
|
||||
// Check to see if it's already in!
|
||||
unsigned &MDValueID = MDValueMap[MD];
|
||||
if (MDValueID) {
|
||||
// Increment use count.
|
||||
MDValues[MDValueID-1].second++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Enumerate the type of this value.
|
||||
EnumerateType(MD->getType());
|
||||
|
||||
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
|
||||
if (MDNode *E = MD->getOperand(i))
|
||||
EnumerateValue(E);
|
||||
MDValues.push_back(std::make_pair(MD, 1U));
|
||||
MDValueMap[MD] = Values.size();
|
||||
}
|
||||
|
||||
void ValueEnumerator::EnumerateMetadata(const MetadataBase *MD) {
|
||||
// Check to see if it's already in!
|
||||
unsigned &MDValueID = MDValueMap[MD];
|
||||
@ -212,7 +245,7 @@ void ValueEnumerator::EnumerateMetadata(const MetadataBase *MD) {
|
||||
MDValues.push_back(std::make_pair(MD, 1U));
|
||||
MDValueMap[MD] = MDValues.size();
|
||||
MDValueID = MDValues.size();
|
||||
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
|
||||
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
|
||||
if (Value *V = N->getOperand(i))
|
||||
EnumerateValue(V);
|
||||
else
|
||||
@ -221,14 +254,6 @@ void ValueEnumerator::EnumerateMetadata(const MetadataBase *MD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (const NamedMDNode *N = dyn_cast<NamedMDNode>(MD)) {
|
||||
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
|
||||
EnumerateValue(N->getOperand(i));
|
||||
MDValues.push_back(std::make_pair(MD, 1U));
|
||||
MDValueMap[MD] = Values.size();
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the value.
|
||||
assert(isa<MDString>(MD) && "Unknown metadata kind");
|
||||
MDValues.push_back(std::make_pair(MD, 1U));
|
||||
@ -239,6 +264,8 @@ void ValueEnumerator::EnumerateValue(const Value *V) {
|
||||
assert(!V->getType()->isVoidTy() && "Can't insert void values!");
|
||||
if (const MetadataBase *MB = dyn_cast<MetadataBase>(V))
|
||||
return EnumerateMetadata(MB);
|
||||
else if (const NamedMDNode *NMD = dyn_cast<NamedMDNode>(V))
|
||||
return EnumerateNamedMDNode(NMD);
|
||||
|
||||
// Check to see if it's already in!
|
||||
unsigned &ValueID = ValueMap[V];
|
||||
@ -309,6 +336,7 @@ void ValueEnumerator::EnumerateType(const Type *Ty) {
|
||||
// walk through it, enumerating the types of the constant.
|
||||
void ValueEnumerator::EnumerateOperandType(const Value *V) {
|
||||
EnumerateType(V->getType());
|
||||
|
||||
if (const Constant *C = dyn_cast<Constant>(V)) {
|
||||
// If this constant is already enumerated, ignore it, we know its type must
|
||||
// be enumerated.
|
||||
@ -382,7 +410,15 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
|
||||
// Add all of the instructions.
|
||||
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
|
||||
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
|
||||
if (I->getType() != Type::getVoidTy(F.getContext()))
|
||||
for (User::const_op_iterator OI = I->op_begin(), E = I->op_end();
|
||||
OI != E; ++OI) {
|
||||
if (MDNode *MD = dyn_cast<MDNode>(*OI))
|
||||
if (!MD->isFunctionLocal())
|
||||
// These were already enumerated during ValueEnumerator creation.
|
||||
continue;
|
||||
EnumerateOperandType(*OI);
|
||||
}
|
||||
if (!I->getType()->isVoidTy())
|
||||
EnumerateValue(I);
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,11 @@ class BasicBlock;
|
||||
class Function;
|
||||
class Module;
|
||||
class MetadataBase;
|
||||
class NamedMDNode;
|
||||
class AttrListPtr;
|
||||
class TypeSymbolTable;
|
||||
class ValueSymbolTable;
|
||||
class MDSymbolTable;
|
||||
|
||||
class ValueEnumerator {
|
||||
public:
|
||||
@ -126,6 +128,7 @@ class ValueEnumerator {
|
||||
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
|
||||
|
||||
void EnumerateMetadata(const MetadataBase *MD);
|
||||
void EnumerateNamedMDNode(const NamedMDNode *NMD);
|
||||
void EnumerateValue(const Value *V);
|
||||
void EnumerateType(const Type *T);
|
||||
void EnumerateOperandType(const Value *V);
|
||||
@ -133,6 +136,7 @@ class ValueEnumerator {
|
||||
|
||||
void EnumerateTypeSymbolTable(const TypeSymbolTable &ST);
|
||||
void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
|
||||
void EnumerateMDSymbolTable(const MDSymbolTable &ST);
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===----- AggressiveAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===//
|
||||
//===----- AggressiveAntiDepBreaker.cpp - Anti-dep breaker ----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -77,18 +77,18 @@ unsigned AggressiveAntiDepState::UnionGroups(unsigned Reg1, unsigned Reg2)
|
||||
{
|
||||
assert(GroupNodes[0] == 0 && "GroupNode 0 not parent!");
|
||||
assert(GroupNodeIndices[0] == 0 && "Reg 0 not in Group 0!");
|
||||
|
||||
|
||||
// find group for each register
|
||||
unsigned Group1 = GetGroup(Reg1);
|
||||
unsigned Group2 = GetGroup(Reg2);
|
||||
|
||||
|
||||
// if either group is 0, then that must become the parent
|
||||
unsigned Parent = (Group1 == 0) ? Group1 : Group2;
|
||||
unsigned Other = (Parent == Group1) ? Group2 : Group1;
|
||||
GroupNodes.at(Other) = Parent;
|
||||
return Parent;
|
||||
}
|
||||
|
||||
|
||||
unsigned AggressiveAntiDepState::LeaveGroup(unsigned Reg)
|
||||
{
|
||||
// Create a new GroupNode for Reg. Reg's existing GroupNode must
|
||||
@ -111,7 +111,7 @@ bool AggressiveAntiDepState::IsLive(unsigned Reg)
|
||||
|
||||
AggressiveAntiDepBreaker::
|
||||
AggressiveAntiDepBreaker(MachineFunction& MFi,
|
||||
TargetSubtarget::RegClassVector& CriticalPathRCs) :
|
||||
TargetSubtarget::RegClassVector& CriticalPathRCs) :
|
||||
AntiDepBreaker(), MF(MFi),
|
||||
MRI(MF.getRegInfo()),
|
||||
TRI(MF.getTarget().getRegisterInfo()),
|
||||
@ -126,9 +126,9 @@ AggressiveAntiDepBreaker(MachineFunction& MFi,
|
||||
else
|
||||
CriticalPathSet |= CPSet;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(dbgs() << "AntiDep Critical-Path Registers:");
|
||||
DEBUG(for (int r = CriticalPathSet.find_first(); r != -1;
|
||||
DEBUG(for (int r = CriticalPathSet.find_first(); r != -1;
|
||||
r = CriticalPathSet.find_next(r))
|
||||
dbgs() << " " << TRI->getName(r));
|
||||
DEBUG(dbgs() << '\n');
|
||||
@ -232,10 +232,11 @@ void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,
|
||||
// schedule region).
|
||||
if (State->IsLive(Reg)) {
|
||||
DEBUG(if (State->GetGroup(Reg) != 0)
|
||||
dbgs() << " " << TRI->getName(Reg) << "=g" <<
|
||||
dbgs() << " " << TRI->getName(Reg) << "=g" <<
|
||||
State->GetGroup(Reg) << "->g0(region live-out)");
|
||||
State->UnionGroups(Reg, 0);
|
||||
} else if ((DefIndices[Reg] < InsertPosIndex) && (DefIndices[Reg] >= Count)) {
|
||||
} else if ((DefIndices[Reg] < InsertPosIndex)
|
||||
&& (DefIndices[Reg] >= Count)) {
|
||||
DefIndices[Reg] = Count;
|
||||
}
|
||||
}
|
||||
@ -266,7 +267,7 @@ void AggressiveAntiDepBreaker::GetPassthruRegs(MachineInstr *MI,
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||
MachineOperand &MO = MI->getOperand(i);
|
||||
if (!MO.isReg()) continue;
|
||||
if ((MO.isDef() && MI->isRegTiedToUseOperand(i)) ||
|
||||
if ((MO.isDef() && MI->isRegTiedToUseOperand(i)) ||
|
||||
IsImplicitDefUse(MI, MO)) {
|
||||
const unsigned Reg = MO.getReg();
|
||||
PassthruRegs.insert(Reg);
|
||||
@ -320,11 +321,12 @@ static SUnit *CriticalPathStep(SUnit *SU) {
|
||||
}
|
||||
|
||||
void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
|
||||
const char *tag, const char *header,
|
||||
const char *tag,
|
||||
const char *header,
|
||||
const char *footer) {
|
||||
unsigned *KillIndices = State->GetKillIndices();
|
||||
unsigned *DefIndices = State->GetDefIndices();
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
RegRefs = State->GetRegRefs();
|
||||
|
||||
if (!State->IsLive(Reg)) {
|
||||
@ -355,10 +357,12 @@ void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
|
||||
DEBUG(if ((header == NULL) && (footer != NULL)) dbgs() << footer);
|
||||
}
|
||||
|
||||
void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count,
|
||||
std::set<unsigned>& PassthruRegs) {
|
||||
void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
|
||||
unsigned Count,
|
||||
std::set<unsigned>& PassthruRegs)
|
||||
{
|
||||
unsigned *DefIndices = State->GetDefIndices();
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
RegRefs = State->GetRegRefs();
|
||||
|
||||
// Handle dead defs by simulating a last-use of the register just
|
||||
@ -371,7 +375,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
|
||||
if (!MO.isReg() || !MO.isDef()) continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Reg == 0) continue;
|
||||
|
||||
|
||||
HandleLastUse(Reg, Count + 1, "", "\tDead Def: ", "\n");
|
||||
}
|
||||
|
||||
@ -382,7 +386,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Reg == 0) continue;
|
||||
|
||||
DEBUG(dbgs() << " " << TRI->getName(Reg) << "=g" << State->GetGroup(Reg));
|
||||
DEBUG(dbgs() << " " << TRI->getName(Reg) << "=g" << State->GetGroup(Reg));
|
||||
|
||||
// If MI's defs have a special allocation requirement, don't allow
|
||||
// any def registers to be changed. Also assume all registers
|
||||
@ -398,11 +402,11 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
|
||||
unsigned AliasReg = *Alias;
|
||||
if (State->IsLive(AliasReg)) {
|
||||
State->UnionGroups(Reg, AliasReg);
|
||||
DEBUG(dbgs() << "->g" << State->GetGroup(Reg) << "(via " <<
|
||||
DEBUG(dbgs() << "->g" << State->GetGroup(Reg) << "(via " <<
|
||||
TRI->getName(AliasReg) << ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Note register reference...
|
||||
const TargetRegisterClass *RC = NULL;
|
||||
if (i < MI->getDesc().getNumOperands())
|
||||
@ -438,7 +442,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
|
||||
void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||
unsigned Count) {
|
||||
DEBUG(dbgs() << "\tUse Groups:");
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
RegRefs = State->GetRegRefs();
|
||||
|
||||
// Scan the register uses for this instruction and update
|
||||
@ -448,9 +452,9 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||
if (!MO.isReg() || !MO.isUse()) continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Reg == 0) continue;
|
||||
|
||||
DEBUG(dbgs() << " " << TRI->getName(Reg) << "=g" <<
|
||||
State->GetGroup(Reg));
|
||||
|
||||
DEBUG(dbgs() << " " << TRI->getName(Reg) << "=g" <<
|
||||
State->GetGroup(Reg));
|
||||
|
||||
// It wasn't previously live but now it is, this is a kill. Forget
|
||||
// the previous live-range information and start a new live-range
|
||||
@ -472,7 +476,7 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||
AggressiveAntiDepState::RegisterReference RR = { &MO, RC };
|
||||
RegRefs.insert(std::make_pair(Reg, RR));
|
||||
}
|
||||
|
||||
|
||||
DEBUG(dbgs() << '\n');
|
||||
|
||||
// Form a group of all defs and uses of a KILL instruction to ensure
|
||||
@ -486,7 +490,7 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||
if (!MO.isReg()) continue;
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Reg == 0) continue;
|
||||
|
||||
|
||||
if (FirstReg != 0) {
|
||||
DEBUG(dbgs() << "=" << TRI->getName(Reg));
|
||||
State->UnionGroups(FirstReg, Reg);
|
||||
@ -495,7 +499,7 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||
FirstReg = Reg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEBUG(dbgs() << "->g" << State->GetGroup(FirstReg) << '\n');
|
||||
}
|
||||
}
|
||||
@ -507,13 +511,14 @@ BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) {
|
||||
// Check all references that need rewriting for Reg. For each, use
|
||||
// the corresponding register class to narrow the set of registers
|
||||
// that are appropriate for renaming.
|
||||
std::pair<std::multimap<unsigned,
|
||||
std::pair<std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference>::iterator,
|
||||
std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference>::iterator>
|
||||
Range = State->GetRegRefs().equal_range(Reg);
|
||||
for (std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>::iterator
|
||||
Q = Range.first, QE = Range.second; Q != QE; ++Q) {
|
||||
for (std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference>::iterator Q = Range.first,
|
||||
QE = Range.second; Q != QE; ++Q) {
|
||||
const TargetRegisterClass *RC = Q->second.RC;
|
||||
if (RC == NULL) continue;
|
||||
|
||||
@ -527,9 +532,9 @@ BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) {
|
||||
|
||||
DEBUG(dbgs() << " " << RC->getName());
|
||||
}
|
||||
|
||||
|
||||
return BV;
|
||||
}
|
||||
}
|
||||
|
||||
bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
unsigned AntiDepGroupIndex,
|
||||
@ -537,7 +542,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
std::map<unsigned, unsigned> &RenameMap) {
|
||||
unsigned *KillIndices = State->GetKillIndices();
|
||||
unsigned *DefIndices = State->GetDefIndices();
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
RegRefs = State->GetRegRefs();
|
||||
|
||||
// Collect all referenced registers in the same group as
|
||||
@ -552,7 +557,8 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
// Find the "superest" register in the group. At the same time,
|
||||
// collect the BitVector of registers that can be used to rename
|
||||
// each register.
|
||||
DEBUG(dbgs() << "\tRename Candidates for Group g" << AntiDepGroupIndex << ":\n");
|
||||
DEBUG(dbgs() << "\tRename Candidates for Group g" << AntiDepGroupIndex
|
||||
<< ":\n");
|
||||
std::map<unsigned, BitVector> RenameRegisterMap;
|
||||
unsigned SuperReg = 0;
|
||||
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
||||
@ -563,7 +569,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
// If Reg has any references, then collect possible rename regs
|
||||
if (RegRefs.count(Reg) > 0) {
|
||||
DEBUG(dbgs() << "\t\t" << TRI->getName(Reg) << ":");
|
||||
|
||||
|
||||
BitVector BV = GetRenameRegisters(Reg);
|
||||
RenameRegisterMap.insert(std::pair<unsigned, BitVector>(Reg, BV));
|
||||
|
||||
@ -590,7 +596,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
static int renamecnt = 0;
|
||||
if (renamecnt++ % DebugDiv != DebugMod)
|
||||
return false;
|
||||
|
||||
|
||||
dbgs() << "*** Performing rename " << TRI->getName(SuperReg) <<
|
||||
" for debug ***\n";
|
||||
}
|
||||
@ -600,9 +606,9 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
// order. If that register is available, and the corresponding
|
||||
// registers are available for the other group subregisters, then we
|
||||
// can use those registers to rename.
|
||||
const TargetRegisterClass *SuperRC =
|
||||
const TargetRegisterClass *SuperRC =
|
||||
TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other);
|
||||
|
||||
|
||||
const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF);
|
||||
const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF);
|
||||
if (RB == RE) {
|
||||
@ -624,7 +630,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
const unsigned NewSuperReg = *R;
|
||||
// Don't replace a register with itself.
|
||||
if (NewSuperReg == SuperReg) continue;
|
||||
|
||||
|
||||
DEBUG(dbgs() << " [" << TRI->getName(NewSuperReg) << ':');
|
||||
RenameMap.clear();
|
||||
|
||||
@ -643,7 +649,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << " " << TRI->getName(NewReg));
|
||||
|
||||
|
||||
// Check if Reg can be renamed to NewReg.
|
||||
BitVector BV = RenameRegisterMap[Reg];
|
||||
if (!BV.test(NewReg)) {
|
||||
@ -663,7 +669,8 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
for (const unsigned *Alias = TRI->getAliasSet(NewReg);
|
||||
*Alias; ++Alias) {
|
||||
unsigned AliasReg = *Alias;
|
||||
if (State->IsLive(AliasReg) || (KillIndices[Reg] > DefIndices[AliasReg])) {
|
||||
if (State->IsLive(AliasReg) ||
|
||||
(KillIndices[Reg] > DefIndices[AliasReg])) {
|
||||
DEBUG(dbgs() << "(alias " << TRI->getName(AliasReg) << " live)");
|
||||
found = true;
|
||||
break;
|
||||
@ -672,11 +679,11 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
||||
if (found)
|
||||
goto next_super_reg;
|
||||
}
|
||||
|
||||
|
||||
// Record that 'Reg' can be renamed to 'NewReg'.
|
||||
RenameMap.insert(std::pair<unsigned, unsigned>(Reg, NewReg));
|
||||
}
|
||||
|
||||
|
||||
// If we fall-out here, then every register in the group can be
|
||||
// renamed, as recorded in RenameMap.
|
||||
RenameOrder.erase(SuperRC);
|
||||
@ -704,13 +711,13 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
unsigned InsertPosIndex) {
|
||||
unsigned *KillIndices = State->GetKillIndices();
|
||||
unsigned *DefIndices = State->GetDefIndices();
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
|
||||
RegRefs = State->GetRegRefs();
|
||||
|
||||
// The code below assumes that there is at least one instruction,
|
||||
// so just duck out immediately if the block is empty.
|
||||
if (SUnits.empty()) return 0;
|
||||
|
||||
|
||||
// For each regclass the next register to use for renaming.
|
||||
RenameOrderType RenameOrder;
|
||||
|
||||
@ -729,17 +736,17 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
if (CriticalPathSet.any()) {
|
||||
for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
|
||||
SUnit *SU = &SUnits[i];
|
||||
if (!CriticalPathSU ||
|
||||
((SU->getDepth() + SU->Latency) >
|
||||
if (!CriticalPathSU ||
|
||||
((SU->getDepth() + SU->Latency) >
|
||||
(CriticalPathSU->getDepth() + CriticalPathSU->Latency))) {
|
||||
CriticalPathSU = SU;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CriticalPathMI = CriticalPathSU->getInstr();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifndef NDEBUG
|
||||
DEBUG(dbgs() << "\n===== Aggressive anti-dependency breaking\n");
|
||||
DEBUG(dbgs() << "Available regs:");
|
||||
for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) {
|
||||
@ -766,7 +773,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
|
||||
// Process the defs in MI...
|
||||
PrescanInstruction(MI, Count, PassthruRegs);
|
||||
|
||||
|
||||
// The dependence edges that represent anti- and output-
|
||||
// dependencies that are candidates for breaking.
|
||||
std::vector<SDep*> Edges;
|
||||
@ -779,7 +786,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
if (MI == CriticalPathMI) {
|
||||
CriticalPathSU = CriticalPathStep(CriticalPathSU);
|
||||
CriticalPathMI = (CriticalPathSU) ? CriticalPathSU->getInstr() : 0;
|
||||
} else {
|
||||
} else {
|
||||
ExcludeRegs = &CriticalPathSet;
|
||||
}
|
||||
|
||||
@ -790,14 +797,14 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
for (unsigned i = 0, e = Edges.size(); i != e; ++i) {
|
||||
SDep *Edge = Edges[i];
|
||||
SUnit *NextSU = Edge->getSUnit();
|
||||
|
||||
|
||||
if ((Edge->getKind() != SDep::Anti) &&
|
||||
(Edge->getKind() != SDep::Output)) continue;
|
||||
|
||||
|
||||
unsigned AntiDepReg = Edge->getReg();
|
||||
DEBUG(dbgs() << "\tAntidep reg: " << TRI->getName(AntiDepReg));
|
||||
assert(AntiDepReg != 0 && "Anti-dependence on reg0?");
|
||||
|
||||
|
||||
if (!AllocatableSet.test(AntiDepReg)) {
|
||||
// Don't break anti-dependencies on non-allocatable registers.
|
||||
DEBUG(dbgs() << " (non-allocatable)\n");
|
||||
@ -816,12 +823,13 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
} else {
|
||||
// No anti-dep breaking for implicit deps
|
||||
MachineOperand *AntiDepOp = MI->findRegisterDefOperand(AntiDepReg);
|
||||
assert(AntiDepOp != NULL && "Can't find index for defined register operand");
|
||||
assert(AntiDepOp != NULL &&
|
||||
"Can't find index for defined register operand");
|
||||
if ((AntiDepOp == NULL) || AntiDepOp->isImplicit()) {
|
||||
DEBUG(dbgs() << " (implicit)\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// If the SUnit has other dependencies on the SUnit that
|
||||
// it anti-depends on, don't bother breaking the
|
||||
// anti-dependency since those edges would prevent such
|
||||
@ -847,58 +855,59 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
DEBUG(dbgs() << " (real dependency)\n");
|
||||
AntiDepReg = 0;
|
||||
break;
|
||||
} else if ((P->getSUnit() != NextSU) &&
|
||||
(P->getKind() == SDep::Data) &&
|
||||
} else if ((P->getSUnit() != NextSU) &&
|
||||
(P->getKind() == SDep::Data) &&
|
||||
(P->getReg() == AntiDepReg)) {
|
||||
DEBUG(dbgs() << " (other dependency)\n");
|
||||
AntiDepReg = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (AntiDepReg == 0) continue;
|
||||
}
|
||||
|
||||
|
||||
assert(AntiDepReg != 0);
|
||||
if (AntiDepReg == 0) continue;
|
||||
|
||||
|
||||
// Determine AntiDepReg's register group.
|
||||
const unsigned GroupIndex = State->GetGroup(AntiDepReg);
|
||||
if (GroupIndex == 0) {
|
||||
DEBUG(dbgs() << " (zero group)\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
DEBUG(dbgs() << '\n');
|
||||
|
||||
|
||||
// Look for a suitable register to use to break the anti-dependence.
|
||||
std::map<unsigned, unsigned> RenameMap;
|
||||
if (FindSuitableFreeRegisters(GroupIndex, RenameOrder, RenameMap)) {
|
||||
DEBUG(dbgs() << "\tBreaking anti-dependence edge on "
|
||||
<< TRI->getName(AntiDepReg) << ":");
|
||||
|
||||
|
||||
// Handle each group register...
|
||||
for (std::map<unsigned, unsigned>::iterator
|
||||
S = RenameMap.begin(), E = RenameMap.end(); S != E; ++S) {
|
||||
unsigned CurrReg = S->first;
|
||||
unsigned NewReg = S->second;
|
||||
|
||||
DEBUG(dbgs() << " " << TRI->getName(CurrReg) << "->" <<
|
||||
TRI->getName(NewReg) << "(" <<
|
||||
|
||||
DEBUG(dbgs() << " " << TRI->getName(CurrReg) << "->" <<
|
||||
TRI->getName(NewReg) << "(" <<
|
||||
RegRefs.count(CurrReg) << " refs)");
|
||||
|
||||
|
||||
// Update the references to the old register CurrReg to
|
||||
// refer to the new register NewReg.
|
||||
std::pair<std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference>::iterator,
|
||||
std::pair<std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference>::iterator,
|
||||
std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference>::iterator>
|
||||
AggressiveAntiDepState::RegisterReference>::iterator>
|
||||
Range = RegRefs.equal_range(CurrReg);
|
||||
for (std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>::iterator
|
||||
for (std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference>::iterator
|
||||
Q = Range.first, QE = Range.second; Q != QE; ++Q) {
|
||||
Q->second.Operand->setReg(NewReg);
|
||||
}
|
||||
|
||||
|
||||
// We just went back in time and modified history; the
|
||||
// liveness information for CurrReg is now inconsistent. Set
|
||||
// the state as if it were dead.
|
||||
@ -906,7 +915,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
RegRefs.erase(NewReg);
|
||||
DefIndices[NewReg] = DefIndices[CurrReg];
|
||||
KillIndices[NewReg] = KillIndices[CurrReg];
|
||||
|
||||
|
||||
State->UnionGroups(CurrReg, 0);
|
||||
RegRefs.erase(CurrReg);
|
||||
DefIndices[CurrReg] = KillIndices[CurrReg];
|
||||
@ -915,7 +924,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
(DefIndices[CurrReg] == ~0u)) &&
|
||||
"Kill and Def maps aren't consistent for AntiDepReg!");
|
||||
}
|
||||
|
||||
|
||||
++Broken;
|
||||
DEBUG(dbgs() << '\n');
|
||||
}
|
||||
@ -924,6 +933,6 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
|
||||
|
||||
ScanInstruction(MI, Count);
|
||||
}
|
||||
|
||||
|
||||
return Broken;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
/// Class AggressiveAntiDepState
|
||||
/// Class AggressiveAntiDepState
|
||||
/// Contains all the state necessary for anti-dep breaking.
|
||||
class AggressiveAntiDepState {
|
||||
public:
|
||||
@ -54,27 +54,27 @@ namespace llvm {
|
||||
/// is the parent of a group, or point to another node to indicate
|
||||
/// that it is a member of the same group as that node.
|
||||
std::vector<unsigned> GroupNodes;
|
||||
|
||||
|
||||
/// GroupNodeIndices - For each register, the index of the GroupNode
|
||||
/// currently representing the group that the register belongs to.
|
||||
/// Register 0 is always represented by the 0 group, a group
|
||||
/// composed of registers that are not eligible for anti-aliasing.
|
||||
unsigned GroupNodeIndices[TargetRegisterInfo::FirstVirtualRegister];
|
||||
|
||||
|
||||
/// RegRefs - Map registers to all their references within a live range.
|
||||
std::multimap<unsigned, RegisterReference> RegRefs;
|
||||
|
||||
|
||||
/// KillIndices - The index of the most recent kill (proceding bottom-up),
|
||||
/// or ~0u if the register is not live.
|
||||
unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister];
|
||||
|
||||
|
||||
/// DefIndices - The index of the most recent complete def (proceding bottom
|
||||
/// up), or ~0u if the register is live.
|
||||
unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister];
|
||||
|
||||
public:
|
||||
AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB);
|
||||
|
||||
|
||||
/// GetKillIndices - Return the kill indices.
|
||||
unsigned *GetKillIndices() { return KillIndices; }
|
||||
|
||||
@ -87,13 +87,14 @@ namespace llvm {
|
||||
// GetGroup - Get the group for a register. The returned value is
|
||||
// the index of the GroupNode representing the group.
|
||||
unsigned GetGroup(unsigned Reg);
|
||||
|
||||
|
||||
// GetGroupRegs - Return a vector of the registers belonging to a
|
||||
// group. If RegRefs is non-NULL then only included referenced registers.
|
||||
void GetGroupRegs(
|
||||
unsigned Group,
|
||||
std::vector<unsigned> &Regs,
|
||||
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference> *RegRefs);
|
||||
std::multimap<unsigned,
|
||||
AggressiveAntiDepState::RegisterReference> *RegRefs);
|
||||
|
||||
// UnionGroups - Union Reg1's and Reg2's groups to form a new
|
||||
// group. Return the index of the GroupNode representing the
|
||||
@ -110,7 +111,7 @@ namespace llvm {
|
||||
};
|
||||
|
||||
|
||||
/// Class AggressiveAntiDepBreaker
|
||||
/// Class AggressiveAntiDepBreaker
|
||||
class AggressiveAntiDepBreaker : public AntiDepBreaker {
|
||||
MachineFunction& MF;
|
||||
MachineRegisterInfo &MRI;
|
||||
@ -130,14 +131,15 @@ namespace llvm {
|
||||
AggressiveAntiDepState *State;
|
||||
|
||||
public:
|
||||
AggressiveAntiDepBreaker(MachineFunction& MFi,
|
||||
AggressiveAntiDepBreaker(MachineFunction& MFi,
|
||||
TargetSubtarget::RegClassVector& CriticalPathRCs);
|
||||
~AggressiveAntiDepBreaker();
|
||||
|
||||
|
||||
/// Start - Initialize anti-dep breaking for a new basic block.
|
||||
void StartBlock(MachineBasicBlock *BB);
|
||||
|
||||
/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path
|
||||
/// BreakAntiDependencies - Identifiy anti-dependencies along the critical
|
||||
/// path
|
||||
/// of the ScheduleDAG and break them by renaming registers.
|
||||
///
|
||||
unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
@ -160,7 +162,7 @@ namespace llvm {
|
||||
/// IsImplicitDefUse - Return true if MO represents a register
|
||||
/// that is both implicitly used and defined in MI
|
||||
bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO);
|
||||
|
||||
|
||||
/// GetPassthruRegs - If MI implicitly def/uses a register, then
|
||||
/// return that register and all subregisters.
|
||||
void GetPassthruRegs(MachineInstr *MI, std::set<unsigned>& PassthruRegs);
|
||||
|
@ -807,124 +807,145 @@ void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const {
|
||||
// Print out the specified constant, without a storage class. Only the
|
||||
// constants valid in constant expressions can occur here.
|
||||
void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
|
||||
if (CV->isNullValue() || isa<UndefValue>(CV))
|
||||
if (CV->isNullValue() || isa<UndefValue>(CV)) {
|
||||
O << '0';
|
||||
else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
|
||||
O << CI->getZExtValue();
|
||||
} else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
|
||||
// This is a constant address for a global variable or function. Use the
|
||||
// name of the variable or function as the address value.
|
||||
O << Mang->getMangledName(GV);
|
||||
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
|
||||
const TargetData *TD = TM.getTargetData();
|
||||
unsigned Opcode = CE->getOpcode();
|
||||
switch (Opcode) {
|
||||
case Instruction::Trunc:
|
||||
case Instruction::ZExt:
|
||||
case Instruction::SExt:
|
||||
case Instruction::FPTrunc:
|
||||
case Instruction::FPExt:
|
||||
case Instruction::UIToFP:
|
||||
case Instruction::SIToFP:
|
||||
case Instruction::FPToUI:
|
||||
case Instruction::FPToSI:
|
||||
llvm_unreachable("FIXME: Don't support this constant cast expr");
|
||||
case Instruction::GetElementPtr: {
|
||||
// generate a symbolic expression for the byte address
|
||||
const Constant *ptrVal = CE->getOperand(0);
|
||||
SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
|
||||
if (int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
|
||||
idxVec.size())) {
|
||||
// Truncate/sext the offset to the pointer size.
|
||||
if (TD->getPointerSizeInBits() != 64) {
|
||||
int SExtAmount = 64-TD->getPointerSizeInBits();
|
||||
Offset = (Offset << SExtAmount) >> SExtAmount;
|
||||
}
|
||||
|
||||
if (Offset)
|
||||
O << '(';
|
||||
EmitConstantValueOnly(ptrVal);
|
||||
if (Offset > 0)
|
||||
O << ") + " << Offset;
|
||||
else if (Offset < 0)
|
||||
O << ") - " << -Offset;
|
||||
} else {
|
||||
EmitConstantValueOnly(ptrVal);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::BitCast:
|
||||
return EmitConstantValueOnly(CE->getOperand(0));
|
||||
|
||||
case Instruction::IntToPtr: {
|
||||
// Handle casts to pointers by changing them into casts to the appropriate
|
||||
// integer type. This promotes constant folding and simplifies this code.
|
||||
Constant *Op = CE->getOperand(0);
|
||||
Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()),
|
||||
false/*ZExt*/);
|
||||
return EmitConstantValueOnly(Op);
|
||||
}
|
||||
|
||||
|
||||
case Instruction::PtrToInt: {
|
||||
// Support only foldable casts to/from pointers that can be eliminated by
|
||||
// changing the pointer to the appropriately sized integer type.
|
||||
Constant *Op = CE->getOperand(0);
|
||||
const Type *Ty = CE->getType();
|
||||
|
||||
// We can emit the pointer value into this slot if the slot is an
|
||||
// integer slot greater or equal to the size of the pointer.
|
||||
if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType()))
|
||||
return EmitConstantValueOnly(Op);
|
||||
|
||||
O << "((";
|
||||
EmitConstantValueOnly(Op);
|
||||
APInt ptrMask =
|
||||
APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType()));
|
||||
|
||||
SmallString<40> S;
|
||||
ptrMask.toStringUnsigned(S);
|
||||
O << ") & " << S.str() << ')';
|
||||
break;
|
||||
}
|
||||
case Instruction::Add:
|
||||
case Instruction::Sub:
|
||||
case Instruction::And:
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor:
|
||||
O << '(';
|
||||
EmitConstantValueOnly(CE->getOperand(0));
|
||||
O << ')';
|
||||
switch (Opcode) {
|
||||
case Instruction::Add:
|
||||
O << " + ";
|
||||
break;
|
||||
case Instruction::Sub:
|
||||
O << " - ";
|
||||
break;
|
||||
case Instruction::And:
|
||||
O << " & ";
|
||||
break;
|
||||
case Instruction::Or:
|
||||
O << " | ";
|
||||
break;
|
||||
case Instruction::Xor:
|
||||
O << " ^ ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
O << '(';
|
||||
EmitConstantValueOnly(CE->getOperand(1));
|
||||
O << ')';
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unsupported operator!");
|
||||
}
|
||||
} else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
|
||||
GetBlockAddressSymbol(BA)->print(O, MAI);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
|
||||
if (CE == 0) {
|
||||
llvm_unreachable("Unknown constant value!");
|
||||
O << '0';
|
||||
return;
|
||||
}
|
||||
|
||||
switch (CE->getOpcode()) {
|
||||
case Instruction::ZExt:
|
||||
case Instruction::SExt:
|
||||
case Instruction::FPTrunc:
|
||||
case Instruction::FPExt:
|
||||
case Instruction::UIToFP:
|
||||
case Instruction::SIToFP:
|
||||
case Instruction::FPToUI:
|
||||
case Instruction::FPToSI:
|
||||
default:
|
||||
llvm_unreachable("FIXME: Don't support this constant cast expr");
|
||||
case Instruction::GetElementPtr: {
|
||||
// generate a symbolic expression for the byte address
|
||||
const TargetData *TD = TM.getTargetData();
|
||||
const Constant *ptrVal = CE->getOperand(0);
|
||||
SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
|
||||
int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
|
||||
idxVec.size());
|
||||
if (Offset == 0)
|
||||
return EmitConstantValueOnly(ptrVal);
|
||||
|
||||
// Truncate/sext the offset to the pointer size.
|
||||
if (TD->getPointerSizeInBits() != 64) {
|
||||
int SExtAmount = 64-TD->getPointerSizeInBits();
|
||||
Offset = (Offset << SExtAmount) >> SExtAmount;
|
||||
}
|
||||
|
||||
if (Offset)
|
||||
O << '(';
|
||||
EmitConstantValueOnly(ptrVal);
|
||||
if (Offset > 0)
|
||||
O << ") + " << Offset;
|
||||
else
|
||||
O << ") - " << -Offset;
|
||||
return;
|
||||
}
|
||||
case Instruction::BitCast:
|
||||
return EmitConstantValueOnly(CE->getOperand(0));
|
||||
|
||||
case Instruction::IntToPtr: {
|
||||
// Handle casts to pointers by changing them into casts to the appropriate
|
||||
// integer type. This promotes constant folding and simplifies this code.
|
||||
const TargetData *TD = TM.getTargetData();
|
||||
Constant *Op = CE->getOperand(0);
|
||||
Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()),
|
||||
false/*ZExt*/);
|
||||
return EmitConstantValueOnly(Op);
|
||||
}
|
||||
|
||||
case Instruction::PtrToInt: {
|
||||
// Support only foldable casts to/from pointers that can be eliminated by
|
||||
// changing the pointer to the appropriately sized integer type.
|
||||
Constant *Op = CE->getOperand(0);
|
||||
const Type *Ty = CE->getType();
|
||||
const TargetData *TD = TM.getTargetData();
|
||||
|
||||
// We can emit the pointer value into this slot if the slot is an
|
||||
// integer slot greater or equal to the size of the pointer.
|
||||
if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType()))
|
||||
return EmitConstantValueOnly(Op);
|
||||
|
||||
O << "((";
|
||||
EmitConstantValueOnly(Op);
|
||||
APInt ptrMask =
|
||||
APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType()));
|
||||
|
||||
SmallString<40> S;
|
||||
ptrMask.toStringUnsigned(S);
|
||||
O << ") & " << S.str() << ')';
|
||||
return;
|
||||
}
|
||||
|
||||
case Instruction::Trunc:
|
||||
// We emit the value and depend on the assembler to truncate the generated
|
||||
// expression properly. This is important for differences between
|
||||
// blockaddress labels. Since the two labels are in the same function, it
|
||||
// is reasonable to treat their delta as a 32-bit value.
|
||||
return EmitConstantValueOnly(CE->getOperand(0));
|
||||
|
||||
case Instruction::Add:
|
||||
case Instruction::Sub:
|
||||
case Instruction::And:
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor:
|
||||
O << '(';
|
||||
EmitConstantValueOnly(CE->getOperand(0));
|
||||
O << ')';
|
||||
switch (CE->getOpcode()) {
|
||||
case Instruction::Add:
|
||||
O << " + ";
|
||||
break;
|
||||
case Instruction::Sub:
|
||||
O << " - ";
|
||||
break;
|
||||
case Instruction::And:
|
||||
O << " & ";
|
||||
break;
|
||||
case Instruction::Or:
|
||||
O << " | ";
|
||||
break;
|
||||
case Instruction::Xor:
|
||||
O << " ^ ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
O << '(';
|
||||
EmitConstantValueOnly(CE->getOperand(1));
|
||||
O << ')';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1225,8 +1246,7 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
|
||||
unsigned AddrSpace) {
|
||||
const TargetData *TD = TM.getTargetData();
|
||||
unsigned BitWidth = CI->getBitWidth();
|
||||
assert(isPowerOf2_32(BitWidth) &&
|
||||
"Non-power-of-2-sized integers not handled!");
|
||||
assert((BitWidth & 63) == 0 && "only support multiples of 64-bits");
|
||||
|
||||
// We don't expect assemblers to support integer data directives
|
||||
// for more than 64 bits, so we emit the data in at most 64-bit
|
||||
@ -1239,39 +1259,34 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
|
||||
else
|
||||
Val = RawData[i];
|
||||
|
||||
if (MAI->getData64bitsDirective(AddrSpace))
|
||||
if (MAI->getData64bitsDirective(AddrSpace)) {
|
||||
O << MAI->getData64bitsDirective(AddrSpace) << Val << '\n';
|
||||
else if (TD->isBigEndian()) {
|
||||
O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32);
|
||||
if (VerboseAsm) {
|
||||
O.PadToColumn(MAI->getCommentColumn());
|
||||
O << MAI->getCommentString()
|
||||
<< " most significant half of i64 " << Val;
|
||||
}
|
||||
O << '\n';
|
||||
O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val);
|
||||
if (VerboseAsm) {
|
||||
O.PadToColumn(MAI->getCommentColumn());
|
||||
O << MAI->getCommentString()
|
||||
<< " least significant half of i64 " << Val;
|
||||
}
|
||||
O << '\n';
|
||||
} else {
|
||||
O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val);
|
||||
if (VerboseAsm) {
|
||||
O.PadToColumn(MAI->getCommentColumn());
|
||||
O << MAI->getCommentString()
|
||||
<< " least significant half of i64 " << Val;
|
||||
}
|
||||
O << '\n';
|
||||
O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32);
|
||||
if (VerboseAsm) {
|
||||
O.PadToColumn(MAI->getCommentColumn());
|
||||
O << MAI->getCommentString()
|
||||
<< " most significant half of i64 " << Val;
|
||||
}
|
||||
O << '\n';
|
||||
continue;
|
||||
}
|
||||
|
||||
// Emit two 32-bit chunks, order depends on endianness.
|
||||
unsigned FirstChunk = unsigned(Val), SecondChunk = unsigned(Val >> 32);
|
||||
const char *FirstName = " least", *SecondName = " most";
|
||||
if (TD->isBigEndian()) {
|
||||
std::swap(FirstChunk, SecondChunk);
|
||||
std::swap(FirstName, SecondName);
|
||||
}
|
||||
|
||||
O << MAI->getData32bitsDirective(AddrSpace) << FirstChunk;
|
||||
if (VerboseAsm) {
|
||||
O.PadToColumn(MAI->getCommentColumn());
|
||||
O << MAI->getCommentString()
|
||||
<< FirstName << " significant half of i64 " << Val;
|
||||
}
|
||||
O << '\n';
|
||||
|
||||
O << MAI->getData32bitsDirective(AddrSpace) << SecondChunk;
|
||||
if (VerboseAsm) {
|
||||
O.PadToColumn(MAI->getCommentColumn());
|
||||
O << MAI->getCommentString()
|
||||
<< SecondName << " significant half of i64 " << Val;
|
||||
}
|
||||
O << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1284,22 +1299,39 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
|
||||
if (CV->isNullValue() || isa<UndefValue>(CV)) {
|
||||
EmitZeros(Size, AddrSpace);
|
||||
return;
|
||||
} else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
|
||||
}
|
||||
|
||||
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
|
||||
EmitGlobalConstantArray(CVA , AddrSpace);
|
||||
return;
|
||||
} else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
|
||||
}
|
||||
|
||||
if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
|
||||
EmitGlobalConstantStruct(CVS, AddrSpace);
|
||||
return;
|
||||
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
|
||||
}
|
||||
|
||||
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
|
||||
EmitGlobalConstantFP(CFP, AddrSpace);
|
||||
return;
|
||||
} else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
|
||||
}
|
||||
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
|
||||
// If we can directly emit an 8-byte constant, do it.
|
||||
if (Size == 8)
|
||||
if (const char *Data64Dir = MAI->getData64bitsDirective(AddrSpace)) {
|
||||
O << Data64Dir << CI->getZExtValue() << '\n';
|
||||
return;
|
||||
}
|
||||
|
||||
// Small integers are handled below; large integers are handled here.
|
||||
if (Size > 4) {
|
||||
EmitGlobalConstantLargeInt(CI, AddrSpace);
|
||||
return;
|
||||
}
|
||||
} else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
|
||||
}
|
||||
|
||||
if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
|
||||
EmitGlobalConstantVector(CP);
|
||||
return;
|
||||
}
|
||||
@ -1617,7 +1649,7 @@ void AsmPrinter::printLabel(unsigned Id) const {
|
||||
|
||||
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
|
||||
/// instruction, using the specified assembler variant. Targets should
|
||||
/// overried this to format as appropriate.
|
||||
/// override this to format as appropriate.
|
||||
bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant, const char *ExtraCode) {
|
||||
// Target doesn't support this yet!
|
||||
@ -1645,15 +1677,17 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
|
||||
// This code must use the function name itself, and not the function number,
|
||||
// since it must be possible to generate the label name from within other
|
||||
// functions.
|
||||
std::string FuncName = Mang->getMangledName(F);
|
||||
SmallString<60> FnName;
|
||||
Mang->getNameWithPrefix(FnName, F, false);
|
||||
|
||||
SmallString<60> Name;
|
||||
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BA"
|
||||
<< FuncName.size() << '_' << FuncName << '_'
|
||||
<< Mang->makeNameProper(BB->getName())
|
||||
<< Suffix;
|
||||
// FIXME: THIS IS BROKEN IF THE LLVM BASIC BLOCK DOESN'T HAVE A NAME!
|
||||
SmallString<60> NameResult;
|
||||
Mang->getNameWithPrefix(NameResult,
|
||||
StringRef("BA") + Twine((unsigned)FnName.size()) +
|
||||
"_" + FnName.str() + "_" + BB->getName() + Suffix,
|
||||
Mangler::Private);
|
||||
|
||||
return OutContext.GetOrCreateSymbol(Name.str());
|
||||
return OutContext.GetOrCreateSymbol(NameResult.str());
|
||||
}
|
||||
|
||||
MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const {
|
||||
|
@ -212,19 +212,30 @@ class DbgScope {
|
||||
///
|
||||
void addVariable(DbgVariable *V) { Variables.push_back(V); }
|
||||
|
||||
void fixInstructionMarkers() {
|
||||
void fixInstructionMarkers(DenseMap<const MachineInstr *,
|
||||
unsigned> &MIIndexMap) {
|
||||
assert (getFirstInsn() && "First instruction is missing!");
|
||||
if (getLastInsn())
|
||||
return;
|
||||
|
||||
// If a scope does not have an instruction to mark an end then use
|
||||
// the end of last child scope.
|
||||
|
||||
// Use the end of last child scope as end of this scope.
|
||||
SmallVector<DbgScope *, 4> &Scopes = getScopes();
|
||||
assert (!Scopes.empty() && "Inner most scope does not have last insn!");
|
||||
DbgScope *L = Scopes.back();
|
||||
if (!L->getLastInsn())
|
||||
L->fixInstructionMarkers();
|
||||
setLastInsn(L->getLastInsn());
|
||||
const MachineInstr *LastInsn = getFirstInsn();
|
||||
unsigned LIndex = 0;
|
||||
if (Scopes.empty()) {
|
||||
assert (getLastInsn() && "Inner most scope does not have last insn!");
|
||||
return;
|
||||
}
|
||||
for (SmallVector<DbgScope *, 4>::iterator SI = Scopes.begin(),
|
||||
SE = Scopes.end(); SI != SE; ++SI) {
|
||||
DbgScope *DS = *SI;
|
||||
DS->fixInstructionMarkers(MIIndexMap);
|
||||
const MachineInstr *DSLastInsn = DS->getLastInsn();
|
||||
unsigned DSI = MIIndexMap[DSLastInsn];
|
||||
if (DSI > LIndex) {
|
||||
LastInsn = DSLastInsn;
|
||||
LIndex = DSI;
|
||||
}
|
||||
}
|
||||
setLastInsn(LastInsn);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -1021,6 +1032,16 @@ DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) {
|
||||
return Enumerator;
|
||||
}
|
||||
|
||||
/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
|
||||
/// printer to not emit usual symbol prefix before the symbol name is used then
|
||||
/// return linkage name after skipping this special LLVM prefix.
|
||||
static StringRef getRealLinkageName(StringRef LinkageName) {
|
||||
char One = '\1';
|
||||
if (LinkageName.startswith(StringRef(&One, 1)))
|
||||
return LinkageName.substr(1);
|
||||
return LinkageName;
|
||||
}
|
||||
|
||||
/// createGlobalVariableDIE - Create new DIE using GV.
|
||||
DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
|
||||
// If the global variable was optmized out then no need to create debug info
|
||||
@ -1033,16 +1054,10 @@ DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
|
||||
GV.getDisplayName());
|
||||
|
||||
StringRef LinkageName = GV.getLinkageName();
|
||||
if (!LinkageName.empty()) {
|
||||
// Skip special LLVM prefix that is used to inform the asm printer to not
|
||||
// emit usual symbol prefix before the symbol name. This happens for
|
||||
// Objective-C symbol names and symbol whose name is replaced using GCC's
|
||||
// __asm__ attribute.
|
||||
if (LinkageName[0] == 1)
|
||||
LinkageName = LinkageName.substr(1);
|
||||
if (!LinkageName.empty())
|
||||
addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
|
||||
LinkageName);
|
||||
}
|
||||
getRealLinkageName(LinkageName));
|
||||
|
||||
addType(GVDie, GV.getType());
|
||||
if (!GV.isLocalToUnit())
|
||||
addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
|
||||
@ -1074,10 +1089,9 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
|
||||
addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
|
||||
|
||||
uint64_t Offset = DT.getOffsetInBits();
|
||||
uint64_t FieldOffset = Offset;
|
||||
uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
|
||||
uint64_t HiMark = (Offset + FieldSize) & AlignMask;
|
||||
FieldOffset = (HiMark - FieldSize);
|
||||
uint64_t FieldOffset = (HiMark - FieldSize);
|
||||
Offset -= FieldOffset;
|
||||
|
||||
// Maybe we need to work from the other end.
|
||||
@ -1119,16 +1133,10 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
|
||||
addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
|
||||
|
||||
StringRef LinkageName = SP.getLinkageName();
|
||||
if (!LinkageName.empty()) {
|
||||
// Skip special LLVM prefix that is used to inform the asm printer to not
|
||||
// emit usual symbol prefix before the symbol name. This happens for
|
||||
// Objective-C symbol names and symbol whose name is replaced using GCC's
|
||||
// __asm__ attribute.
|
||||
if (LinkageName[0] == 1)
|
||||
LinkageName = LinkageName.substr(1);
|
||||
if (!LinkageName.empty())
|
||||
addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
|
||||
LinkageName);
|
||||
}
|
||||
getRealLinkageName(LinkageName));
|
||||
|
||||
addSourceLine(SPDie, &SP);
|
||||
|
||||
// Add prototyped tag, if C or ObjC.
|
||||
@ -1382,7 +1390,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
|
||||
I->second.push_back(std::make_pair(StartID, ScopeDIE));
|
||||
|
||||
StringPool.insert(InlinedSP.getName());
|
||||
StringPool.insert(InlinedSP.getLinkageName());
|
||||
StringPool.insert(getRealLinkageName(InlinedSP.getLinkageName()));
|
||||
|
||||
DILocation DL(Scope->getInlinedAt());
|
||||
addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID());
|
||||
addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
|
||||
@ -1644,8 +1653,11 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
|
||||
ModuleCU->insertDIE(N, VariableDie);
|
||||
|
||||
// Add to context owner.
|
||||
if (DI_GV.isDefinition()
|
||||
&& !DI_GV.getContext().isCompileUnit()) {
|
||||
DIDescriptor GVContext = DI_GV.getContext();
|
||||
// Do not create specification DIE if context is either compile unit
|
||||
// or a subprogram.
|
||||
if (DI_GV.isDefinition() && !GVContext.isCompileUnit()
|
||||
&& !GVContext.isSubprogram()) {
|
||||
// Create specification DIE.
|
||||
DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
|
||||
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
|
||||
@ -1663,7 +1675,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
|
||||
Asm->Mang->getMangledName(DI_GV.getGlobal()));
|
||||
addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
|
||||
}
|
||||
addToContextOwner(VariableDie, DI_GV.getContext());
|
||||
addToContextOwner(VariableDie, GVContext);
|
||||
|
||||
// Expose as global. FIXME - need to check external flag.
|
||||
ModuleCU->addGlobal(DI_GV.getName(), VariableDie);
|
||||
@ -1804,7 +1816,8 @@ void DwarfDebug::endModule() {
|
||||
DIE *NDie = ModuleCU->getDIE(N);
|
||||
if (!NDie) continue;
|
||||
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
|
||||
addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
|
||||
// FIXME - This is not the correct approach.
|
||||
// addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
|
||||
}
|
||||
|
||||
// Standard sections final addresses.
|
||||
@ -1976,12 +1989,15 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
|
||||
if (!DbgScopeMap.empty())
|
||||
return false;
|
||||
|
||||
DenseMap<const MachineInstr *, unsigned> MIIndexMap;
|
||||
unsigned MIIndex = 0;
|
||||
// Scan each instruction and create scopes. First build working set of scopes.
|
||||
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
|
||||
I != E; ++I) {
|
||||
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
|
||||
II != IE; ++II) {
|
||||
const MachineInstr *MInsn = II;
|
||||
MIIndexMap[MInsn] = MIIndex++;
|
||||
DebugLoc DL = MInsn->getDebugLoc();
|
||||
if (DL.isUnknown()) continue;
|
||||
DebugLocTuple DLT = MF->getDebugLocTuple(DL);
|
||||
@ -2014,16 +2030,10 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
|
||||
}
|
||||
}
|
||||
|
||||
// If a scope's last instruction is not set then use its child scope's
|
||||
// last instruction as this scope's last instrunction.
|
||||
for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(),
|
||||
DE = DbgScopeMap.end(); DI != DE; ++DI) {
|
||||
if (DI->second->isAbstractScope())
|
||||
continue;
|
||||
assert (DI->second->getFirstInsn() && "Invalid first instruction!");
|
||||
DI->second->fixInstructionMarkers();
|
||||
assert (DI->second->getLastInsn() && "Invalid last instruction!");
|
||||
}
|
||||
if (!CurrentFnDbgScope)
|
||||
return false;
|
||||
|
||||
CurrentFnDbgScope->fixInstructionMarkers(MIIndexMap);
|
||||
|
||||
// Each scope has first instruction and last instruction to mark beginning
|
||||
// and end of a scope respectively. Create an inverse map that list scopes
|
||||
@ -2105,38 +2115,41 @@ void DwarfDebug::endFunction(MachineFunction *MF) {
|
||||
if (DbgScopeMap.empty())
|
||||
return;
|
||||
|
||||
// Define end label for subprogram.
|
||||
EmitLabel("func_end", SubprogramCount);
|
||||
|
||||
// Get function line info.
|
||||
if (!Lines.empty()) {
|
||||
// Get section line info.
|
||||
unsigned ID = SectionMap.insert(Asm->getCurrentSection());
|
||||
if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
|
||||
std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
|
||||
// Append the function info to section info.
|
||||
SectionLineInfos.insert(SectionLineInfos.end(),
|
||||
Lines.begin(), Lines.end());
|
||||
if (CurrentFnDbgScope) {
|
||||
// Define end label for subprogram.
|
||||
EmitLabel("func_end", SubprogramCount);
|
||||
|
||||
// Get function line info.
|
||||
if (!Lines.empty()) {
|
||||
// Get section line info.
|
||||
unsigned ID = SectionMap.insert(Asm->getCurrentSection());
|
||||
if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
|
||||
std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
|
||||
// Append the function info to section info.
|
||||
SectionLineInfos.insert(SectionLineInfos.end(),
|
||||
Lines.begin(), Lines.end());
|
||||
}
|
||||
|
||||
// Construct abstract scopes.
|
||||
for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
|
||||
AE = AbstractScopesList.end(); AI != AE; ++AI)
|
||||
constructScopeDIE(*AI);
|
||||
|
||||
constructScopeDIE(CurrentFnDbgScope);
|
||||
|
||||
DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
|
||||
MMI->getFrameMoves()));
|
||||
}
|
||||
|
||||
// Construct abstract scopes.
|
||||
for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
|
||||
AE = AbstractScopesList.end(); AI != AE; ++AI)
|
||||
constructScopeDIE(*AI);
|
||||
|
||||
constructScopeDIE(CurrentFnDbgScope);
|
||||
|
||||
DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
|
||||
MMI->getFrameMoves()));
|
||||
|
||||
// Clear debug info
|
||||
CurrentFnDbgScope = NULL;
|
||||
DbgScopeMap.clear();
|
||||
DbgScopeBeginMap.clear();
|
||||
DbgScopeEndMap.clear();
|
||||
ConcreteScopes.clear();
|
||||
AbstractScopesList.clear();
|
||||
|
||||
if (CurrentFnDbgScope) {
|
||||
CurrentFnDbgScope = NULL;
|
||||
DbgScopeMap.clear();
|
||||
DbgScopeBeginMap.clear();
|
||||
DbgScopeEndMap.clear();
|
||||
ConcreteScopes.clear();
|
||||
AbstractScopesList.clear();
|
||||
}
|
||||
Lines.clear();
|
||||
|
||||
if (TimePassesIsEnabled)
|
||||
@ -2908,8 +2921,6 @@ void DwarfDebug::emitDebugInlineInfo() {
|
||||
for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
|
||||
E = InlinedSPNodes.end(); I != E; ++I) {
|
||||
|
||||
// for (ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
|
||||
// I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) {
|
||||
MDNode *Node = *I;
|
||||
ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
|
||||
= InlineInfo.find(Node);
|
||||
@ -2920,20 +2931,11 @@ void DwarfDebug::emitDebugInlineInfo() {
|
||||
|
||||
if (LName.empty())
|
||||
Asm->EmitString(Name);
|
||||
else {
|
||||
// Skip special LLVM prefix that is used to inform the asm printer to not
|
||||
// emit usual symbol prefix before the symbol name. This happens for
|
||||
// Objective-C symbol names and symbol whose name is replaced using GCC's
|
||||
// __asm__ attribute.
|
||||
if (LName[0] == 1)
|
||||
LName = LName.substr(1);
|
||||
// Asm->EmitString(LName);
|
||||
else
|
||||
EmitSectionOffset("string", "section_str",
|
||||
StringPool.idFor(LName), false, true);
|
||||
StringPool.idFor(getRealLinkageName(LName)), false, true);
|
||||
|
||||
}
|
||||
Asm->EOL("MIPS linkage name");
|
||||
// Asm->EmitString(Name);
|
||||
EmitSectionOffset("string", "section_str",
|
||||
StringPool.idFor(Name), false, true);
|
||||
Asm->EOL("Function name");
|
||||
|
@ -35,12 +35,13 @@ add_llvm_library(LLVMCodeGen
|
||||
MachineModuleInfoImpls.cpp
|
||||
MachinePassRegistry.cpp
|
||||
MachineRegisterInfo.cpp
|
||||
MachineSink.cpp
|
||||
MachineSSAUpdater.cpp
|
||||
MachineSink.cpp
|
||||
MachineVerifier.cpp
|
||||
MaxStackAlignment.cpp
|
||||
ObjectCodeEmitter.cpp
|
||||
OcamlGC.cpp
|
||||
OptimizeExts.cpp
|
||||
PHIElimination.cpp
|
||||
Passes.cpp
|
||||
PostRASchedulerList.cpp
|
||||
|
@ -288,9 +288,11 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI,
|
||||
}
|
||||
|
||||
unsigned
|
||||
CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg,
|
||||
CriticalAntiDepBreaker::findSuitableFreeRegister(MachineInstr *MI,
|
||||
unsigned AntiDepReg,
|
||||
unsigned LastNewReg,
|
||||
const TargetRegisterClass *RC) {
|
||||
const TargetRegisterClass *RC)
|
||||
{
|
||||
for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF),
|
||||
RE = RC->allocation_order_end(MF); R != RE; ++R) {
|
||||
unsigned NewReg = *R;
|
||||
@ -300,12 +302,16 @@ CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg,
|
||||
// an anti-dependence with this AntiDepReg, because that would
|
||||
// re-introduce that anti-dependence.
|
||||
if (NewReg == LastNewReg) continue;
|
||||
// If the instruction already has a def of the NewReg, it's not suitable.
|
||||
// For example, Instruction with multiple definitions can result in this
|
||||
// condition.
|
||||
if (MI->modifiesRegister(NewReg, TRI)) continue;
|
||||
// If NewReg is dead and NewReg's most recent def is not before
|
||||
// AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg.
|
||||
assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) &&
|
||||
"Kill and Def maps aren't consistent for AntiDepReg!");
|
||||
assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) &&
|
||||
"Kill and Def maps aren't consistent for NewReg!");
|
||||
assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u))
|
||||
&& "Kill and Def maps aren't consistent for AntiDepReg!");
|
||||
assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u))
|
||||
&& "Kill and Def maps aren't consistent for NewReg!");
|
||||
if (KillIndices[NewReg] != ~0u ||
|
||||
Classes[NewReg] == reinterpret_cast<TargetRegisterClass *>(-1) ||
|
||||
KillIndices[AntiDepReg] > DefIndices[NewReg])
|
||||
@ -336,14 +342,14 @@ BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
DEBUG(errs() << "Critical path has total latency "
|
||||
DEBUG(dbgs() << "Critical path has total latency "
|
||||
<< (Max->getDepth() + Max->Latency) << "\n");
|
||||
DEBUG(errs() << "Available regs:");
|
||||
DEBUG(dbgs() << "Available regs:");
|
||||
for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) {
|
||||
if (KillIndices[Reg] == ~0u)
|
||||
DEBUG(errs() << " " << TRI->getName(Reg));
|
||||
DEBUG(dbgs() << " " << TRI->getName(Reg));
|
||||
}
|
||||
DEBUG(errs() << '\n');
|
||||
DEBUG(dbgs() << '\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -495,10 +501,10 @@ BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
// TODO: Instead of picking the first free register, consider which might
|
||||
// be the best.
|
||||
if (AntiDepReg != 0) {
|
||||
if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg,
|
||||
if (unsigned NewReg = findSuitableFreeRegister(MI, AntiDepReg,
|
||||
LastNewReg[AntiDepReg],
|
||||
RC)) {
|
||||
DEBUG(errs() << "Breaking anti-dependence edge on "
|
||||
DEBUG(dbgs() << "Breaking anti-dependence edge on "
|
||||
<< TRI->getName(AntiDepReg)
|
||||
<< " with " << RegRefs.count(AntiDepReg) << " references"
|
||||
<< " using " << TRI->getName(NewReg) << "!\n");
|
||||
|
@ -64,11 +64,12 @@ namespace llvm {
|
||||
public:
|
||||
CriticalAntiDepBreaker(MachineFunction& MFi);
|
||||
~CriticalAntiDepBreaker();
|
||||
|
||||
|
||||
/// Start - Initialize anti-dep breaking for a new basic block.
|
||||
void StartBlock(MachineBasicBlock *BB);
|
||||
|
||||
/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path
|
||||
/// BreakAntiDependencies - Identifiy anti-dependencies along the critical
|
||||
/// path
|
||||
/// of the ScheduleDAG and break them by renaming registers.
|
||||
///
|
||||
unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,
|
||||
@ -87,7 +88,8 @@ namespace llvm {
|
||||
private:
|
||||
void PrescanInstruction(MachineInstr *MI);
|
||||
void ScanInstruction(MachineInstr *MI, unsigned Count);
|
||||
unsigned findSuitableFreeRegister(unsigned AntiDepReg,
|
||||
unsigned findSuitableFreeRegister(MachineInstr *MI,
|
||||
unsigned AntiDepReg,
|
||||
unsigned LastNewReg,
|
||||
const TargetRegisterClass *);
|
||||
};
|
||||
|
@ -109,7 +109,7 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
// If the instruction is dead, delete it!
|
||||
if (isDead(MI)) {
|
||||
DEBUG(errs() << "DeadMachineInstructionElim: DELETING: " << *MI);
|
||||
DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI);
|
||||
AnyChanges = true;
|
||||
MI->eraseFromParent();
|
||||
MIE = MBB->rend();
|
||||
|
@ -37,7 +37,7 @@ namespace llvm {
|
||||
/// startFunction - This callback is invoked when a new machine function is
|
||||
/// about to be emitted.
|
||||
void ELFCodeEmitter::startFunction(MachineFunction &MF) {
|
||||
DEBUG(errs() << "processing function: "
|
||||
DEBUG(dbgs() << "processing function: "
|
||||
<< MF.getFunction()->getName() << "\n");
|
||||
|
||||
// Get the ELF Section that this function belongs in.
|
||||
|
@ -1076,7 +1076,7 @@ void ELFWriter::OutputSectionsAndSectionTable() {
|
||||
// Emit all of sections to the file and build the section header table.
|
||||
for (ELFSectionIter I=SectionList.begin(), E=SectionList.end(); I != E; ++I) {
|
||||
ELFSection &S = *(*I);
|
||||
DEBUG(errs() << "SectionIdx: " << S.SectionIdx << ", Name: " << S.getName()
|
||||
DEBUG(dbgs() << "SectionIdx: " << S.SectionIdx << ", Name: " << S.getName()
|
||||
<< ", Size: " << S.Size << ", Offset: " << S.Offset
|
||||
<< ", SectionData Size: " << S.size() << "\n");
|
||||
|
||||
|
@ -48,7 +48,7 @@ ExactHazardRecognizer(const InstrItineraryData &LItinData) :
|
||||
Scoreboard = new unsigned[ScoreboardDepth];
|
||||
ScoreboardHead = 0;
|
||||
|
||||
DEBUG(errs() << "Using exact hazard recognizer: ScoreboardDepth = "
|
||||
DEBUG(dbgs() << "Using exact hazard recognizer: ScoreboardDepth = "
|
||||
<< ScoreboardDepth << '\n');
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ unsigned ExactHazardRecognizer::getFutureIndex(unsigned offset) {
|
||||
}
|
||||
|
||||
void ExactHazardRecognizer::dumpScoreboard() {
|
||||
errs() << "Scoreboard:\n";
|
||||
dbgs() << "Scoreboard:\n";
|
||||
|
||||
unsigned last = ScoreboardDepth - 1;
|
||||
while ((last > 0) && (Scoreboard[getFutureIndex(last)] == 0))
|
||||
@ -74,10 +74,10 @@ void ExactHazardRecognizer::dumpScoreboard() {
|
||||
|
||||
for (unsigned i = 0; i <= last; i++) {
|
||||
unsigned FUs = Scoreboard[getFutureIndex(i)];
|
||||
errs() << "\t";
|
||||
dbgs() << "\t";
|
||||
for (int j = 31; j >= 0; j--)
|
||||
errs() << ((FUs & (1 << j)) ? '1' : '0');
|
||||
errs() << '\n';
|
||||
dbgs() << ((FUs & (1 << j)) ? '1' : '0');
|
||||
dbgs() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,8 +102,8 @@ ExactHazardRecognizer::HazardType ExactHazardRecognizer::getHazardType(SUnit *SU
|
||||
unsigned index = getFutureIndex(cycle + i);
|
||||
unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
|
||||
if (!freeUnits) {
|
||||
DEBUG(errs() << "*** Hazard in cycle " << (cycle + i) << ", ");
|
||||
DEBUG(errs() << "SU(" << SU->NodeNum << "): ");
|
||||
DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", ");
|
||||
DEBUG(dbgs() << "SU(" << SU->NodeNum << "): ");
|
||||
DEBUG(SU->getInstr()->dump());
|
||||
return Hazard;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
@ -92,7 +93,7 @@ GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M,
|
||||
}
|
||||
}
|
||||
|
||||
errs() << "unsupported GC: " << Name << "\n";
|
||||
dbgs() << "unsupported GC: " << Name << "\n";
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
@ -109,7 +110,7 @@ GCStrategy::~GCStrategy() {
|
||||
bool GCStrategy::initializeCustomLowering(Module &M) { return false; }
|
||||
|
||||
bool GCStrategy::performCustomLowering(Function &F) {
|
||||
errs() << "gc " << getName() << " must override performCustomLowering.\n";
|
||||
dbgs() << "gc " << getName() << " must override performCustomLowering.\n";
|
||||
llvm_unreachable(0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -229,14 +229,14 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
||||
TII = MF.getTarget().getInstrInfo();
|
||||
if (!TII) return false;
|
||||
|
||||
DEBUG(errs() << "\nIfcvt: function (" << ++FnNum << ") \'"
|
||||
DEBUG(dbgs() << "\nIfcvt: function (" << ++FnNum << ") \'"
|
||||
<< MF.getFunction()->getName() << "\'");
|
||||
|
||||
if (FnNum < IfCvtFnStart || (IfCvtFnStop != -1 && FnNum > IfCvtFnStop)) {
|
||||
DEBUG(errs() << " skipped\n");
|
||||
DEBUG(dbgs() << " skipped\n");
|
||||
return false;
|
||||
}
|
||||
DEBUG(errs() << "\n");
|
||||
DEBUG(dbgs() << "\n");
|
||||
|
||||
MF.RenumberBlocks();
|
||||
BBAnalysis.resize(MF.getNumBlockIDs());
|
||||
@ -281,13 +281,13 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
||||
case ICSimpleFalse: {
|
||||
bool isFalse = Kind == ICSimpleFalse;
|
||||
if ((isFalse && DisableSimpleF) || (!isFalse && DisableSimple)) break;
|
||||
DEBUG(errs() << "Ifcvt (Simple" << (Kind == ICSimpleFalse ? " false" :"")
|
||||
DEBUG(dbgs() << "Ifcvt (Simple" << (Kind == ICSimpleFalse ? " false" :"")
|
||||
<< "): BB#" << BBI.BB->getNumber() << " ("
|
||||
<< ((Kind == ICSimpleFalse)
|
||||
? BBI.FalseBB->getNumber()
|
||||
: BBI.TrueBB->getNumber()) << ") ");
|
||||
RetVal = IfConvertSimple(BBI, Kind);
|
||||
DEBUG(errs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
||||
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
||||
if (RetVal) {
|
||||
if (isFalse) NumSimpleFalse++;
|
||||
else NumSimple++;
|
||||
@ -304,16 +304,16 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (DisableTriangleR && !isFalse && isRev) break;
|
||||
if (DisableTriangleF && isFalse && !isRev) break;
|
||||
if (DisableTriangleFR && isFalse && isRev) break;
|
||||
DEBUG(errs() << "Ifcvt (Triangle");
|
||||
DEBUG(dbgs() << "Ifcvt (Triangle");
|
||||
if (isFalse)
|
||||
DEBUG(errs() << " false");
|
||||
DEBUG(dbgs() << " false");
|
||||
if (isRev)
|
||||
DEBUG(errs() << " rev");
|
||||
DEBUG(errs() << "): BB#" << BBI.BB->getNumber() << " (T:"
|
||||
DEBUG(dbgs() << " rev");
|
||||
DEBUG(dbgs() << "): BB#" << BBI.BB->getNumber() << " (T:"
|
||||
<< BBI.TrueBB->getNumber() << ",F:"
|
||||
<< BBI.FalseBB->getNumber() << ") ");
|
||||
RetVal = IfConvertTriangle(BBI, Kind);
|
||||
DEBUG(errs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
||||
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
||||
if (RetVal) {
|
||||
if (isFalse) {
|
||||
if (isRev) NumTriangleFRev++;
|
||||
@ -327,11 +327,11 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
|
||||
}
|
||||
case ICDiamond: {
|
||||
if (DisableDiamond) break;
|
||||
DEBUG(errs() << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
|
||||
DEBUG(dbgs() << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
|
||||
<< BBI.TrueBB->getNumber() << ",F:"
|
||||
<< BBI.FalseBB->getNumber() << ") ");
|
||||
RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2);
|
||||
DEBUG(errs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
||||
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
|
||||
if (RetVal) NumDiamonds++;
|
||||
break;
|
||||
}
|
||||
@ -1141,7 +1141,7 @@ void IfConverter::PredicateBlock(BBInfo &BBI,
|
||||
continue;
|
||||
if (!TII->PredicateInstruction(I, Cond)) {
|
||||
#ifndef NDEBUG
|
||||
errs() << "Unable to predicate " << *I << "!\n";
|
||||
dbgs() << "Unable to predicate " << *I << "!\n";
|
||||
#endif
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
@ -1177,7 +1177,7 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
|
||||
if (!isPredicated)
|
||||
if (!TII->PredicateInstruction(MI, Cond)) {
|
||||
#ifndef NDEBUG
|
||||
errs() << "Unable to predicate " << *I << "!\n";
|
||||
dbgs() << "Unable to predicate " << *I << "!\n";
|
||||
#endif
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
|
@ -349,12 +349,12 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
|
||||
case Intrinsic::setjmp: {
|
||||
Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin() + 1, CI->op_end(),
|
||||
Type::getInt32Ty(Context));
|
||||
if (CI->getType() != Type::getVoidTy(Context))
|
||||
if (!CI->getType()->isVoidTy())
|
||||
CI->replaceAllUsesWith(V);
|
||||
break;
|
||||
}
|
||||
case Intrinsic::sigsetjmp:
|
||||
if (CI->getType() != Type::getVoidTy(Context))
|
||||
if (!CI->getType()->isVoidTy())
|
||||
CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
|
||||
break;
|
||||
|
||||
@ -427,10 +427,6 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Intrinsic::dbg_stoppoint:
|
||||
case Intrinsic::dbg_region_start:
|
||||
case Intrinsic::dbg_region_end:
|
||||
case Intrinsic::dbg_func_start:
|
||||
case Intrinsic::dbg_declare:
|
||||
break; // Simply strip out debugging intrinsics
|
||||
|
||||
@ -512,7 +508,7 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
|
||||
}
|
||||
case Intrinsic::flt_rounds:
|
||||
// Lower to "round to the nearest"
|
||||
if (CI->getType() != Type::getVoidTy(Context))
|
||||
if (!CI->getType()->isVoidTy())
|
||||
CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1));
|
||||
break;
|
||||
case Intrinsic::invariant_start:
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "llvm/Target/TargetRegistry.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -61,6 +62,7 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
|
||||
cl::desc("Verify generated machine code"),
|
||||
cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));
|
||||
|
||||
|
||||
// Enable or disable FastISel. Both options are needed, because
|
||||
// FastISel is enabled by default with -fast, and we wish to be
|
||||
// able to enable or disable fast-isel independently from -O0.
|
||||
@ -246,7 +248,7 @@ static void printAndVerify(PassManagerBase &PM,
|
||||
const char *Banner,
|
||||
bool allowDoubleDefs = false) {
|
||||
if (PrintMachineCode)
|
||||
PM.add(createMachineFunctionPrinterPass(errs(), Banner));
|
||||
PM.add(createMachineFunctionPrinterPass(dbgs(), Banner));
|
||||
|
||||
if (VerifyMachineCode)
|
||||
PM.add(createMachineVerifierPass(allowDoubleDefs));
|
||||
@ -269,7 +271,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
if (OptLevel != CodeGenOpt::None && !DisableLSR) {
|
||||
PM.add(createLoopStrengthReducePass(getTargetLowering()));
|
||||
if (PrintLSR)
|
||||
PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &errs()));
|
||||
PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs()));
|
||||
}
|
||||
|
||||
// Turn exception handling constructs into something the code generators can
|
||||
@ -278,8 +280,13 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
{
|
||||
case ExceptionHandling::SjLj:
|
||||
// SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
|
||||
PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
|
||||
// Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
|
||||
// catch info can get misplaced when a selector ends up more than one block
|
||||
// removed from the parent invoke(s). This could happen when a landing
|
||||
// pad is shared by multiple invokes and is also a target of a normal
|
||||
// edge from elsewhere.
|
||||
PM.add(createSjLjEHPass(getTargetLowering()));
|
||||
PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
|
||||
break;
|
||||
case ExceptionHandling::Dwarf:
|
||||
PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
|
||||
@ -302,7 +309,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
if (PrintISelInput)
|
||||
PM.add(createPrintFunctionPass("\n\n"
|
||||
"*** Final LLVM Code input to ISel ***\n",
|
||||
&errs()));
|
||||
&dbgs()));
|
||||
|
||||
// Standard Lower-Level Passes.
|
||||
|
||||
@ -323,6 +330,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
/* allowDoubleDefs= */ true);
|
||||
|
||||
if (OptLevel != CodeGenOpt::None) {
|
||||
PM.add(createOptimizeExtsPass());
|
||||
if (!DisableMachineLICM)
|
||||
PM.add(createMachineLICMPass());
|
||||
if (!DisableMachineSink)
|
||||
@ -335,7 +343,8 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
if (OptLevel != CodeGenOpt::None &&
|
||||
!DisableTailDuplicate && PreAllocTailDup) {
|
||||
PM.add(createTailDuplicatePass(true));
|
||||
printAndVerify(PM, "After Pre-RegAlloc TailDuplicate");
|
||||
printAndVerify(PM, "After Pre-RegAlloc TailDuplicate",
|
||||
/* allowDoubleDefs= */ true);
|
||||
}
|
||||
|
||||
// Run pre-ra passes.
|
||||
@ -391,7 +400,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
|
||||
PM.add(createGCMachineCodeAnalysisPass());
|
||||
|
||||
if (PrintGCInfo)
|
||||
PM.add(createGCInfoPrinter(errs()));
|
||||
PM.add(createGCInfoPrinter(dbgs()));
|
||||
|
||||
if (OptLevel != CodeGenOpt::None && !DisableCodePlace) {
|
||||
PM.add(createCodePlacementOptPass());
|
||||
|
@ -10,7 +10,7 @@
|
||||
// This file implements the LiveRange and LiveInterval classes. Given some
|
||||
// numbering of each the machine instructions an interval [i, j) is said to be a
|
||||
// live interval for register v if there is no instruction with number j' > j
|
||||
// such that v is live at j' abd there is no instruction with number i' < i such
|
||||
// such that v is live at j' and there is no instruction with number i' < i such
|
||||
// that v is live at i'. In this implementation intervals can have holes,
|
||||
// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
|
||||
// individual range is represented as an instance of LiveRange, and the whole
|
||||
@ -24,6 +24,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <algorithm>
|
||||
@ -813,7 +814,7 @@ raw_ostream& llvm::operator<<(raw_ostream& os, const LiveRange &LR) {
|
||||
}
|
||||
|
||||
void LiveRange::dump() const {
|
||||
errs() << *this << "\n";
|
||||
dbgs() << *this << "\n";
|
||||
}
|
||||
|
||||
void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
|
||||
@ -872,7 +873,7 @@ void LiveInterval::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
|
||||
}
|
||||
|
||||
void LiveInterval::dump() const {
|
||||
errs() << *this << "\n";
|
||||
dbgs() << *this << "\n";
|
||||
}
|
||||
|
||||
|
||||
|
@ -146,7 +146,7 @@ void LiveIntervals::printInstrs(raw_ostream &OS) const {
|
||||
}
|
||||
|
||||
void LiveIntervals::dumpInstrs() const {
|
||||
printInstrs(errs());
|
||||
printInstrs(dbgs());
|
||||
}
|
||||
|
||||
bool LiveIntervals::conflictsWithPhysReg(const LiveInterval &li,
|
||||
@ -253,9 +253,9 @@ bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,
|
||||
#ifndef NDEBUG
|
||||
static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) {
|
||||
if (TargetRegisterInfo::isPhysicalRegister(reg))
|
||||
errs() << tri_->getName(reg);
|
||||
dbgs() << tri_->getName(reg);
|
||||
else
|
||||
errs() << "%reg" << reg;
|
||||
dbgs() << "%reg" << reg;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -266,7 +266,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
unsigned MOIdx,
|
||||
LiveInterval &interval) {
|
||||
DEBUG({
|
||||
errs() << "\t\tregister: ";
|
||||
dbgs() << "\t\tregister: ";
|
||||
printRegName(interval.reg, tri_);
|
||||
});
|
||||
|
||||
@ -314,7 +314,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
"Shouldn't be alive across any blocks!");
|
||||
LiveRange LR(defIndex, killIdx, ValNo);
|
||||
interval.addRange(LR);
|
||||
DEBUG(errs() << " +" << LR << "\n");
|
||||
DEBUG(dbgs() << " +" << LR << "\n");
|
||||
ValNo->addKill(killIdx);
|
||||
return;
|
||||
}
|
||||
@ -325,7 +325,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
// live into some number of blocks, but gets killed. Start by adding a
|
||||
// range that goes from this definition to the end of the defining block.
|
||||
LiveRange NewLR(defIndex, getMBBEndIdx(mbb), ValNo);
|
||||
DEBUG(errs() << " +" << NewLR);
|
||||
DEBUG(dbgs() << " +" << NewLR);
|
||||
interval.addRange(NewLR);
|
||||
|
||||
// Iterate over all of the blocks that the variable is completely
|
||||
@ -336,7 +336,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
MachineBasicBlock *aliveBlock = mf_->getBlockNumbered(*I);
|
||||
LiveRange LR(getMBBStartIdx(aliveBlock), getMBBEndIdx(aliveBlock), ValNo);
|
||||
interval.addRange(LR);
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
}
|
||||
|
||||
// Finally, this virtual register is live from the start of any killing
|
||||
@ -348,7 +348,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
LiveRange LR(getMBBStartIdx(Kill->getParent()), killIdx, ValNo);
|
||||
interval.addRange(LR);
|
||||
ValNo->addKill(killIdx);
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -393,7 +393,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
|
||||
// Add the new live interval which replaces the range for the input copy.
|
||||
LiveRange LR(DefIndex, RedefIndex, ValNo);
|
||||
DEBUG(errs() << " replace range with " << LR);
|
||||
DEBUG(dbgs() << " replace range with " << LR);
|
||||
interval.addRange(LR);
|
||||
ValNo->addKill(RedefIndex);
|
||||
|
||||
@ -404,8 +404,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
OldValNo));
|
||||
|
||||
DEBUG({
|
||||
errs() << " RESULT: ";
|
||||
interval.print(errs(), tri_);
|
||||
dbgs() << " RESULT: ";
|
||||
interval.print(dbgs(), tri_);
|
||||
});
|
||||
} else {
|
||||
// Otherwise, this must be because of phi elimination. If this is the
|
||||
@ -422,8 +422,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
SlotIndex Start = getMBBStartIdx(Killer->getParent());
|
||||
SlotIndex End = getInstructionIndex(Killer).getDefIndex();
|
||||
DEBUG({
|
||||
errs() << "\n\t\trenaming [" << Start << "," << End << "] in: ";
|
||||
interval.print(errs(), tri_);
|
||||
dbgs() << "\n\t\trenaming [" << Start << "," << End << "] in: ";
|
||||
interval.print(dbgs(), tri_);
|
||||
});
|
||||
interval.removeRange(Start, End);
|
||||
|
||||
@ -442,8 +442,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
VNI->addKill(indexes_->getTerminatorGap(killMBB));
|
||||
VNI->setHasPHIKill(true);
|
||||
DEBUG({
|
||||
errs() << " RESULT: ";
|
||||
interval.print(errs(), tri_);
|
||||
dbgs() << " RESULT: ";
|
||||
interval.print(dbgs(), tri_);
|
||||
});
|
||||
}
|
||||
|
||||
@ -469,11 +469,11 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
interval.addRange(LR);
|
||||
ValNo->addKill(indexes_->getTerminatorGap(mbb));
|
||||
ValNo->setHasPHIKill(true);
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(errs() << '\n');
|
||||
DEBUG(dbgs() << '\n');
|
||||
}
|
||||
|
||||
void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
||||
@ -485,7 +485,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
||||
// A physical register cannot be live across basic block, so its
|
||||
// lifetime must end somewhere in its defining basic block.
|
||||
DEBUG({
|
||||
errs() << "\t\tregister: ";
|
||||
dbgs() << "\t\tregister: ";
|
||||
printRegName(interval.reg, tri_);
|
||||
});
|
||||
|
||||
@ -502,7 +502,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
||||
// For earlyclobbers, the defSlot was pushed back one; the extra
|
||||
// advance below compensates.
|
||||
if (MO.isDead()) {
|
||||
DEBUG(errs() << " dead");
|
||||
DEBUG(dbgs() << " dead");
|
||||
end = start.getStoreIndex();
|
||||
goto exit;
|
||||
}
|
||||
@ -517,7 +517,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
||||
baseIndex = indexes_->getNextNonNullIndex(baseIndex);
|
||||
|
||||
if (mi->killsRegister(interval.reg, tri_)) {
|
||||
DEBUG(errs() << " killed");
|
||||
DEBUG(dbgs() << " killed");
|
||||
end = baseIndex.getDefIndex();
|
||||
goto exit;
|
||||
} else {
|
||||
@ -531,7 +531,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
||||
// Then the register is essentially dead at the instruction that defines
|
||||
// it. Hence its interval is:
|
||||
// [defSlot(def), defSlot(def)+1)
|
||||
DEBUG(errs() << " dead");
|
||||
DEBUG(dbgs() << " dead");
|
||||
end = start.getStoreIndex();
|
||||
}
|
||||
goto exit;
|
||||
@ -560,7 +560,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
|
||||
LiveRange LR(start, end, ValNo);
|
||||
interval.addRange(LR);
|
||||
LR.valno->addKill(end);
|
||||
DEBUG(errs() << " +" << LR << '\n');
|
||||
DEBUG(dbgs() << " +" << LR << '\n');
|
||||
}
|
||||
|
||||
void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
|
||||
@ -595,7 +595,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
|
||||
SlotIndex MIIdx,
|
||||
LiveInterval &interval, bool isAlias) {
|
||||
DEBUG({
|
||||
errs() << "\t\tlivein register: ";
|
||||
dbgs() << "\t\tlivein register: ";
|
||||
printRegName(interval.reg, tri_);
|
||||
});
|
||||
|
||||
@ -612,7 +612,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
|
||||
|
||||
while (mi != MBB->end()) {
|
||||
if (mi->killsRegister(interval.reg, tri_)) {
|
||||
DEBUG(errs() << " killed");
|
||||
DEBUG(dbgs() << " killed");
|
||||
end = baseIndex.getDefIndex();
|
||||
SeenDefUse = true;
|
||||
break;
|
||||
@ -621,7 +621,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
|
||||
// Then the register is essentially dead at the instruction that defines
|
||||
// it. Hence its interval is:
|
||||
// [defSlot(def), defSlot(def)+1)
|
||||
DEBUG(errs() << " dead");
|
||||
DEBUG(dbgs() << " dead");
|
||||
end = start.getStoreIndex();
|
||||
SeenDefUse = true;
|
||||
break;
|
||||
@ -636,10 +636,10 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
|
||||
// Live-in register might not be used at all.
|
||||
if (!SeenDefUse) {
|
||||
if (isAlias) {
|
||||
DEBUG(errs() << " dead");
|
||||
DEBUG(dbgs() << " dead");
|
||||
end = MIIdx.getStoreIndex();
|
||||
} else {
|
||||
DEBUG(errs() << " live through");
|
||||
DEBUG(dbgs() << " live through");
|
||||
end = baseIndex;
|
||||
}
|
||||
}
|
||||
@ -652,7 +652,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
|
||||
|
||||
interval.addRange(LR);
|
||||
LR.valno->addKill(end);
|
||||
DEBUG(errs() << " +" << LR << '\n');
|
||||
DEBUG(dbgs() << " +" << LR << '\n');
|
||||
}
|
||||
|
||||
/// computeIntervals - computes the live intervals for virtual
|
||||
@ -660,7 +660,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
|
||||
/// live interval is an interval [i, j) where 1 <= i <= j < N for
|
||||
/// which a variable is live
|
||||
void LiveIntervals::computeIntervals() {
|
||||
DEBUG(errs() << "********** COMPUTING LIVE INTERVALS **********\n"
|
||||
DEBUG(dbgs() << "********** COMPUTING LIVE INTERVALS **********\n"
|
||||
<< "********** Function: "
|
||||
<< ((Value*)mf_->getFunction())->getName() << '\n');
|
||||
|
||||
@ -670,7 +670,7 @@ void LiveIntervals::computeIntervals() {
|
||||
MachineBasicBlock *MBB = MBBI;
|
||||
// Track the index of the current machine instr.
|
||||
SlotIndex MIIndex = getMBBStartIdx(MBB);
|
||||
DEBUG(errs() << MBB->getName() << ":\n");
|
||||
DEBUG(dbgs() << MBB->getName() << ":\n");
|
||||
|
||||
MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end();
|
||||
|
||||
@ -690,7 +690,7 @@ void LiveIntervals::computeIntervals() {
|
||||
MIIndex = indexes_->getNextNonNullIndex(MIIndex);
|
||||
|
||||
for (; MI != miEnd; ++MI) {
|
||||
DEBUG(errs() << MIIndex << "\t" << *MI);
|
||||
DEBUG(dbgs() << MIIndex << "\t" << *MI);
|
||||
|
||||
// Handle defs.
|
||||
for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
|
||||
@ -1055,7 +1055,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
|
||||
// If this is the rematerializable definition MI itself and
|
||||
// all of its uses are rematerialized, simply delete it.
|
||||
if (MI == ReMatOrigDefMI && CanDelete) {
|
||||
DEBUG(errs() << "\t\t\t\tErasing re-materlizable def: "
|
||||
DEBUG(dbgs() << "\t\t\t\tErasing re-materlizable def: "
|
||||
<< MI << '\n');
|
||||
RemoveMachineInstrFromMaps(MI);
|
||||
vrm.RemoveMachineInstrFromMaps(MI);
|
||||
@ -1208,28 +1208,28 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
|
||||
if (CreatedNewVReg) {
|
||||
LiveRange LR(index.getLoadIndex(), index.getDefIndex(),
|
||||
nI.getNextValue(SlotIndex(), 0, false, VNInfoAllocator));
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
nI.addRange(LR);
|
||||
} else {
|
||||
// Extend the split live interval to this def / use.
|
||||
SlotIndex End = index.getDefIndex();
|
||||
LiveRange LR(nI.ranges[nI.ranges.size()-1].end, End,
|
||||
nI.getValNumInfo(nI.getNumValNums()-1));
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
nI.addRange(LR);
|
||||
}
|
||||
}
|
||||
if (HasDef) {
|
||||
LiveRange LR(index.getDefIndex(), index.getStoreIndex(),
|
||||
nI.getNextValue(SlotIndex(), 0, false, VNInfoAllocator));
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
nI.addRange(LR);
|
||||
}
|
||||
|
||||
DEBUG({
|
||||
errs() << "\t\t\t\tAdded new interval: ";
|
||||
nI.print(errs(), tri_);
|
||||
errs() << '\n';
|
||||
dbgs() << "\t\t\t\tAdded new interval: ";
|
||||
nI.print(dbgs(), tri_);
|
||||
dbgs() << '\n';
|
||||
});
|
||||
}
|
||||
return CanFold;
|
||||
@ -1557,9 +1557,9 @@ addIntervalsForSpillsFast(const LiveInterval &li,
|
||||
"attempt to spill already spilled interval!");
|
||||
|
||||
DEBUG({
|
||||
errs() << "\t\t\t\tadding intervals for spills for interval: ";
|
||||
dbgs() << "\t\t\t\tadding intervals for spills for interval: ";
|
||||
li.dump();
|
||||
errs() << '\n';
|
||||
dbgs() << '\n';
|
||||
});
|
||||
|
||||
const TargetRegisterClass* rc = mri_->getRegClass(li.reg);
|
||||
@ -1610,7 +1610,7 @@ addIntervalsForSpillsFast(const LiveInterval &li,
|
||||
LiveRange LR(index.getLoadIndex(), index.getUseIndex(),
|
||||
nI.getNextValue(SlotIndex(), 0, false,
|
||||
getVNInfoAllocator()));
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
nI.addRange(LR);
|
||||
vrm.addRestorePoint(NewVReg, MI);
|
||||
}
|
||||
@ -1618,7 +1618,7 @@ addIntervalsForSpillsFast(const LiveInterval &li,
|
||||
LiveRange LR(index.getDefIndex(), index.getStoreIndex(),
|
||||
nI.getNextValue(SlotIndex(), 0, false,
|
||||
getVNInfoAllocator()));
|
||||
DEBUG(errs() << " +" << LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
nI.addRange(LR);
|
||||
vrm.addSpillPoint(NewVReg, true, MI);
|
||||
}
|
||||
@ -1626,9 +1626,9 @@ addIntervalsForSpillsFast(const LiveInterval &li,
|
||||
added.push_back(&nI);
|
||||
|
||||
DEBUG({
|
||||
errs() << "\t\t\t\tadded new interval: ";
|
||||
dbgs() << "\t\t\t\tadded new interval: ";
|
||||
nI.dump();
|
||||
errs() << '\n';
|
||||
dbgs() << '\n';
|
||||
});
|
||||
}
|
||||
|
||||
@ -1651,9 +1651,9 @@ addIntervalsForSpills(const LiveInterval &li,
|
||||
"attempt to spill already spilled interval!");
|
||||
|
||||
DEBUG({
|
||||
errs() << "\t\t\t\tadding intervals for spills for interval: ";
|
||||
li.print(errs(), tri_);
|
||||
errs() << '\n';
|
||||
dbgs() << "\t\t\t\tadding intervals for spills for interval: ";
|
||||
li.print(dbgs(), tri_);
|
||||
dbgs() << '\n';
|
||||
});
|
||||
|
||||
// Each bit specify whether a spill is required in the MBB.
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
@ -59,17 +60,17 @@ LiveVariables::VarInfo::findKill(const MachineBasicBlock *MBB) const {
|
||||
}
|
||||
|
||||
void LiveVariables::VarInfo::dump() const {
|
||||
errs() << " Alive in blocks: ";
|
||||
dbgs() << " Alive in blocks: ";
|
||||
for (SparseBitVector<>::iterator I = AliveBlocks.begin(),
|
||||
E = AliveBlocks.end(); I != E; ++I)
|
||||
errs() << *I << ", ";
|
||||
errs() << "\n Killed by:";
|
||||
dbgs() << *I << ", ";
|
||||
dbgs() << "\n Killed by:";
|
||||
if (Kills.empty())
|
||||
errs() << " No instructions.\n";
|
||||
dbgs() << " No instructions.\n";
|
||||
else {
|
||||
for (unsigned i = 0, e = Kills.size(); i != e; ++i)
|
||||
errs() << "\n #" << i << ": " << *Kills[i];
|
||||
errs() << "\n";
|
||||
dbgs() << "\n #" << i << ": " << *Kills[i];
|
||||
dbgs() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,7 +290,6 @@ MachineInstr *LiveVariables::FindLastRefOrPartRef(unsigned Reg) {
|
||||
|
||||
MachineInstr *LastRefOrPartRef = LastUse ? LastUse : LastDef;
|
||||
unsigned LastRefOrPartRefDist = DistanceMap[LastRefOrPartRef];
|
||||
MachineInstr *LastPartDef = 0;
|
||||
unsigned LastPartDefDist = 0;
|
||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||
unsigned SubReg = *SubRegs; ++SubRegs) {
|
||||
@ -298,13 +298,9 @@ MachineInstr *LiveVariables::FindLastRefOrPartRef(unsigned Reg) {
|
||||
// There was a def of this sub-register in between. This is a partial
|
||||
// def, keep track of the last one.
|
||||
unsigned Dist = DistanceMap[Def];
|
||||
if (Dist > LastPartDefDist) {
|
||||
if (Dist > LastPartDefDist)
|
||||
LastPartDefDist = Dist;
|
||||
LastPartDef = Def;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (MachineInstr *Use = PhysRegUse[SubReg]) {
|
||||
} else if (MachineInstr *Use = PhysRegUse[SubReg]) {
|
||||
unsigned Dist = DistanceMap[Use];
|
||||
if (Dist > LastRefOrPartRefDist) {
|
||||
LastRefOrPartRefDist = Dist;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user