aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt12
-rw-r--r--docs/CMake.html4
-rw-r--r--docs/GoldPlugin.html30
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h66
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h70
-rw-r--r--include/llvm/ExecutionEngine/JITMemoryManager.h26
-rw-r--r--include/llvm/Support/StandardPasses.h250
-rw-r--r--lib/CodeGen/CMakeLists.txt2
-rw-r--r--lib/CodeGen/ELFCodeEmitter.cpp94
-rw-r--r--lib/CodeGen/ELFCodeEmitter.h87
-rw-r--r--lib/CodeGen/ELFWriter.cpp142
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp14
-rw-r--r--lib/ExecutionEngine/JIT/JITMemoryManager.cpp54
-rw-r--r--lib/Target/Alpha/AlphaISelDAGToDAG.cpp68
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp3
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.cpp53
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.h12
-rw-r--r--lib/Target/Alpha/AlphaMachineFunctionInfo.h48
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp38
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp3
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp29
-rw-r--r--lib/Target/Mips/MipsInstrInfo.h6
-rw-r--r--lib/Target/Mips/MipsMachineFunction.h10
-rw-r--r--lib/Target/PIC16/PIC16.h2
-rw-r--r--lib/Target/PIC16/PIC16AsmPrinter.cpp12
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.cpp26
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.h7
-rw-r--r--lib/Target/PIC16/PIC16ISelLowering.cpp34
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.cpp28
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.h5
-rw-r--r--lib/Target/PIC16/PIC16InstrInfo.td8
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp34
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp3
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp22
-rw-r--r--test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll (renamed from test/Transforms/IndVarSimplify/variable-stride-ivs.ll)0
-rw-r--r--test/Transforms/IndVarSimplify/variable-stride-ivs-1.ll43
-rw-r--r--tools/llvm-config/CMakeLists.txt1
-rw-r--r--tools/llvm-ld/Optimize.cpp69
-rw-r--r--tools/lto/LTOCodeGenerator.cpp59
-rw-r--r--tools/opt/opt.cpp147
40 files changed, 1010 insertions, 611 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6af569b25a00..ba63484d8c0a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,8 @@ This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.
Please delete them.")
endif()
+string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
+
include(FindPerl)
set(LLVM_MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
@@ -55,6 +57,16 @@ endif( MSVC )
option(LLVM_ENABLE_THREADS "Use threads if available." ON)
+if( uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE" )
+ option(LLVM_ENABLE_ASSERTS "Enable asserts" OFF)
+else()
+ option(LLVM_ENABLE_ASSERTS "Enable asserts" ON)
+endif()
+
+if( LLVM_ENABLE_ASSERTS )
+ add_definitions( -D_DEBUG -UNDEBUG )
+endif()
+
if( LLVM_TARGETS_TO_BUILD STREQUAL "all" )
set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} )
endif()
diff --git a/docs/CMake.html b/docs/CMake.html
index 27ec88ec9478..b329ca46d62e 100644
--- a/docs/CMake.html
+++ b/docs/CMake.html
@@ -248,6 +248,10 @@
<dt><b>LLVM_ENABLE_THREADS</b>:BOOL</dt>
<dd>Build with threads support, if available. Defaults to ON.</dd>
+ <dt><b>LLVM_ENABLE_ASSERTS</b>:BOOL</dt>
+ <dd>Enables code asserts. Defaults to ON if and only if
+ CMAKE_BUILD_TYPE is <i>Release</i>.</dd>
+
<dt><b>LLVM_ENABLE_PIC</b>:BOOL</dt>
<dd>Add the <i>-fPIC</i> flag to the compiler command-line, if the
compiler supports this flag. Some systems, like Windows, does not
diff --git a/docs/GoldPlugin.html b/docs/GoldPlugin.html
index ee014101bc24..6be5277efd16 100644
--- a/docs/GoldPlugin.html
+++ b/docs/GoldPlugin.html
@@ -14,6 +14,7 @@
<li><a href="#usage">Usage</a>
<ul>
<li><a href="#example1">Example of link time optimization</a></li>
+ <li><a href="#lto_autotools">Quickstart for using LTO with autotooled projects</a></li>
</ul></li>
<li><a href="#licensing">Licensing</a></li>
</ol>
@@ -136,6 +137,35 @@ $ llvm-gcc -use-gold-plugin a.o b.o -o main # &lt;-- link with LLVMgold plugin
</div>
<!--=========================================================================-->
+<div class="doc_section"><a name="lto_autotools">Quickstart for using LTO with autotooled projects</a></div>
+<!--=========================================================================-->
+<div class="doc_text">
+ <p><tt>gold</tt>, <tt>ar</tt> and <tt>nm</tt> all support plugins now, so everything should be
+ in place for an easy to use LTO build of autotooled projects:</p>
+ <ul>
+ <li>Follow the instructions <a href="#build">on how to build libLLVMgold.so</a>.</li>
+ <li>Install the newly built binutils to <tt>$PREFIX</tt></li>
+ <li>Copy <tt>Release/lib/libLLVMgold.so</tt> to
+ <tt>$PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/4.2.1/</tt> and
+ <tt>$PREFIX/lib/bfd-plugins/</tt></li>
+ <li>Set environment variables (<tt>$PREFIX</tt> is where you installed llvm-gcc and
+ binutils):
+ <pre class="doc_code">
+export CC="$PREFIX/bin/llvm-gcc -use-gold-plugin"
+export CXX="$PREFIX/bin/llvm-g++ -use-gold-plugin"
+export AR="$PREFIX/bin/ar --plugin libLLVMgold.so"
+export NM="$PREFIX/bin/nm --plugin libLLVMgold.so"
+export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
+export CFLAGS="-O4"
+ </pre>
+ </li>
+ <li>Configure &amp; build the project as usual: <tt>./configure &amp;&amp; make &amp;&amp; make check</tt> </li>
+ </ul>
+ <p> The environment variable settings may work for non-autotooled projects
+ too, but you may need to set the <tt>LD</tt> environment variable as well.</p>
+</div>
+
+<!--=========================================================================-->
<div class="doc_section"><a name="licensing">Licensing</a></div>
<!--=========================================================================-->
<div class="doc_text">
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index bf6b76ee9001..81a7c60bdb60 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -89,7 +89,7 @@ public:
/// emitByte - This callback is invoked when a byte needs to be written to the
/// output stream.
///
- void emitByte(uint8_t B) {
+ void emitByte(unsigned char B) {
if (CurBufferPtr != BufferEnd)
*CurBufferPtr++ = B;
}
@@ -99,10 +99,10 @@ public:
///
void emitWordLE(unsigned W) {
if (4 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 0);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
} else {
CurBufferPtr = BufferEnd;
}
@@ -113,10 +113,10 @@ public:
///
void emitWordBE(unsigned W) {
if (4 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 24);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
} else {
CurBufferPtr = BufferEnd;
}
@@ -127,14 +127,14 @@ public:
///
void emitDWordLE(uint64_t W) {
if (8 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 0);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 24);
- *CurBufferPtr++ = (uint8_t)(W >> 32);
- *CurBufferPtr++ = (uint8_t)(W >> 40);
- *CurBufferPtr++ = (uint8_t)(W >> 48);
- *CurBufferPtr++ = (uint8_t)(W >> 56);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 32);
+ *CurBufferPtr++ = (unsigned char)(W >> 40);
+ *CurBufferPtr++ = (unsigned char)(W >> 48);
+ *CurBufferPtr++ = (unsigned char)(W >> 56);
} else {
CurBufferPtr = BufferEnd;
}
@@ -145,14 +145,14 @@ public:
///
void emitDWordBE(uint64_t W) {
if (8 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 56);
- *CurBufferPtr++ = (uint8_t)(W >> 48);
- *CurBufferPtr++ = (uint8_t)(W >> 40);
- *CurBufferPtr++ = (uint8_t)(W >> 32);
- *CurBufferPtr++ = (uint8_t)(W >> 24);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 56);
+ *CurBufferPtr++ = (unsigned char)(W >> 48);
+ *CurBufferPtr++ = (unsigned char)(W >> 40);
+ *CurBufferPtr++ = (unsigned char)(W >> 32);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
} else {
CurBufferPtr = BufferEnd;
}
@@ -166,8 +166,8 @@ public:
if(Alignment <= (uintptr_t)(BufferEnd-CurBufferPtr)) {
// Move the current buffer ptr up to the specified alignment.
CurBufferPtr =
- (uint8_t*)(((uintptr_t)CurBufferPtr+Alignment-1) &
- ~(uintptr_t)(Alignment-1));
+ (unsigned char*)(((uintptr_t)CurBufferPtr+Alignment-1) &
+ ~(uintptr_t)(Alignment-1));
} else {
CurBufferPtr = BufferEnd;
}
@@ -178,7 +178,7 @@ public:
/// written to the output stream.
void emitULEB128Bytes(unsigned Value) {
do {
- uint8_t Byte = Value & 0x7f;
+ unsigned char Byte = Value & 0x7f;
Value >>= 7;
if (Value) Byte |= 0x80;
emitByte(Byte);
@@ -187,12 +187,12 @@ public:
/// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
/// written to the output stream.
- void emitSLEB128Bytes(int32_t Value) {
- int32_t Sign = Value >> (8 * sizeof(Value) - 1);
+ void emitSLEB128Bytes(int Value) {
+ int Sign = Value >> (8 * sizeof(Value) - 1);
bool IsMore;
do {
- uint8_t Byte = Value & 0x7f;
+ unsigned char Byte = Value & 0x7f;
Value >>= 7;
IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
if (IsMore) Byte |= 0x80;
@@ -205,14 +205,14 @@ public:
void emitString(const std::string &String) {
for (unsigned i = 0, N = static_cast<unsigned>(String.size());
i < N; ++i) {
- uint8_t C = String[i];
+ unsigned char C = String[i];
emitByte(C);
}
emitByte(0);
}
/// emitInt32 - Emit a int32 directive.
- void emitInt32(int32_t Value) {
+ void emitInt32(int Value) {
if (4 <= BufferEnd-CurBufferPtr) {
*((uint32_t*)CurBufferPtr) = Value;
CurBufferPtr += 4;
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
index aaa41a48cb27..226c4c2ad8fb 100644
--- a/include/llvm/CodeGen/MachineCodeEmitter.h
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -50,14 +50,14 @@ class MachineCodeEmitter {
protected:
/// BufferBegin/BufferEnd - Pointers to the start and end of the memory
/// allocated for this code buffer.
- uint8_t *BufferBegin, *BufferEnd;
+ unsigned char *BufferBegin, *BufferEnd;
/// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
/// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
/// this pointer is at BufferEnd, it will never move due to code emission, and
/// all code emission requests will be ignored (this is the buffer overflow
/// condition).
- uint8_t *CurBufferPtr;
+ unsigned char *CurBufferPtr;
public:
virtual ~MachineCodeEmitter() {}
@@ -96,7 +96,7 @@ public:
/// emitByte - This callback is invoked when a byte needs to be written to the
/// output stream.
///
- void emitByte(uint8_t B) {
+ void emitByte(unsigned char B) {
if (CurBufferPtr != BufferEnd)
*CurBufferPtr++ = B;
}
@@ -106,10 +106,10 @@ public:
///
void emitWordLE(unsigned W) {
if (4 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 0);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
} else {
CurBufferPtr = BufferEnd;
}
@@ -120,10 +120,10 @@ public:
///
void emitWordBE(unsigned W) {
if (4 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 24);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
} else {
CurBufferPtr = BufferEnd;
}
@@ -134,14 +134,14 @@ public:
///
void emitDWordLE(uint64_t W) {
if (8 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 0);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 24);
- *CurBufferPtr++ = (uint8_t)(W >> 32);
- *CurBufferPtr++ = (uint8_t)(W >> 40);
- *CurBufferPtr++ = (uint8_t)(W >> 48);
- *CurBufferPtr++ = (uint8_t)(W >> 56);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 32);
+ *CurBufferPtr++ = (unsigned char)(W >> 40);
+ *CurBufferPtr++ = (unsigned char)(W >> 48);
+ *CurBufferPtr++ = (unsigned char)(W >> 56);
} else {
CurBufferPtr = BufferEnd;
}
@@ -152,14 +152,14 @@ public:
///
void emitDWordBE(uint64_t W) {
if (8 <= BufferEnd-CurBufferPtr) {
- *CurBufferPtr++ = (uint8_t)(W >> 56);
- *CurBufferPtr++ = (uint8_t)(W >> 48);
- *CurBufferPtr++ = (uint8_t)(W >> 40);
- *CurBufferPtr++ = (uint8_t)(W >> 32);
- *CurBufferPtr++ = (uint8_t)(W >> 24);
- *CurBufferPtr++ = (uint8_t)(W >> 16);
- *CurBufferPtr++ = (uint8_t)(W >> 8);
- *CurBufferPtr++ = (uint8_t)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 56);
+ *CurBufferPtr++ = (unsigned char)(W >> 48);
+ *CurBufferPtr++ = (unsigned char)(W >> 40);
+ *CurBufferPtr++ = (unsigned char)(W >> 32);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
} else {
CurBufferPtr = BufferEnd;
}
@@ -173,8 +173,8 @@ public:
if(Alignment <= (uintptr_t)(BufferEnd-CurBufferPtr)) {
// Move the current buffer ptr up to the specified alignment.
CurBufferPtr =
- (uint8_t*)(((uintptr_t)CurBufferPtr+Alignment-1) &
- ~(uintptr_t)(Alignment-1));
+ (unsigned char*)(((uintptr_t)CurBufferPtr+Alignment-1) &
+ ~(uintptr_t)(Alignment-1));
} else {
CurBufferPtr = BufferEnd;
}
@@ -185,7 +185,7 @@ public:
/// written to the output stream.
void emitULEB128Bytes(unsigned Value) {
do {
- uint8_t Byte = Value & 0x7f;
+ unsigned char Byte = Value & 0x7f;
Value >>= 7;
if (Value) Byte |= 0x80;
emitByte(Byte);
@@ -194,12 +194,12 @@ public:
/// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
/// written to the output stream.
- void emitSLEB128Bytes(int32_t Value) {
- int32_t Sign = Value >> (8 * sizeof(Value) - 1);
+ void emitSLEB128Bytes(int Value) {
+ int Sign = Value >> (8 * sizeof(Value) - 1);
bool IsMore;
do {
- uint8_t Byte = Value & 0x7f;
+ unsigned char Byte = Value & 0x7f;
Value >>= 7;
IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
if (IsMore) Byte |= 0x80;
@@ -212,14 +212,14 @@ public:
void emitString(const std::string &String) {
for (unsigned i = 0, N = static_cast<unsigned>(String.size());
i < N; ++i) {
- uint8_t C = String[i];
+ unsigned char C = String[i];
emitByte(C);
}
emitByte(0);
}
/// emitInt32 - Emit a int32 directive.
- void emitInt32(int32_t Value) {
+ void emitInt32(int Value) {
if (4 <= BufferEnd-CurBufferPtr) {
*((uint32_t*)CurBufferPtr) = Value;
CurBufferPtr += 4;
diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h
index 688a1626d2c3..581300e6e370 100644
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -60,7 +60,7 @@ public:
/// getGOTBase - If this is managing a Global Offset Table, this method should
/// return a pointer to its base.
- virtual uint8_t *getGOTBase() const = 0;
+ virtual unsigned char *getGOTBase() const = 0;
/// SetDlsymTable - If the JIT must be able to relocate stubs after they have
/// been emitted, potentially because they are being copied to a process
@@ -89,8 +89,8 @@ public:
/// emit the function, so it doesn't pass in the size. Instead, this method
/// is required to pass back a "valid size". The JIT will be careful to not
/// write more than the returned ActualSize bytes of memory.
- virtual uint8_t *startFunctionBody(const Function *F,
- uintptr_t &ActualSize) = 0;
+ virtual unsigned char *startFunctionBody(const Function *F,
+ uintptr_t &ActualSize) = 0;
/// allocateStub - This method is called by the JIT to allocate space for a
/// function stub (used to handle limited branch displacements) while it is
@@ -100,8 +100,9 @@ public:
/// thunk for it. The stub should be "close" to the current function body,
/// but should not be included in the 'actualsize' returned by
/// startFunctionBody.
- virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment) = 0;
+ virtual unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment) =0;
+
/// endFunctionBody - This method is called when the JIT is done codegen'ing
/// the specified function. At this point we know the size of the JIT
@@ -109,11 +110,11 @@ public:
/// the startFunctionBody method) and FunctionEnd which is a pointer to the
/// actual end of the function. This method should mark the space allocated
/// and remember where it is in case the client wants to deallocate it.
- virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd) = 0;
+ virtual void endFunctionBody(const Function *F, unsigned char *FunctionStart,
+ unsigned char *FunctionEnd) = 0;
/// allocateSpace - Allocate a memory block of the given size.
- virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) = 0;
+ virtual unsigned char *allocateSpace(intptr_t Size, unsigned Alignment) = 0;
/// deallocateMemForFunction - Free JIT memory for the specified function.
/// This is never called when the JIT is currently emitting a function.
@@ -121,13 +122,14 @@ public:
/// startExceptionTable - When we finished JITing the function, if exception
/// handling is set, we emit the exception table.
- virtual uint8_t* startExceptionTable(const Function* F,
- uintptr_t &ActualSize) = 0;
+ virtual unsigned char* startExceptionTable(const Function* F,
+ uintptr_t &ActualSize) = 0;
/// endExceptionTable - This method is called when the JIT is done emitting
/// the exception table.
- virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
- uint8_t *TableEnd, uint8_t* FrameRegister) = 0;
+ virtual void endExceptionTable(const Function *F, unsigned char *TableStart,
+ unsigned char *TableEnd,
+ unsigned char* FrameRegister) = 0;
};
} // end namespace llvm.
diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h
new file mode 100644
index 000000000000..024c0194d4e0
--- /dev/null
+++ b/include/llvm/Support/StandardPasses.h
@@ -0,0 +1,250 @@
+//===-- llvm/Support/StandardPasses.h - Standard pass lists -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines utility functions for creating a "standard" set of
+// optimization passes, so that compilers and tools which use optimization
+// passes use the same set of standard passes.
+//
+// These are implemented as inline functions so that we do not have to worry
+// about link issues.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STANDARDPASSES_H
+#define LLVM_SUPPORT_STANDARDPASSES_H
+
+#include "llvm/PassManager.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/IPO.h"
+
+namespace llvm {
+ /// createStandardFunctionPasses - Add the standard list of function passes to
+ /// the provided pass manager.
+ ///
+ /// \arg OptimizationLevel - The optimization level, corresponding to -O0,
+ /// -O1, etc.
+ static inline void createStandardFunctionPasses(FunctionPassManager *PM,
+ unsigned OptimizationLevel);
+
+ /// createStandardModulePasses - Add the standard list of module passes to the
+ /// provided pass manager.
+ ///
+ /// \arg OptimizationLevel - The optimization level, corresponding to -O0,
+ /// -O1, etc.
+ /// \arg OptimizeSize - Whether the transformations should optimize for size.
+ /// \arg UnitAtATime - Allow passes which may make global module changes.
+ /// \arg UnrollLoops - Allow loop unrolling.
+ /// \arg SimplifyLibCalls - Allow library calls to be simplified.
+ /// \arg HaveExceptions - Whether the module may have code using exceptions.
+ /// \arg InliningPass - The inlining pass to use, if any, or null. This will
+ /// always be added, even at -O0.a
+ static inline void createStandardModulePasses(PassManager *PM,
+ unsigned OptimizationLevel,
+ bool OptimizeSize,
+ bool UnitAtATime,
+ bool UnrollLoops,
+ bool SimplifyLibCalls,
+ bool HaveExceptions,
+ Pass *InliningPass);
+
+ /// createStandardLTOPasses - Add the standard list of module passes suitable
+ /// for link time optimization.
+ ///
+ /// Internalize - Run the internalize pass.
+ /// RunInliner - Use a function inlining pass.
+ /// RunSecondGlobalOpt - Run the global optimizer pass twice.
+ /// VerifyEach - Run the verifier after each pass.
+ //
+ // FIXME: RunSecondGlobalOpt should go away once we resolve which of LTO or
+ // llvm-ld is better.
+ static inline void createStandardLTOPasses(PassManager *PM,
+ bool Internalize,
+ bool RunInliner,
+ bool RunSecondGlobalOpt,
+ bool VerifyEach);
+
+ // Implementations
+
+ static inline void createStandardFunctionPasses(FunctionPassManager *PM,
+ unsigned OptimizationLevel) {
+ if (OptimizationLevel > 0) {
+ PM->add(createCFGSimplificationPass());
+ if (OptimizationLevel == 1)
+ PM->add(createPromoteMemoryToRegisterPass());
+ else
+ PM->add(createScalarReplAggregatesPass());
+ PM->add(createInstructionCombiningPass());
+ }
+ }
+
+ static inline void createStandardModulePasses(PassManager *PM,
+ unsigned OptimizationLevel,
+ bool OptimizeSize,
+ bool UnitAtATime,
+ bool UnrollLoops,
+ bool SimplifyLibCalls,
+ bool HaveExceptions,
+ Pass *InliningPass) {
+ if (OptimizationLevel == 0) {
+ if (InliningPass)
+ PM->add(InliningPass);
+ } else {
+ if (UnitAtATime)
+ PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
+ PM->add(createCFGSimplificationPass()); // Clean up disgusting code
+ // Kill useless allocas
+ PM->add(createPromoteMemoryToRegisterPass());
+ if (UnitAtATime) {
+ PM->add(createGlobalOptimizerPass()); // Optimize out global vars
+ PM->add(createGlobalDCEPass()); // Remove unused fns and globs
+ // IP Constant Propagation
+ PM->add(createIPConstantPropagationPass());
+ PM->add(createDeadArgEliminationPass()); // Dead argument elimination
+ }
+ PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
+ PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
+ if (UnitAtATime) {
+ if (HaveExceptions)
+ PM->add(createPruneEHPass()); // Remove dead EH info
+ PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs
+ }
+ if (InliningPass)
+ PM->add(InliningPass);
+ if (OptimizationLevel > 2)
+ PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
+ if (SimplifyLibCalls)
+ PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
+ PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
+ PM->add(createJumpThreadingPass()); // Thread jumps.
+ PM->add(createCFGSimplificationPass()); // Merge & remove BBs
+ PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas
+ PM->add(createInstructionCombiningPass()); // Combine silly seq's
+ PM->add(createCondPropagationPass()); // Propagate conditionals
+ PM->add(createTailCallEliminationPass()); // Eliminate tail calls
+ PM->add(createCFGSimplificationPass()); // Merge & remove BBs
+ PM->add(createReassociatePass()); // Reassociate expressions
+ PM->add(createLoopRotatePass()); // Rotate Loop
+ PM->add(createLICMPass()); // Hoist loop invariants
+ PM->add(createLoopUnswitchPass(OptimizeSize));
+ PM->add(createLoopIndexSplitPass()); // Split loop index
+ PM->add(createInstructionCombiningPass());
+ PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
+ PM->add(createLoopDeletionPass()); // Delete dead loops
+ if (UnrollLoops)
+ PM->add(createLoopUnrollPass()); // Unroll small loops
+ PM->add(createInstructionCombiningPass()); // Clean up after the unroller
+ PM->add(createGVNPass()); // Remove redundancies
+ PM->add(createMemCpyOptPass()); // Remove memcpy / form memset
+ PM->add(createSCCPPass()); // Constant prop with SCCP
+
+ // Run instcombine after redundancy elimination to exploit opportunities
+ // opened up by them.
+ PM->add(createInstructionCombiningPass());
+ PM->add(createCondPropagationPass()); // Propagate conditionals
+ PM->add(createDeadStoreEliminationPass()); // Delete dead stores
+ PM->add(createAggressiveDCEPass()); // Delete dead instructions
+ PM->add(createCFGSimplificationPass()); // Merge & remove BBs
+
+ if (UnitAtATime) {
+ PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
+ PM->add(createDeadTypeEliminationPass()); // Eliminate dead types
+ }
+
+ if (OptimizationLevel > 1 && UnitAtATime)
+ PM->add(createConstantMergePass()); // Merge dup global constants
+ }
+ }
+
+ static inline void addOnePass(PassManager *PM, Pass *P, bool AndVerify) {
+ PM->add(P);
+
+ if (AndVerify)
+ PM->add(createVerifierPass());
+ }
+
+ static inline void createStandardLTOPasses(PassManager *PM,
+ bool Internalize,
+ bool RunInliner,
+ bool RunSecondGlobalOpt,
+ bool VerifyEach) {
+ // Now that composite has been compiled, scan through the module, looking
+ // for a main function. If main is defined, mark all other functions
+ // internal.
+ if (Internalize)
+ addOnePass(PM, createInternalizePass(true), VerifyEach);
+
+ // Propagate constants at call sites into the functions they call. This
+ // opens opportunities for globalopt (and inlining) by substituting function
+ // pointers passed as arguments to direct uses of functions.
+ addOnePass(PM, createIPSCCPPass(), VerifyEach);
+
+ // Now that we internalized some globals, see if we can hack on them!
+ addOnePass(PM, createGlobalOptimizerPass(), VerifyEach);
+
+ // Linking modules together can lead to duplicated global constants, only
+ // keep one copy of each constant...
+ addOnePass(PM, createConstantMergePass(), VerifyEach);
+
+ // Remove unused arguments from functions...
+ addOnePass(PM, createDeadArgEliminationPass(), VerifyEach);
+
+ // Reduce the code after globalopt and ipsccp. Both can open up significant
+ // simplification opportunities, and both can propagate functions through
+ // function pointers. When this happens, we often have to resolve varargs
+ // calls, etc, so let instcombine do this.
+ addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
+
+ // Inline small functions
+ if (RunInliner)
+ addOnePass(PM, createFunctionInliningPass(), VerifyEach);
+
+ addOnePass(PM, createPruneEHPass(), VerifyEach); // Remove dead EH info.
+ // Optimize globals again.
+ if (RunSecondGlobalOpt)
+ addOnePass(PM, createGlobalOptimizerPass(), VerifyEach);
+ addOnePass(PM, createGlobalDCEPass(), VerifyEach); // Remove dead functions.
+
+ // If we didn't decide to inline a function, check to see if we can
+ // transform it to pass arguments by value instead of by reference.
+ addOnePass(PM, createArgumentPromotionPass(), VerifyEach);
+
+ // The IPO passes may leave cruft around. Clean up after them.
+ addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
+ addOnePass(PM, createJumpThreadingPass(), VerifyEach);
+ // Break up allocas
+ addOnePass(PM, createScalarReplAggregatesPass(), VerifyEach);
+
+ // Run a few AA driven optimizations here and now, to cleanup the code.
+ addOnePass(PM, createFunctionAttrsPass(), VerifyEach); // Add nocapture.
+ addOnePass(PM, createGlobalsModRefPass(), VerifyEach); // IP alias analysis.
+
+ addOnePass(PM, createLICMPass(), VerifyEach); // Hoist loop invariants.
+ addOnePass(PM, createGVNPass(), VerifyEach); // Remove redundancies.
+ addOnePass(PM, createMemCpyOptPass(), VerifyEach); // Remove dead memcpys.
+ // Nuke dead stores.
+ addOnePass(PM, createDeadStoreEliminationPass(), VerifyEach);
+
+ // Cleanup and simplify the code after the scalar optimizations.
+ addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
+
+ addOnePass(PM, createJumpThreadingPass(), VerifyEach);
+ // Cleanup jump threading.
+ addOnePass(PM, createPromoteMemoryToRegisterPass(), VerifyEach);
+
+ // Delete basic blocks, which optimization passes may have killed...
+ addOnePass(PM, createCFGSimplificationPass(), VerifyEach);
+
+ // Now that we have optimized the program, discard unreachable functions.
+ addOnePass(PM, createGlobalDCEPass(), VerifyEach);
+ }
+}
+
+#endif
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index ca4b31c63774..ff917a72f0c8 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_library(LLVMCodeGen
CodePlacementOpt.cpp
DeadMachineInstructionElim.cpp
DwarfEHPrepare.cpp
+ ELFCodeEmitter.cpp
ELFWriter.cpp
GCMetadata.cpp
GCMetadataPrinter.cpp
@@ -16,6 +17,7 @@ add_llvm_library(LLVMCodeGen
LiveStackAnalysis.cpp
LiveVariables.cpp
LowerSubregs.cpp
+ MachOCodeEmitter.cpp
MachOWriter.cpp
MachineBasicBlock.cpp
MachineDominators.cpp
diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp
new file mode 100644
index 000000000000..0a0245f3dd59
--- /dev/null
+++ b/lib/CodeGen/ELFCodeEmitter.cpp
@@ -0,0 +1,94 @@
+//===-- lib/CodeGen/ELFCodeEmitter.cpp ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ELFCodeEmitter.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Support/OutputBuffer.h"
+
+//===----------------------------------------------------------------------===//
+// ELFCodeEmitter Implementation
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+/// startFunction - This callback is invoked when a new machine function is
+/// about to be emitted.
+void ELFCodeEmitter::startFunction(MachineFunction &F) {
+ // Align the output buffer to the appropriate alignment.
+ unsigned Align = 16; // FIXME: GENERICIZE!!
+ // Get the ELF Section that this function belongs in.
+ ES = &EW.getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS,
+ ELFWriter::ELFSection::SHF_EXECINSTR |
+ ELFWriter::ELFSection::SHF_ALLOC);
+ OutBuffer = &ES->SectionData;
+ cerr << "FIXME: This code needs to be updated for changes in the "
+ << "CodeEmitter interfaces. In particular, this should set "
+ << "BufferBegin/BufferEnd/CurBufferPtr, not deal with OutBuffer!";
+ abort();
+
+ // Upgrade the section alignment if required.
+ if (ES->Align < Align) ES->Align = Align;
+
+ // Add padding zeros to the end of the buffer to make sure that the
+ // function will start on the correct byte alignment within the section.
+ OutputBuffer OB(*OutBuffer,
+ TM.getTargetData()->getPointerSizeInBits() == 64,
+ TM.getTargetData()->isLittleEndian());
+ OB.align(Align);
+ FnStart = OutBuffer->size();
+}
+
+/// finishFunction - This callback is invoked after the function is completely
+/// finished.
+bool ELFCodeEmitter::finishFunction(MachineFunction &F) {
+ // We now know the size of the function, add a symbol to represent it.
+ ELFWriter::ELFSym FnSym(F.getFunction());
+
+ // Figure out the binding (linkage) of the symbol.
+ switch (F.getFunction()->getLinkage()) {
+ default:
+ // appending linkage is illegal for functions.
+ assert(0 && "Unknown linkage type!");
+ case GlobalValue::ExternalLinkage:
+ FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL);
+ break;
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
+ FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK);
+ break;
+ case GlobalValue::PrivateLinkage:
+ assert (0 && "PrivateLinkage should not be in the symbol table.");
+ case GlobalValue::InternalLinkage:
+ FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL);
+ break;
+ }
+
+ ES->Size = OutBuffer->size();
+
+ FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
+ FnSym.SectionIdx = ES->SectionIdx;
+ FnSym.Value = FnStart; // Value = Offset from start of Section.
+ FnSym.Size = OutBuffer->size()-FnStart;
+
+ // Finally, add it to the symtab.
+ EW.SymbolTable.push_back(FnSym);
+ return false;
+}
+
+} // end namespace llvm
diff --git a/lib/CodeGen/ELFCodeEmitter.h b/lib/CodeGen/ELFCodeEmitter.h
new file mode 100644
index 000000000000..11ebcc871da1
--- /dev/null
+++ b/lib/CodeGen/ELFCodeEmitter.h
@@ -0,0 +1,87 @@
+//===-- lib/CodeGen/ELFCodeEmitter.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ELFCODEEMITTER_H
+#define ELFCODEEMITTER_H
+
+#include "ELFWriter.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include <vector>
+
+namespace llvm {
+
+ /// ELFCodeEmitter - This class is used by the ELFWriter to
+ /// emit the code for functions to the ELF file.
+ class ELFCodeEmitter : public MachineCodeEmitter {
+ ELFWriter &EW;
+ TargetMachine &TM;
+ ELFWriter::ELFSection *ES; // Section to write to.
+ std::vector<unsigned char> *OutBuffer;
+ size_t FnStart;
+ public:
+ explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
+
+ void startFunction(MachineFunction &F);
+ bool finishFunction(MachineFunction &F);
+
+ void addRelocation(const MachineRelocation &MR) {
+ assert(0 && "relo not handled yet!");
+ }
+
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
+ }
+
+ virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
+ assert(0 && "CP not implementated yet!");
+ return 0;
+ }
+ virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
+ assert(0 && "JT not implementated yet!");
+ return 0;
+ }
+
+ virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
+ assert(0 && "JT not implementated yet!");
+ return 0;
+ }
+
+ virtual uintptr_t getLabelAddress(uint64_t Label) const {
+ assert(0 && "Label address not implementated yet!");
+ abort();
+ return 0;
+ }
+
+ virtual void emitLabel(uint64_t LabelID) {
+ assert(0 && "emit Label not implementated yet!");
+ abort();
+ }
+
+ virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
+ /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
+ void startGVStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment = 1) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ }
+ void startGVStub(const GlobalValue* F, void *Buffer, unsigned StubSize) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ }
+ void *finishGVStub(const GlobalValue *F) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ return 0;
+ }
+}; // end class ELFCodeEmitter
+
+} // end namespace llvm
+
+#endif
+
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index 7cc116235243..be8edce08d74 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -32,6 +32,7 @@
//===----------------------------------------------------------------------===//
#include "ELFWriter.h"
+#include "ELFCodeEmitter.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/DerivedTypes.h"
@@ -61,149 +62,10 @@ MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
}
//===----------------------------------------------------------------------===//
-// ELFCodeEmitter Implementation
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
- /// ELFCodeEmitter - This class is used by the ELFWriter to emit the code for
- /// functions to the ELF file.
- class ELFCodeEmitter : public MachineCodeEmitter {
- ELFWriter &EW;
- TargetMachine &TM;
- ELFWriter::ELFSection *ES; // Section to write to.
- std::vector<unsigned char> *OutBuffer;
- size_t FnStart;
- public:
- explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
-
- void startFunction(MachineFunction &F);
- bool finishFunction(MachineFunction &F);
-
- void addRelocation(const MachineRelocation &MR) {
- assert(0 && "relo not handled yet!");
- }
-
- virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
- }
-
- virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- assert(0 && "CP not implementated yet!");
- return 0;
- }
- virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
- assert(0 && "JT not implementated yet!");
- return 0;
- }
-
- virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
- assert(0 && "JT not implementated yet!");
- return 0;
- }
-
- virtual uintptr_t getLabelAddress(uint64_t Label) const {
- assert(0 && "Label address not implementated yet!");
- abort();
- return 0;
- }
-
- virtual void emitLabel(uint64_t LabelID) {
- assert(0 && "emit Label not implementated yet!");
- abort();
- }
-
-
- virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
-
-
- /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
- void startGVStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment = 1) {
- assert(0 && "JIT specific function called!");
- abort();
- }
- void startGVStub(const GlobalValue* F, void *Buffer, unsigned StubSize) {
- assert(0 && "JIT specific function called!");
- abort();
- }
- void *finishGVStub(const GlobalValue *F) {
- assert(0 && "JIT specific function called!");
- abort();
- return 0;
- }
- };
-}
-
-/// startFunction - This callback is invoked when a new machine function is
-/// about to be emitted.
-void ELFCodeEmitter::startFunction(MachineFunction &F) {
- // Align the output buffer to the appropriate alignment.
- unsigned Align = 16; // FIXME: GENERICIZE!!
- // Get the ELF Section that this function belongs in.
- ES = &EW.getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS,
- ELFWriter::ELFSection::SHF_EXECINSTR |
- ELFWriter::ELFSection::SHF_ALLOC);
- OutBuffer = &ES->SectionData;
- cerr << "FIXME: This code needs to be updated for changes in the "
- << "CodeEmitter interfaces. In particular, this should set "
- << "BufferBegin/BufferEnd/CurBufferPtr, not deal with OutBuffer!";
- abort();
-
- // Upgrade the section alignment if required.
- if (ES->Align < Align) ES->Align = Align;
-
- // Add padding zeros to the end of the buffer to make sure that the
- // function will start on the correct byte alignment within the section.
- OutputBuffer OB(*OutBuffer,
- TM.getTargetData()->getPointerSizeInBits() == 64,
- TM.getTargetData()->isLittleEndian());
- OB.align(Align);
- FnStart = OutBuffer->size();
-}
-
-/// finishFunction - This callback is invoked after the function is completely
-/// finished.
-bool ELFCodeEmitter::finishFunction(MachineFunction &F) {
- // We now know the size of the function, add a symbol to represent it.
- ELFWriter::ELFSym FnSym(F.getFunction());
-
- // Figure out the binding (linkage) of the symbol.
- switch (F.getFunction()->getLinkage()) {
- default:
- // appending linkage is illegal for functions.
- assert(0 && "Unknown linkage type!");
- case GlobalValue::ExternalLinkage:
- FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL);
- break;
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK);
- break;
- case GlobalValue::PrivateLinkage:
- assert (0 && "PrivateLinkage should not be in the symbol table.");
- case GlobalValue::InternalLinkage:
- FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL);
- break;
- }
-
- ES->Size = OutBuffer->size();
-
- FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
- FnSym.SectionIdx = ES->SectionIdx;
- FnSym.Value = FnStart; // Value = Offset from start of Section.
- FnSym.Size = OutBuffer->size()-FnStart;
-
- // Finally, add it to the symtab.
- EW.SymbolTable.push_back(FnSym);
- return false;
-}
-
-//===----------------------------------------------------------------------===//
// ELFWriter Implementation
//===----------------------------------------------------------------------===//
-ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
+ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
: MachineFunctionPass(&ID), O(o), TM(tm) {
e_flags = 0; // e_flags defaults to 0, no flags.
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index d3b0820c5f05..89131a0dde7f 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -551,7 +551,7 @@ namespace {
// When outputting a function stub in the context of some other function, we
// save BufferBegin/BufferEnd/CurBufferPtr here.
- uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr;
+ unsigned char *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr;
/// Relocations - These are the relocations that the function needs, as
/// emitted.
@@ -1056,11 +1056,11 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
// FnStart is the start of the text, not the start of the constant pool and
// other per-function data.
- uint8_t *FnStart =
- (uint8_t *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction());
+ unsigned char *FnStart =
+ (unsigned char *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction());
// FnEnd is the end of the function's machine code.
- uint8_t *FnEnd = CurBufferPtr;
+ unsigned char *FnEnd = CurBufferPtr;
if (!Relocations.empty()) {
CurFn = F.getFunction();
@@ -1183,7 +1183,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
} else {
DOUT << "JIT: Binary code:\n";
DOUT << std::hex;
- uint8_t* q = FnStart;
+ unsigned char* q = FnStart;
for (int i = 0; q < FnEnd; q += 4, ++i) {
if (i == 4)
i = 0;
@@ -1221,7 +1221,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
ActualSize);
BufferEnd = BufferBegin+ActualSize;
- uint8_t* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd);
+ unsigned char* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd);
MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
FrameRegister);
BufferBegin = SavedBufferBegin;
@@ -1416,7 +1416,7 @@ void JITEmitter::startGVStub(const GlobalValue* GV, void *Buffer,
SavedBufferEnd = BufferEnd;
SavedCurBufferPtr = CurBufferPtr;
- BufferBegin = CurBufferPtr = (uint8_t *)Buffer;
+ BufferBegin = CurBufferPtr = (unsigned char *)Buffer;
BufferEnd = BufferBegin+StubSize+1;
}
diff --git a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
index 70ccdccb8049..2819b6d4653b 100644
--- a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
+++ b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
@@ -257,9 +257,9 @@ namespace {
// When emitting code into a memory block, this is the block.
MemoryRangeHeader *CurBlock;
- uint8_t *CurStubPtr, *StubBase;
- uint8_t *GOTBase; // Target Specific reserved memory
- void *DlsymTable; // Stub external symbol information
+ unsigned char *CurStubPtr, *StubBase;
+ unsigned char *GOTBase; // Target Specific reserved memory
+ void *DlsymTable; // Stub external symbol information
// Centralize memory block allocation.
sys::MemoryBlock getNewMemoryBlock(unsigned size);
@@ -273,12 +273,12 @@ namespace {
void AllocateGOT();
void SetDlsymTable(void *);
- uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment);
+ unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment);
/// startFunctionBody - When a function starts, allocate a block of free
/// executable memory, returning a pointer to it and its actual size.
- uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize) {
+ unsigned char *startFunctionBody(const Function *F, uintptr_t &ActualSize) {
FreeRangeHeader* candidateBlock = FreeMemoryList;
FreeRangeHeader* head = FreeMemoryList;
@@ -301,18 +301,18 @@ namespace {
// Allocate the entire memory block.
FreeMemoryList = candidateBlock->AllocateBlock();
ActualSize = CurBlock->BlockSize-sizeof(MemoryRangeHeader);
- return (uint8_t *)(CurBlock+1);
+ return (unsigned char *)(CurBlock+1);
}
/// endFunctionBody - The function F is now allocated, and takes the memory
/// in the range [FunctionStart,FunctionEnd).
- void endFunctionBody(const Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd) {
+ void endFunctionBody(const Function *F, unsigned char *FunctionStart,
+ unsigned char *FunctionEnd) {
assert(FunctionEnd > FunctionStart);
- assert(FunctionStart == (uint8_t *)(CurBlock+1) &&
+ assert(FunctionStart == (unsigned char *)(CurBlock+1) &&
"Mismatched function start/end!");
- uintptr_t BlockSize = FunctionEnd - (uint8_t *)CurBlock;
+ uintptr_t BlockSize = FunctionEnd - (unsigned char *)CurBlock;
FunctionBlocks[F] = CurBlock;
// Release the memory at the end of this block that isn't needed.
@@ -320,17 +320,17 @@ namespace {
}
/// allocateSpace - Allocate a memory block of the given size.
- uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
+ unsigned char *allocateSpace(intptr_t Size, unsigned Alignment) {
CurBlock = FreeMemoryList;
FreeMemoryList = FreeMemoryList->AllocateBlock();
- uint8_t *result = (uint8_t *)CurBlock+1;
+ unsigned char *result = (unsigned char *)CurBlock+1;
if (Alignment == 0) Alignment = 1;
- result = (uint8_t*)(((intptr_t)result+Alignment-1) &
+ result = (unsigned char*)(((intptr_t)result+Alignment-1) &
~(intptr_t)(Alignment-1));
- uintptr_t BlockSize = result + Size - (uint8_t *)CurBlock;
+ uintptr_t BlockSize = result + Size - (unsigned char *)CurBlock;
FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
return result;
@@ -338,26 +338,28 @@ namespace {
/// startExceptionTable - Use startFunctionBody to allocate memory for the
/// function's exception table.
- uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) {
+ unsigned char* startExceptionTable(const Function* F,
+ uintptr_t &ActualSize) {
return startFunctionBody(F, ActualSize);
}
/// endExceptionTable - The exception table of F is now allocated,
/// and takes the memory in the range [TableStart,TableEnd).
- void endExceptionTable(const Function *F, uint8_t *TableStart,
- uint8_t *TableEnd, uint8_t* FrameRegister) {
+ void endExceptionTable(const Function *F, unsigned char *TableStart,
+ unsigned char *TableEnd,
+ unsigned char* FrameRegister) {
assert(TableEnd > TableStart);
- assert(TableStart == (uint8_t *)(CurBlock+1) &&
+ assert(TableStart == (unsigned char *)(CurBlock+1) &&
"Mismatched table start/end!");
- uintptr_t BlockSize = TableEnd - (uint8_t *)CurBlock;
+ uintptr_t BlockSize = TableEnd - (unsigned char *)CurBlock;
TableBlocks[F] = CurBlock;
// Release the memory at the end of this block that isn't needed.
FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
}
- uint8_t *getGOTBase() const {
+ unsigned char *getGOTBase() const {
return GOTBase;
}
@@ -431,7 +433,7 @@ DefaultJITMemoryManager::DefaultJITMemoryManager() {
sys::MemoryBlock MemBlock = getNewMemoryBlock(16 << 20);
#endif
- uint8_t *MemBase = static_cast<uint8_t*>(MemBlock.base());
+ unsigned char *MemBase = static_cast<unsigned char*>(MemBlock.base());
// Allocate stubs backwards from the base, allocate functions forward
// from the base.
@@ -490,7 +492,7 @@ DefaultJITMemoryManager::DefaultJITMemoryManager() {
void DefaultJITMemoryManager::AllocateGOT() {
assert(GOTBase == 0 && "Cannot allocate the got multiple times");
- GOTBase = new uint8_t[sizeof(void*) * 8192];
+ GOTBase = new unsigned char[sizeof(void*) * 8192];
HasGOT = true;
}
@@ -506,12 +508,12 @@ DefaultJITMemoryManager::~DefaultJITMemoryManager() {
Blocks.clear();
}
-uint8_t *DefaultJITMemoryManager::allocateStub(const GlobalValue* F,
+unsigned char *DefaultJITMemoryManager::allocateStub(const GlobalValue* F,
unsigned StubSize,
unsigned Alignment) {
CurStubPtr -= StubSize;
- CurStubPtr = (uint8_t*)(((intptr_t)CurStubPtr) &
- ~(intptr_t)(Alignment-1));
+ CurStubPtr = (unsigned char*)(((intptr_t)CurStubPtr) &
+ ~(intptr_t)(Alignment-1));
if (CurStubPtr < StubBase) {
// FIXME: allocate a new block
fprintf(stderr, "JIT ran out of memory for function stubs!\n");
diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
index affcd3e7fec8..e3f631a1f5be 100644
--- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
+++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
@@ -185,8 +185,20 @@ namespace {
#include "AlphaGenDAGISel.inc"
private:
- SDValue getGlobalBaseReg();
- SDValue getGlobalRetAddr();
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const AlphaTargetMachine &getTargetMachine() {
+ return static_cast<const AlphaTargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const AlphaInstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
+ SDNode *getGlobalBaseReg();
+ SDNode *getGlobalRetAddr();
void SelectCALL(SDValue Op);
};
@@ -195,34 +207,18 @@ private:
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
///
-SDValue AlphaDAGToDAGISel::getGlobalBaseReg() {
- unsigned GP = 0;
- for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(),
- ee = RegInfo->livein_end(); ii != ee; ++ii)
- if (ii->first == Alpha::R29) {
- GP = ii->second;
- break;
- }
- assert(GP && "GOT PTR not in liveins");
- // FIXME is there anywhere sensible to get a DebugLoc here?
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- DebugLoc::getUnknownLoc(), GP, MVT::i64);
+SDNode *AlphaDAGToDAGISel::getGlobalBaseReg() {
+ MachineFunction *MF = BB->getParent();
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
+ return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
-/// getRASaveReg - Grab the return address
+/// getGlobalRetAddr - Grab the return address.
///
-SDValue AlphaDAGToDAGISel::getGlobalRetAddr() {
- unsigned RA = 0;
- for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(),
- ee = RegInfo->livein_end(); ii != ee; ++ii)
- if (ii->first == Alpha::R26) {
- RA = ii->second;
- break;
- }
- assert(RA && "RA PTR not in liveins");
- // FIXME is there anywhere sensible to get a DebugLoc here?
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- DebugLoc::getUnknownLoc(), RA, MVT::i64);
+SDNode *AlphaDAGToDAGISel::getGlobalRetAddr() {
+ MachineFunction *MF = BB->getParent();
+ unsigned GlobalRetAddr = getInstrInfo()->getGlobalRetAddr(MF);
+ return CurDAG->getRegister(GlobalRetAddr, TLI.getPointerTy()).getNode();
}
/// InstructionSelect - This callback is invoked by
@@ -256,16 +252,10 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
CurDAG->getTargetFrameIndex(FI, MVT::i32),
getI64Imm(0));
}
- case ISD::GLOBAL_OFFSET_TABLE: {
- SDValue Result = getGlobalBaseReg();
- ReplaceUses(Op, Result);
- return NULL;
- }
- case AlphaISD::GlobalRetAddr: {
- SDValue Result = getGlobalRetAddr();
- ReplaceUses(Op, Result);
- return NULL;
- }
+ case ISD::GLOBAL_OFFSET_TABLE:
+ return getGlobalBaseReg();
+ case AlphaISD::GlobalRetAddr:
+ return getGlobalRetAddr();
case AlphaISD::DivCall: {
SDValue Chain = CurDAG->getEntryNode();
@@ -315,7 +305,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
ConstantInt *C = ConstantInt::get(Type::Int64Ty, uval);
SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
SDNode *Tmp = CurDAG->getTargetNode(Alpha::LDAHr, dl, MVT::i64, CPI,
- getGlobalBaseReg());
+ SDValue(getGlobalBaseReg(), 0));
return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other,
CPI, SDValue(Tmp, 0), CurDAG->getEntryNode());
}
@@ -503,7 +493,7 @@ void AlphaDAGToDAGISel::SelectCALL(SDValue Op) {
// Finally, once everything is in registers to pass to the call, emit the
// call itself.
if (Addr.getOpcode() == AlphaISD::GPRelLo) {
- SDValue GOT = getGlobalBaseReg();
+ SDValue GOT = SDValue(getGlobalBaseReg(), 0);
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R29, GOT, InFlag);
InFlag = Chain.getValue(1);
Chain = SDValue(CurDAG->getTargetNode(Alpha::BSR, dl, MVT::Other,
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 10011125cf85..7ed8ef60302d 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -223,9 +223,6 @@ static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG,
SDValue Root = Op.getOperand(0);
DebugLoc dl = Op.getDebugLoc();
- AddLiveIn(MF, Alpha::R29, &Alpha::GPRCRegClass); //GP
- AddLiveIn(MF, Alpha::R26, &Alpha::GPRCRegClass); //RA
-
unsigned args_int[] = {
Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21};
unsigned args_float[] = {
diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp
index a54d97d33c40..229f9d4784a4 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.cpp
+++ b/lib/Target/Alpha/AlphaInstrInfo.cpp
@@ -13,7 +13,9 @@
#include "Alpha.h"
#include "AlphaInstrInfo.h"
+#include "AlphaMachineFunctionInfo.h"
#include "AlphaGenInstrInfo.inc"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -448,3 +450,54 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
return false;
}
+/// getGlobalBaseReg - Return a virtual register initialized with the
+/// the global base register value. Output instructions required to
+/// initialize the register in the function entry block, if necessary.
+///
+unsigned AlphaInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
+ AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
+ unsigned GlobalBaseReg = AlphaFI->getGlobalBaseReg();
+ if (GlobalBaseReg != 0)
+ return GlobalBaseReg;
+
+ // Insert the set of GlobalBaseReg into the first MBB of the function
+ MachineBasicBlock &FirstMBB = MF->front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ MachineRegisterInfo &RegInfo = MF->getRegInfo();
+ const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+
+ GlobalBaseReg = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
+ bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, Alpha::R29,
+ &Alpha::GPRCRegClass, &Alpha::GPRCRegClass);
+ assert(Ok && "Couldn't assign to global base register!");
+ RegInfo.addLiveIn(Alpha::R29);
+
+ AlphaFI->setGlobalBaseReg(GlobalBaseReg);
+ return GlobalBaseReg;
+}
+
+/// getGlobalRetAddr - Return a virtual register initialized with the
+/// the global base register value. Output instructions required to
+/// initialize the register in the function entry block, if necessary.
+///
+unsigned AlphaInstrInfo::getGlobalRetAddr(MachineFunction *MF) const {
+ AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
+ unsigned GlobalRetAddr = AlphaFI->getGlobalRetAddr();
+ if (GlobalRetAddr != 0)
+ return GlobalRetAddr;
+
+ // Insert the set of GlobalRetAddr into the first MBB of the function
+ MachineBasicBlock &FirstMBB = MF->front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ MachineRegisterInfo &RegInfo = MF->getRegInfo();
+ const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+
+ GlobalRetAddr = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
+ bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalRetAddr, Alpha::R26,
+ &Alpha::GPRCRegClass, &Alpha::GPRCRegClass);
+ assert(Ok && "Couldn't assign to global return address register!");
+ RegInfo.addLiveIn(Alpha::R26);
+
+ AlphaFI->setGlobalRetAddr(GlobalRetAddr);
+ return GlobalRetAddr;
+}
diff --git a/lib/Target/Alpha/AlphaInstrInfo.h b/lib/Target/Alpha/AlphaInstrInfo.h
index 182aa32f447a..ea0988553acc 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.h
+++ b/lib/Target/Alpha/AlphaInstrInfo.h
@@ -90,6 +90,18 @@ public:
MachineBasicBlock::iterator MI) const;
bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
+
+ /// getGlobalBaseReg - Return a virtual register initialized with the
+ /// the global base register value. Output instructions required to
+ /// initialize the register in the function entry block, if necessary.
+ ///
+ unsigned getGlobalBaseReg(MachineFunction *MF) const;
+
+ /// getGlobalRetAddr - Return a virtual register initialized with the
+ /// the global return address register value. Output instructions required to
+ /// initialize the register in the function entry block, if necessary.
+ ///
+ unsigned getGlobalRetAddr(MachineFunction *MF) const;
};
}
diff --git a/lib/Target/Alpha/AlphaMachineFunctionInfo.h b/lib/Target/Alpha/AlphaMachineFunctionInfo.h
new file mode 100644
index 000000000000..47de5dfad94d
--- /dev/null
+++ b/lib/Target/Alpha/AlphaMachineFunctionInfo.h
@@ -0,0 +1,48 @@
+//====- AlphaMachineFuctionInfo.h - Alpha machine function info -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares Alpha-specific per-machine-function information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALPHAMACHINEFUNCTIONINFO_H
+#define ALPHAMACHINEFUNCTIONINFO_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+/// AlphaMachineFunctionInfo - This class is derived from MachineFunction
+/// private Alpha target-specific information for each MachineFunction.
+class AlphaMachineFunctionInfo : public MachineFunctionInfo {
+ /// GlobalBaseReg - keeps track of the virtual register initialized for
+ /// use as the global base register. This is used for PIC in some PIC
+ /// relocation models.
+ unsigned GlobalBaseReg;
+
+ /// GlobalRetAddr = keeps track of the virtual register initialized for
+ /// the return address value.
+ unsigned GlobalRetAddr;
+
+public:
+ AlphaMachineFunctionInfo() : GlobalBaseReg(0), GlobalRetAddr(0) {}
+
+ AlphaMachineFunctionInfo(MachineFunction &MF) : GlobalBaseReg(0),
+ GlobalRetAddr(0) {}
+
+ unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
+ void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
+
+ unsigned getGlobalRetAddr() const { return GlobalRetAddr; }
+ void setGlobalRetAddr(unsigned Reg) { GlobalRetAddr = Reg; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index f05ac702ccdd..53de1bbea66e 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -70,7 +70,19 @@ private:
// Include the pieces autogenerated from the target description.
#include "MipsGenDAGISel.inc"
- SDValue getGlobalBaseReg();
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const MipsTargetMachine &getTargetMachine() {
+ return static_cast<const MipsTargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const MipsInstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
+ SDNode *getGlobalBaseReg();
SDNode *Select(SDValue N);
// Complex Pattern.
@@ -116,19 +128,10 @@ InstructionSelect()
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
-SDValue MipsDAGToDAGISel::getGlobalBaseReg() {
- MachineFunction* MF = BB->getParent();
- unsigned GP = 0;
- for(MachineRegisterInfo::livein_iterator ii = MF->getRegInfo().livein_begin(),
- ee = MF->getRegInfo().livein_end(); ii != ee; ++ii)
- if (ii->first == Mips::GP) {
- GP = ii->second;
- break;
- }
- assert(GP && "GOT PTR not in liveins");
- // FIXME is there a sensible place to get debug info for this?
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- DebugLoc::getUnknownLoc(), GP, MVT::i32);
+SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
+ MachineFunction *MF = BB->getParent();
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
+ return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
/// ComplexPattern used on MipsInstrInfo
@@ -321,11 +324,8 @@ Select(SDValue N)
}
// Get target GOT address.
- case ISD::GLOBAL_OFFSET_TABLE: {
- SDValue Result = getGlobalBaseReg();
- ReplaceUses(N, Result);
- return NULL;
- }
+ case ISD::GLOBAL_OFFSET_TABLE:
+ return getGlobalBaseReg();
/// Handle direct and indirect calls when using PIC. On PIC, when
/// GOT is smaller than about 64k (small code) the GA target is
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 9281940019a9..4517cfc96a43 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -941,9 +941,6 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG)
unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
- // GP must be live into PIC and non-PIC call target.
- AddLiveIn(MF, Mips::GP, Mips::CPURegsRegisterClass);
-
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 6225fa9c9884..92af973b0d21 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -13,8 +13,10 @@
#include "MipsInstrInfo.h"
#include "MipsTargetMachine.h"
+#include "MipsMachineFunction.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "MipsGenInstrInfo.inc"
using namespace llvm;
@@ -621,3 +623,30 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm()));
return false;
}
+
+/// getGlobalBaseReg - Return a virtual register initialized with the
+/// the global base register value. Output instructions required to
+/// initialize the register in the function entry block, if necessary.
+///
+unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
+ MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
+ unsigned GlobalBaseReg = MipsFI->getGlobalBaseReg();
+ if (GlobalBaseReg != 0)
+ return GlobalBaseReg;
+
+ // Insert the set of GlobalBaseReg into the first MBB of the function
+ MachineBasicBlock &FirstMBB = MF->front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ MachineRegisterInfo &RegInfo = MF->getRegInfo();
+ const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+
+ GlobalBaseReg = RegInfo.createVirtualRegister(Mips::CPURegsRegisterClass);
+ bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, Mips::GP,
+ Mips::CPURegsRegisterClass,
+ Mips::CPURegsRegisterClass);
+ assert(Ok && "Couldn't assign to global base register!");
+ RegInfo.addLiveIn(Mips::GP);
+
+ MipsFI->setGlobalBaseReg(GlobalBaseReg);
+ return GlobalBaseReg;
+}
diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h
index 334244e6601a..6655c6749fdf 100644
--- a/lib/Target/Mips/MipsInstrInfo.h
+++ b/lib/Target/Mips/MipsInstrInfo.h
@@ -216,6 +216,12 @@ public:
/// Insert nop instruction when hazard condition is found
virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
+
+ /// getGlobalBaseReg - Return a virtual register initialized with the
+ /// the global base register value. Output instructions required to
+ /// initialize the register in the function entry block, if necessary.
+ ///
+ unsigned getGlobalBaseReg(MachineFunction *MF) const;
};
}
diff --git a/lib/Target/Mips/MipsMachineFunction.h b/lib/Target/Mips/MipsMachineFunction.h
index b95394ec81ce..ac3cdfd38e16 100644
--- a/lib/Target/Mips/MipsMachineFunction.h
+++ b/lib/Target/Mips/MipsMachineFunction.h
@@ -75,11 +75,16 @@ private:
/// holds the virtual register into which the sret argument is passed.
unsigned SRetReturnReg;
+ /// GlobalBaseReg - keeps track of the virtual register initialized for
+ /// use as the global base register. This is used for PIC in some PIC
+ /// relocation models.
+ unsigned GlobalBaseReg;
+
public:
MipsFunctionInfo(MachineFunction& MF)
: FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0),
FPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false),
- HasStoreVarArgs(false), SRetReturnReg(0)
+ HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0)
{}
int getFPStackOffset() const { return FPStackOffset; }
@@ -124,6 +129,9 @@ public:
unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
+
+ unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
+ void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
};
} // end of namespace llvm
diff --git a/lib/Target/PIC16/PIC16.h b/lib/Target/PIC16/PIC16.h
index 40bed2f50e10..cf0f9db9e811 100644
--- a/lib/Target/PIC16/PIC16.h
+++ b/lib/Target/PIC16/PIC16.h
@@ -300,9 +300,11 @@ namespace PIC16CC {
case PIC16CC::LT: return "lt";
case PIC16CC::ULT: return "lt";
case PIC16CC::LE: return "le";
+ case PIC16CC::ULE: return "le";
case PIC16CC::GT: return "gt";
case PIC16CC::UGT: return "gt";
case PIC16CC::GE: return "ge";
+ case PIC16CC::UGE: return "ge";
}
}
diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp
index ef3bc4b52a96..b42ee4524beb 100644
--- a/lib/Target/PIC16/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp
@@ -47,6 +47,7 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
const Function *F = MF.getFunction();
CurrentFnName = Mang->getValueName(F);
+ DbgInfo.EmitFileDirective(F);
// Emit the function variables.
EmitFunctionFrame(MF);
@@ -181,17 +182,11 @@ void PIC16AsmPrinter::printLibcallDecls(void) {
bool PIC16AsmPrinter::doInitialization (Module &M) {
bool Result = AsmPrinter::doInitialization(M);
- DbgInfo.EmitFileDirective(M);
// FIXME:: This is temporary solution to generate the include file.
// The processor should be passed to llc as in input and the header file
// should be generated accordingly.
O << "\n\t#include P16F1937.INC\n";
- MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
- assert(MMI);
- DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
- assert(DW && "Dwarf Writer is not available");
- DW->BeginModule(&M, MMI, O, this, TAI);
// Set the section names for all globals.
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
@@ -199,13 +194,14 @@ bool PIC16AsmPrinter::doInitialization (Module &M) {
I->setSection(TAI->SectionForGlobal(I)->getName());
}
+ DbgInfo.EmitFileDirective(M);
EmitFunctionDecls(M);
EmitUndefinedVars(M);
EmitDefinedVars(M);
EmitIData(M);
EmitUData(M);
EmitRomData(M);
- DbgInfo.PopulateFunctsDI(M);
+ DbgInfo.PopulateFunctsDI(M);
return Result;
}
@@ -285,7 +281,7 @@ void PIC16AsmPrinter::EmitRomData (Module &M)
bool PIC16AsmPrinter::doFinalization(Module &M) {
printLibcallDecls();
DbgInfo.EmitVarDebugInfo(M);
- O << "\n\t" << ".EOF";
+ DbgInfo.EmitEOF();
O << "\n\t" << "END\n";
bool Result = AsmPrinter::doFinalization(M);
return Result;
diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp
index 4d43811f24a6..faf4590b43ee 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.cpp
+++ b/lib/Target/PIC16/PIC16DebugInfo.cpp
@@ -264,7 +264,29 @@ void PIC16DbgInfo::EmitFileDirective(Module &M) {
if (CU) {
DICompileUnit DIUnit(CU);
std::string Dir, FN;
- O << "\n\t.file\t\"" << DIUnit.getDirectory(Dir) <<"/"
- << DIUnit.getFilename(FN) << "\"" ;
+ std::string File = DIUnit.getDirectory(Dir) + "/" + DIUnit.getFilename(FN);
+ O << "\n\t.file\t\"" << File << "\"\n" ;
+ CurFile = File;
}
}
+
+void PIC16DbgInfo::EmitFileDirective(const Function *F) {
+ std::string FunctName = F->getName();
+ DISubprogram *SP = getFunctDI(FunctName);
+ if (SP) {
+ std::string Dir, FN;
+ DICompileUnit CU = SP->getCompileUnit();
+ std::string File = CU.getDirectory(Dir) + "/" + CU.getFilename(FN);
+ if ( File != CurFile) {
+ EmitEOF();
+ O << "\n\t.file\t\"" << File << "\"\n" ;
+ CurFile = File;
+ }
+ }
+}
+
+void PIC16DbgInfo::EmitEOF() {
+ if (CurFile != "")
+ O << "\n\t.EOF";
+}
+
diff --git a/lib/Target/PIC16/PIC16DebugInfo.h b/lib/Target/PIC16/PIC16DebugInfo.h
index 96b23da403c3..be3939336b24 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.h
+++ b/lib/Target/PIC16/PIC16DebugInfo.h
@@ -94,8 +94,11 @@ namespace llvm {
std::map <std::string, DISubprogram *> FunctNameMap;
raw_ostream &O;
const TargetAsmInfo *TAI;
+ std::string CurFile;
public:
- PIC16DbgInfo(raw_ostream &o, const TargetAsmInfo *T) : O(o), TAI(T) {}
+ PIC16DbgInfo(raw_ostream &o, const TargetAsmInfo *T) : O(o), TAI(T) {
+ CurFile = "";
+ }
~PIC16DbgInfo();
void PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, bool &HasAux,
int Aux[], std::string &TypeName);
@@ -109,6 +112,8 @@ namespace llvm {
inline void EmitSymbol(std::string Name, int Class);
void EmitVarDebugInfo(Module &M);
void EmitFileDirective(Module &M);
+ void EmitFileDirective(const Function *F);
+ void EmitEOF();
};
} // end namespace llvm;
#endif
diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp
index 92fdcb2c0c15..0f83fd2353a9 100644
--- a/lib/Target/PIC16/PIC16ISelLowering.cpp
+++ b/lib/Target/PIC16/PIC16ISelLowering.cpp
@@ -354,16 +354,29 @@ SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N, SelectionDAG &DAG) {
FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(SDValue(N,0));
// FIXME there isn't really debug info here
DebugLoc dl = FR->getDebugLoc();
- int Index = FR->getIndex();
+ // FIXME: Not used.
+ // int Index = FR->getIndex();
// Expand FrameIndex like GlobalAddress and ExternalSymbol
// Also use Offset field for lo and hi parts. The default
// offset is zero.
+
+ /*
SDValue Offset = DAG.getConstant(0, MVT::i8);
SDValue FI = DAG.getTargetFrameIndex(Index, MVT::i8);
SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, FI, Offset);
SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, FI, Offset);
return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), Lo, Hi);
+ */
+
+ SDValue ES;
+ int FrameOffset;
+ SDValue FI = SDValue(N,0);
+ LegalizeFrameIndex(FI, DAG, ES, FrameOffset);
+ SDValue Offset = DAG.getConstant(FrameOffset, MVT::i8);
+ SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, ES, Offset);
+ SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, ES, Offset);
+ return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), Lo, Hi);
}
@@ -626,12 +639,22 @@ void PIC16TargetLowering::LegalizeAddress(SDValue Ptr, SelectionDAG &DAG,
// Expansion of FrameIndex has Lo/Hi parts
if (isDirectAddress(Ptr)) {
SDValue TFI = Ptr.getOperand(0).getOperand(0);
+ int FrameOffset;
if (TFI.getOpcode() == ISD::TargetFrameIndex) {
- int FrameOffset;
LegalizeFrameIndex(TFI, DAG, Lo, FrameOffset);
Hi = DAG.getConstant(1, MVT::i8);
Offset += FrameOffset;
return;
+ } else if (TFI.getOpcode() == ISD::TargetExternalSymbol) {
+ // FrameIndex has already been expanded.
+ // Now just make use of its expansion
+ Lo = TFI;
+ Hi = DAG.getConstant(1, MVT::i8);
+ SDValue FOffset = Ptr.getOperand(0).getOperand(1);
+ assert (FOffset.getOpcode() == ISD::Constant &&
+ "Invalid operand of PIC16ISD::Lo");
+ Offset += dyn_cast<ConstantSDNode>(FOffset)->getZExtValue();
+ return;
}
}
@@ -721,7 +744,8 @@ SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
for (iter=MemBytes; iter<ExtdBytes; ++iter) {
PICLoads.push_back(SRA);
}
- } else if (ISD::isZEXTLoad(N)) {
+ } else if (ISD::isZEXTLoad(N) || ISD::isEXTLoad(N)) {
+ //} else if (ISD::isZEXTLoad(N)) {
// ZeroExtendedLoad -- For all ExtdBytes use constant 0
SDValue ConstZero = DAG.getConstant(0, MVT::i8);
for (iter=MemBytes; iter<ExtdBytes; ++iter) {
@@ -1557,8 +1581,8 @@ static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) {
case ISD::SETLT: return PIC16CC::LT;
case ISD::SETLE: return PIC16CC::LE;
case ISD::SETULT: return PIC16CC::ULT;
- case ISD::SETULE: return PIC16CC::LE;
- case ISD::SETUGE: return PIC16CC::GE;
+ case ISD::SETULE: return PIC16CC::ULE;
+ case ISD::SETUGE: return PIC16CC::UGE;
case ISD::SETUGT: return PIC16CC::UGT;
}
}
diff --git a/lib/Target/PIC16/PIC16InstrInfo.cpp b/lib/Target/PIC16/PIC16InstrInfo.cpp
index 2a769e8ad16e..8418423fa06a 100644
--- a/lib/Target/PIC16/PIC16InstrInfo.cpp
+++ b/lib/Target/PIC16/PIC16InstrInfo.cpp
@@ -184,3 +184,31 @@ bool PIC16InstrInfo::isMoveInstr(const MachineInstr &MI,
return false;
}
+/// InsertBranch - Insert a branch into the end of the specified
+/// MachineBasicBlock. This operands to this method are the same as those
+/// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch
+/// returns success and when an unconditional branch (TBB is non-null, FBB is
+/// null, Cond is empty) needs to be inserted. It returns the number of
+/// instructions inserted.
+unsigned PIC16InstrInfo::
+InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ const SmallVectorImpl<MachineOperand> &Cond) const {
+ // Shouldn't be a fall through.
+ assert(TBB && "InsertBranch must not be told to insert a fallthrough");
+
+ if (FBB == 0) { // One way branch.
+ if (Cond.empty()) {
+ // Unconditional branch?
+ DebugLoc dl = DebugLoc::getUnknownLoc();
+ BuildMI(&MBB, dl, get(PIC16::br_uncond)).addMBB(TBB);
+ }
+ return 1;
+ }
+
+ // FIXME: If the there are some conditions specified then conditional branch
+ // should be generated.
+ // For the time being no instruction is being generated therefore
+ // returning NULL.
+ return 0;
+}
diff --git a/lib/Target/PIC16/PIC16InstrInfo.h b/lib/Target/PIC16/PIC16InstrInfo.h
index 0b6767969875..85c098428c98 100644
--- a/lib/Target/PIC16/PIC16InstrInfo.h
+++ b/lib/Target/PIC16/PIC16InstrInfo.h
@@ -64,6 +64,11 @@ public:
unsigned &SrcReg, unsigned &DstReg,
unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+ virtual
+ unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ const SmallVectorImpl<MachineOperand> &Cond) const;
+
};
} // namespace llvm
diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td
index c572188cef22..75577163c87f 100644
--- a/lib/Target/PIC16/PIC16InstrInfo.td
+++ b/lib/Target/PIC16/PIC16InstrInfo.td
@@ -189,22 +189,22 @@ def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
// Move a Lo(TGA) to W.
def movlw_lo_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
- "movlw LOW(${src}) + ${src2}",
+ "movlw LOW(${src} + ${src2})",
[(set GPR:$dst, (PIC16Lo tglobaladdr:$src, imm:$src2 ))]>;
// Move a Lo(TES) to W.
def movlw_lo_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
- "movlw LOW(${src}) + ${src2}",
+ "movlw LOW(${src} + ${src2})",
[(set GPR:$dst, (PIC16Lo texternalsym:$src, imm:$src2 ))]>;
// Move a Hi(TGA) to W.
def movlw_hi_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
- "movlw HIGH(${src}) + ${src2}",
+ "movlw HIGH(${src} + ${src2})",
[(set GPR:$dst, (PIC16Hi tglobaladdr:$src, imm:$src2))]>;
// Move a Hi(TES) to W.
def movlw_hi_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
- "movlw HIGH(${src}) + ${src2}",
+ "movlw HIGH(${src} + ${src2})",
[(set GPR:$dst, (PIC16Hi texternalsym:$src, imm:$src2))]>;
}
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index bd1fea71a6d0..b003efddd499 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -113,10 +113,6 @@ namespace {
/// SelectionDAG operations.
///
class VISIBILITY_HIDDEN X86DAGToDAGISel : public SelectionDAGISel {
- /// TM - Keep a reference to X86TargetMachine.
- ///
- X86TargetMachine &TM;
-
/// X86Lowering - This object fully describes how to lower LLVM code to an
/// X86-specific SelectionDAG.
X86TargetLowering &X86Lowering;
@@ -136,8 +132,8 @@ namespace {
public:
explicit X86DAGToDAGISel(X86TargetMachine &tm, CodeGenOpt::Level OptLevel)
: SelectionDAGISel(tm, OptLevel),
- TM(tm), X86Lowering(*TM.getTargetLowering()),
- Subtarget(&TM.getSubtarget<X86Subtarget>()),
+ X86Lowering(*tm.getTargetLowering()),
+ Subtarget(&tm.getSubtarget<X86Subtarget>()),
OptForSize(false) {}
virtual const char *getPassName() const {
@@ -243,6 +239,18 @@ namespace {
///
SDNode *getGlobalBaseReg();
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const X86TargetMachine &getTargetMachine() {
+ return static_cast<const X86TargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const X86InstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
#ifndef NDEBUG
unsigned Indent;
#endif
@@ -674,6 +682,8 @@ bool X86DAGToDAGISel::MatchLoad(SDValue N, X86ISelAddressMode &AM) {
}
bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
+ bool SymbolicAddressesAreRIPRel =
+ getTargetMachine().symbolicAddressesAreRIPRel();
bool is64Bit = Subtarget->is64Bit();
DOUT << "Wrapper: 64bit " << is64Bit;
DOUT << " AM "; DEBUG(AM.dump()); DOUT << "\n";
@@ -684,7 +694,7 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
// Base and index reg must be 0 in order to use rip as base.
bool canUsePICRel = !AM.Base.Reg.getNode() && !AM.IndexReg.getNode();
- if (is64Bit && !canUsePICRel && TM.symbolicAddressesAreRIPRel())
+ if (is64Bit && !canUsePICRel && SymbolicAddressesAreRIPRel)
return true;
if (AM.hasSymbolicDisplacement())
@@ -698,7 +708,7 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
uint64_t Offset = G->getOffset();
if (!is64Bit || isInt32(AM.Disp + Offset)) {
GlobalValue *GV = G->getGlobal();
- bool isRIPRel = TM.symbolicAddressesAreRIPRel();
+ bool isRIPRel = SymbolicAddressesAreRIPRel;
if (N0.getOpcode() == llvm::ISD::TargetGlobalTLSAddress) {
TLSModel::Model model =
getTLSModel (GV, TM.getRelocationModel());
@@ -716,16 +726,16 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
AM.CP = CP->getConstVal();
AM.Align = CP->getAlignment();
AM.Disp += Offset;
- AM.isRIPRel = TM.symbolicAddressesAreRIPRel();
+ AM.isRIPRel = SymbolicAddressesAreRIPRel;
return false;
}
} else if (ExternalSymbolSDNode *S =dyn_cast<ExternalSymbolSDNode>(N0)) {
AM.ES = S->getSymbol();
- AM.isRIPRel = TM.symbolicAddressesAreRIPRel();
+ AM.isRIPRel = SymbolicAddressesAreRIPRel;
return false;
} else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
AM.JT = J->getIndex();
- AM.isRIPRel = TM.symbolicAddressesAreRIPRel();
+ AM.isRIPRel = SymbolicAddressesAreRIPRel;
return false;
}
@@ -1300,7 +1310,7 @@ bool X86DAGToDAGISel::TryFoldLoad(SDValue P, SDValue N,
///
SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
MachineFunction *MF = CurBB->getParent();
- unsigned GlobalBaseReg = TM.getInstrInfo()->getGlobalBaseReg(MF);
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 882ee3a01f1e..1f507c3e0fd7 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -15,7 +15,6 @@
#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86ISelLowering.h"
-#include "X86MachineFunctionInfo.h"
#include "X86TargetMachine.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
@@ -25,14 +24,12 @@
#include "llvm/Intrinsics.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/VectorExtras.h"
-#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetOptions.h"
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index ca7aa7bd30db..af61eae16f80 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -465,17 +465,6 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
// Compute the final addrec to expand into code.
SCEVHandle AR = IU->getReplacementExpr(*UI);
- // FIXME: It is an extremely bad idea to indvar substitute anything more
- // complex than affine induction variables. Doing so will put expensive
- // polynomial evaluations inside of the loop, and the str reduction pass
- // currently can only reduce affine polynomials. For now just disable
- // indvar subst on anything more complex than an affine addrec, unless
- // it can be expanded to a trivial value.
- if (!Stride->isLoopInvariant(L) &&
- !isa<SCEVConstant>(AR) &&
- L->contains(User->getParent()))
- continue;
-
Value *NewVal = 0;
if (AR->isLoopInvariant(L)) {
BasicBlock::iterator I = Rewriter.getInsertionPoint();
@@ -487,6 +476,15 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
Rewriter.setInsertionPoint(I);
++NumReplaced;
} else {
+ // FIXME: It is an extremely bad idea to indvar substitute anything more
+ // complex than affine induction variables. Doing so will put expensive
+ // polynomial evaluations inside of the loop, and the str reduction pass
+ // currently can only reduce affine polynomials. For now just disable
+ // indvar subst on anything more complex than an affine addrec, unless
+ // it can be expanded to a trivial value.
+ if (!Stride->isLoopInvariant(L))
+ continue;
+
const Type *IVTy = Offset->getType();
const Type *UseTy = Op->getType();
@@ -520,7 +518,7 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
// induction variable, still in the canonical induction variable's
// type, so that all expanded arithmetic is done in the same type.
SCEVHandle NewAR = SE->getAddRecExpr(SE->getIntegerSCEV(0, LargestType),
- PromotedStride, L);
+ PromotedStride, L);
// Add the PromotedOffset as a separate step, because it may not be
// loop-invariant.
NewAR = SE->getAddExpr(NewAR, PromotedOffset);
diff --git a/test/Transforms/IndVarSimplify/variable-stride-ivs.ll b/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
index 759ba8e177bc..759ba8e177bc 100644
--- a/test/Transforms/IndVarSimplify/variable-stride-ivs.ll
+++ b/test/Transforms/IndVarSimplify/variable-stride-ivs-0.ll
diff --git a/test/Transforms/IndVarSimplify/variable-stride-ivs-1.ll b/test/Transforms/IndVarSimplify/variable-stride-ivs-1.ll
new file mode 100644
index 000000000000..075e899cd96d
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/variable-stride-ivs-1.ll
@@ -0,0 +1,43 @@
+; RUN: llvm-as < %s | opt -indvars
+; PR4315
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "x86_64-undermydesk-freebsd8.0"
+ %struct.mbuf = type <{ %struct.mbuf*, i8*, i32, i8, i8, i8, i8 }>
+
+define i32 @crash(%struct.mbuf* %m) nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %if.end, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %if.end ] ; <i32> [#uses=3]
+ %chksum.0 = phi i8 [ 0, %entry ], [ %conv3, %if.end ] ; <i8> [#uses=3]
+ %cmp = icmp slt i32 %i.0, 1 ; <i1> [#uses=1]
+ br i1 %cmp, label %for.body, label %do.body
+
+for.body: ; preds = %for.cond
+ br i1 undef, label %if.end, label %do.body
+
+if.end: ; preds = %for.body
+ %i.02 = trunc i32 %i.0 to i8 ; <i8> [#uses=1]
+ %conv3 = add i8 %chksum.0, %i.02 ; <i8> [#uses=1]
+ %inc = add i32 %i.0, 1 ; <i32> [#uses=1]
+ br label %for.cond
+
+do.body: ; preds = %do.cond, %for.body, %for.cond
+ %chksum.2 = phi i8 [ undef, %do.cond ], [ %chksum.0, %for.body ], [ %chksum.0, %for.cond ] ; <i8> [#uses=1]
+ br i1 undef, label %do.cond, label %bb.nph
+
+bb.nph: ; preds = %do.body
+ br label %while.body
+
+while.body: ; preds = %while.body, %bb.nph
+ %chksum.13 = phi i8 [ undef, %while.body ], [ %chksum.2, %bb.nph ] ; <i8> [#uses=0]
+ br i1 undef, label %do.cond, label %while.body
+
+do.cond: ; preds = %while.body, %do.body
+ br i1 false, label %do.end, label %do.body
+
+do.end: ; preds = %do.cond
+ ret i32 0
+}
diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt
index 29287ab82bdc..2cfd6bb22a0f 100644
--- a/tools/llvm-config/CMakeLists.txt
+++ b/tools/llvm-config/CMakeLists.txt
@@ -87,7 +87,6 @@ add_custom_command(OUTPUT ${FINAL_LIBDEPS}
DEPENDS ${LIBDEPS}
COMMENT "Checking for cyclic dependencies between LLVM libraries.")
-string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
set(C_FLGS "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(CXX_FLGS "${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(CPP_FLGS "${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
diff --git a/tools/llvm-ld/Optimize.cpp b/tools/llvm-ld/Optimize.cpp
index f788f060d157..a4ca95199a1c 100644
--- a/tools/llvm-ld/Optimize.cpp
+++ b/tools/llvm-ld/Optimize.cpp
@@ -17,6 +17,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/StandardPasses.h"
#include "llvm/System/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
@@ -91,71 +92,9 @@ void Optimize(Module* M) {
// Add an appropriate TargetData instance for this module...
addPass(Passes, new TargetData(M));
- if (!DisableOptimizations) {
- // Now that composite has been compiled, scan through the module, looking
- // for a main function. If main is defined, mark all other functions
- // internal.
- if (!DisableInternalize)
- addPass(Passes, createInternalizePass(true));
-
- // Propagate constants at call sites into the functions they call. This
- // opens opportunities for globalopt (and inlining) by substituting function
- // pointers passed as arguments to direct uses of functions.
- addPass(Passes, createIPSCCPPass());
-
- // Now that we internalized some globals, see if we can hack on them!
- addPass(Passes, createGlobalOptimizerPass());
-
- // Linking modules together can lead to duplicated global constants, only
- // keep one copy of each constant...
- addPass(Passes, createConstantMergePass());
-
- // Remove unused arguments from functions...
- addPass(Passes, createDeadArgEliminationPass());
-
- // Reduce the code after globalopt and ipsccp. Both can open up significant
- // simplification opportunities, and both can propagate functions through
- // function pointers. When this happens, we often have to resolve varargs
- // calls, etc, so let instcombine do this.
- addPass(Passes, createInstructionCombiningPass());
-
- if (!DisableInline)
- addPass(Passes, createFunctionInliningPass()); // Inline small functions
-
- addPass(Passes, createPruneEHPass()); // Remove dead EH info
- addPass(Passes, createGlobalOptimizerPass()); // Optimize globals again.
- addPass(Passes, createGlobalDCEPass()); // Remove dead functions
-
- // If we didn't decide to inline a function, check to see if we can
- // transform it to pass arguments by value instead of by reference.
- addPass(Passes, createArgumentPromotionPass());
-
- // The IPO passes may leave cruft around. Clean up after them.
- addPass(Passes, createInstructionCombiningPass());
- addPass(Passes, createJumpThreadingPass()); // Thread jumps.
- addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas
-
- // Run a few AA driven optimizations here and now, to cleanup the code.
- addPass(Passes, createFunctionAttrsPass()); // Add nocapture
- addPass(Passes, createGlobalsModRefPass()); // IP alias analysis
-
- addPass(Passes, createLICMPass()); // Hoist loop invariants
- addPass(Passes, createGVNPass()); // Remove redundancies
- addPass(Passes, createMemCpyOptPass()); // Remove dead memcpy's
- addPass(Passes, createDeadStoreEliminationPass()); // Nuke dead stores
-
- // Cleanup and simplify the code after the scalar optimizations.
- addPass(Passes, createInstructionCombiningPass());
-
- addPass(Passes, createJumpThreadingPass()); // Thread jumps.
- addPass(Passes, createPromoteMemoryToRegisterPass()); // Cleanup jumpthread.
-
- // Delete basic blocks, which optimization passes may have killed...
- addPass(Passes, createCFGSimplificationPass());
-
- // Now that we have optimized the program, discard unreachable functions...
- addPass(Passes, createGlobalDCEPass());
- }
+ if (!DisableOptimizations)
+ createStandardLTOPasses(&Passes, !DisableInternalize, !DisableInline,
+ /*RunSecondGlobalOpt=*/true, VerifyEach);
// If the -s or -S command line options were specified, strip the symbols out
// of the resulting program to make it smaller. -s and -S are GNU ld options
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index d3a3f7f7b826..03a11b687daa 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -24,9 +24,10 @@
#include "llvm/ModuleProvider.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/StandardPasses.h"
+#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
#include "llvm/Analysis/Passes.h"
@@ -389,59 +390,9 @@ bool LTOCodeGenerator::generateAssemblyCode(raw_ostream& out,
// Add an appropriate TargetData instance for this module...
passes.add(new TargetData(*_target->getTargetData()));
- // Propagate constants at call sites into the functions they call. This
- // opens opportunities for globalopt (and inlining) by substituting function
- // pointers passed as arguments to direct uses of functions.
- passes.add(createIPSCCPPass());
-
- // Now that we internalized some globals, see if we can hack on them!
- passes.add(createGlobalOptimizerPass());
-
- // Linking modules together can lead to duplicated global constants, only
- // keep one copy of each constant...
- passes.add(createConstantMergePass());
-
- // Remove unused arguments from functions...
- passes.add(createDeadArgEliminationPass());
-
- // Reduce the code after globalopt and ipsccp. Both can open up significant
- // simplification opportunities, and both can propagate functions through
- // function pointers. When this happens, we often have to resolve varargs
- // calls, etc, so let instcombine do this.
- passes.add(createInstructionCombiningPass());
- if (!DisableInline)
- passes.add(createFunctionInliningPass()); // Inline small functions
- passes.add(createPruneEHPass()); // Remove dead EH info
- passes.add(createGlobalDCEPass()); // Remove dead functions
-
- // If we didn't decide to inline a function, check to see if we can
- // transform it to pass arguments by value instead of by reference.
- passes.add(createArgumentPromotionPass());
-
- // The IPO passes may leave cruft around. Clean up after them.
- passes.add(createInstructionCombiningPass());
- passes.add(createJumpThreadingPass()); // Thread jumps.
- passes.add(createScalarReplAggregatesPass()); // Break up allocas
-
- // Run a few AA driven optimizations here and now, to cleanup the code.
- passes.add(createFunctionAttrsPass()); // Add nocapture
- passes.add(createGlobalsModRefPass()); // IP alias analysis
- passes.add(createLICMPass()); // Hoist loop invariants
- passes.add(createGVNPass()); // Remove common subexprs
- passes.add(createMemCpyOptPass()); // Remove dead memcpy's
- passes.add(createDeadStoreEliminationPass()); // Nuke dead stores
-
- // Cleanup and simplify the code after the scalar optimizations.
- passes.add(createInstructionCombiningPass());
- passes.add(createJumpThreadingPass()); // Thread jumps.
- passes.add(createPromoteMemoryToRegisterPass()); // Cleanup after threading.
-
-
- // Delete basic blocks, which optimization passes may have killed...
- passes.add(createCFGSimplificationPass());
-
- // Now that we have optimized the program, discard unreachable functions...
- passes.add(createGlobalDCEPass());
+ createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline,
+ /*RunSecondGlobalOpt=*/ false,
+ /*VerifyEach=*/ false);
// Make sure everything is still good.
passes.add(createVerifierPass());
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 680353ad2352..0c36e21fa58b 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -28,6 +28,7 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PluginLoader.h"
+#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/raw_ostream.h"
@@ -266,79 +267,16 @@ inline void addPass(PassManager &PM, Pass *P) {
/// OptLevel - Optimization Level
void AddOptimizationPasses(PassManager &MPM, FunctionPassManager &FPM,
unsigned OptLevel) {
-
- if (OptLevel == 0)
- return;
-
- FPM.add(createCFGSimplificationPass());
- if (OptLevel == 1)
- FPM.add(createPromoteMemoryToRegisterPass());
- else
- FPM.add(createScalarReplAggregatesPass());
- FPM.add(createInstructionCombiningPass());
-
- if (UnitAtATime)
- MPM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
- MPM.add(createCFGSimplificationPass()); // Clean up disgusting code
- MPM.add(createPromoteMemoryToRegisterPass()); // Kill useless allocas
- if (UnitAtATime) {
- MPM.add(createGlobalOptimizerPass()); // OptLevel out global vars
- MPM.add(createGlobalDCEPass()); // Remove unused fns and globs
- MPM.add(createIPConstantPropagationPass()); // IP Constant Propagation
- MPM.add(createDeadArgEliminationPass()); // Dead argument elimination
- }
- MPM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
- MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
- if (UnitAtATime) {
- MPM.add(createPruneEHPass()); // Remove dead EH info
- MPM.add(createFunctionAttrsPass()); // Deduce function attrs
- }
- if (OptLevel > 1)
- MPM.add(createFunctionInliningPass()); // Inline small functions
- if (OptLevel > 2)
- MPM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args
- if (!DisableSimplifyLibCalls)
- MPM.add(createSimplifyLibCallsPass()); // Library Call Optimizations
- MPM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
- MPM.add(createJumpThreadingPass()); // Thread jumps.
- MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
- MPM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas
- MPM.add(createInstructionCombiningPass()); // Combine silly seq's
- MPM.add(createCondPropagationPass()); // Propagate conditionals
- MPM.add(createTailCallEliminationPass()); // Eliminate tail calls
- MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
- MPM.add(createReassociatePass()); // Reassociate expressions
- MPM.add(createLoopRotatePass()); // Rotate Loop
- MPM.add(createLICMPass()); // Hoist loop invariants
- MPM.add(createLoopUnswitchPass());
- MPM.add(createLoopIndexSplitPass()); // Split loop index
- MPM.add(createInstructionCombiningPass());
- MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
- MPM.add(createLoopDeletionPass()); // Delete dead loops
- if (OptLevel > 1)
- MPM.add(createLoopUnrollPass()); // Unroll small loops
- MPM.add(createInstructionCombiningPass()); // Clean up after the unroller
- MPM.add(createGVNPass()); // Remove redundancies
- MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset
- MPM.add(createSCCPPass()); // Constant prop with SCCP
-
- // Run instcombine after redundancy elimination to exploit opportunities
- // opened up by them.
- MPM.add(createInstructionCombiningPass());
- MPM.add(createCondPropagationPass()); // Propagate conditionals
- MPM.add(createDeadStoreEliminationPass()); // Delete dead stores
- MPM.add(createAggressiveDCEPass()); // Delete dead instructions
- MPM.add(createCFGSimplificationPass()); // Merge & remove BBs
-
- if (UnitAtATime) {
- MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
- MPM.add(createDeadTypeEliminationPass()); // Eliminate dead types
- }
-
- if (OptLevel > 1 && UnitAtATime)
- MPM.add(createConstantMergePass()); // Merge dup global constants
-
- return;
+ createStandardFunctionPasses(&FPM, OptLevel);
+
+ llvm::Pass *InliningPass = OptLevel > 1 ? createFunctionInliningPass() : 0;
+ createStandardModulePasses(&MPM, OptLevel,
+ /*OptimizeSize=*/ false,
+ UnitAtATime,
+ /*UnrollLoops=*/ OptLevel > 1,
+ !DisableSimplifyLibCalls,
+ /*HaveExceptions=*/ true,
+ InliningPass);
}
void AddStandardCompilePasses(PassManager &PM) {
@@ -352,59 +290,16 @@ void AddStandardCompilePasses(PassManager &PM) {
if (DisableOptimizations) return;
- addPass(PM, createRaiseAllocationsPass()); // call %malloc -> malloc inst
- addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code
- addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas
- addPass(PM, createGlobalOptimizerPass()); // Optimize out global vars
- addPass(PM, createGlobalDCEPass()); // Remove unused fns and globs
- addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation
- addPass(PM, createDeadArgEliminationPass()); // Dead argument elimination
- addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE
- addPass(PM, createCFGSimplificationPass()); // Clean up after IPCP & DAE
-
- addPass(PM, createPruneEHPass()); // Remove dead EH info
- addPass(PM, createFunctionAttrsPass()); // Deduce function attrs
-
- if (!DisableInline)
- addPass(PM, createFunctionInliningPass()); // Inline small functions
- addPass(PM, createArgumentPromotionPass()); // Scalarize uninlined fn args
-
- addPass(PM, createSimplifyLibCallsPass()); // Library Call Optimizations
- addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl.
- addPass(PM, createJumpThreadingPass()); // Thread jumps.
- addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
- addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
- addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
- addPass(PM, createCondPropagationPass()); // Propagate conditionals
-
- addPass(PM, createTailCallEliminationPass()); // Eliminate tail calls
- addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
- addPass(PM, createReassociatePass()); // Reassociate expressions
- addPass(PM, createLoopRotatePass());
- addPass(PM, createLICMPass()); // Hoist loop invariants
- addPass(PM, createLoopUnswitchPass()); // Unswitch loops.
- addPass(PM, createLoopIndexSplitPass()); // Index split loops.
- // FIXME : Removing instcombine causes nestedloop regression.
- addPass(PM, createInstructionCombiningPass());
- addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars
- addPass(PM, createLoopDeletionPass()); // Delete dead loops
- addPass(PM, createLoopUnrollPass()); // Unroll small loops
- addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller
- addPass(PM, createGVNPass()); // Remove redundancies
- addPass(PM, createMemCpyOptPass()); // Remove memcpy / form memset
- addPass(PM, createSCCPPass()); // Constant prop with SCCP
-
- // Run instcombine after redundancy elimination to exploit opportunities
- // opened up by them.
- addPass(PM, createInstructionCombiningPass());
- addPass(PM, createCondPropagationPass()); // Propagate conditionals
-
- addPass(PM, createDeadStoreEliminationPass()); // Delete dead stores
- addPass(PM, createAggressiveDCEPass()); // Delete dead instructions
- addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
- addPass(PM, createStripDeadPrototypesPass()); // Get rid of dead prototypes
- addPass(PM, createDeadTypeEliminationPass()); // Eliminate dead types
- addPass(PM, createConstantMergePass()); // Merge dup global constants
+ llvm::Pass *InliningPass = !DisableInline ? createFunctionInliningPass() : 0;
+
+ // -std-compile-opts adds the same module passes as -O3.
+ createStandardModulePasses(&PM, 3,
+ /*OptimizeSize=*/ false,
+ /*UnitAtATime=*/ true,
+ /*UnrollLoops=*/ true,
+ /*SimplifyLibCalls=*/ true,
+ /*HaveExceptions=*/ true,
+ InliningPass);
}
} // anonymous namespace