summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-03 13:28:00 +0000
committered <ed@FreeBSD.org>2009-06-03 13:28:00 +0000
commit036fdcfb2d357cecb320b5a6fd05f4859a63aeba (patch)
tree90502b3518861e1704738c228456f7079013368b
parent3277b69d734b9c90b44ebde4ede005717e2c3b2e (diff)
downloadFreeBSD-src-036fdcfb2d357cecb320b5a6fd05f4859a63aeba.zip
FreeBSD-src-036fdcfb2d357cecb320b5a6fd05f4859a63aeba.tar.gz
Import LLVM, at r72770.
This should fix LLVM PR4225.
-rw-r--r--docs/LangRef.html14
-rw-r--r--include/llvm/ADT/ilist.h8
-rw-r--r--include/llvm/Analysis/ConstantFolding.h2
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h1
-rw-r--r--include/llvm/Support/TargetFolder.h12
-rw-r--r--lib/Analysis/ConstantFolding.cpp2
-rw-r--r--lib/CodeGen/LiveVariables.cpp14
-rw-r--r--lib/CodeGen/MachO.h423
-rw-r--r--lib/CodeGen/MachOCodeEmitter.cpp207
-rw-r--r--lib/CodeGen/MachOCodeEmitter.h129
-rw-r--r--lib/CodeGen/MachOWriter.cpp509
-rw-r--r--lib/CodeGen/MachOWriter.h404
-rw-r--r--lib/CodeGen/RegAllocLinearScan.cpp91
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp24
-rw-r--r--lib/System/Atomic.cpp2
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp4
-rw-r--r--lib/Target/X86/X86FastISel.cpp2
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp5
-rw-r--r--test/Archive/GNU.abin0 -> 4210 bytes
-rw-r--r--test/Archive/IsNAN.obin0 -> 2280 bytes
-rw-r--r--test/Archive/MacOSX.abin0 -> 4176 bytes
-rw-r--r--test/Archive/SVR4.abin0 -> 4214 bytes
-rw-r--r--test/Archive/xpg4.abin0 -> 4214 bytes
-rw-r--r--test/CodeGen/ARM/str_pre-2.ll13
-rw-r--r--test/CodeGen/X86/2009-06-02-RewriterBug.ll362
-rw-r--r--test/CodeGen/X86/codegen-prepare-cast.ll24
-rw-r--r--test/CodeGen/X86/x86-store-gv-addr.ll10
-rwxr-xr-xutils/NewNightlyTest.pl43
28 files changed, 1361 insertions, 944 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 32441cc..f0a171be 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -2403,9 +2403,10 @@ cleanup is performed in the case of either a <tt>longjmp</tt> or a thrown
exception. Additionally, this is important for implementation of
'<tt>catch</tt>' clauses in high-level languages that support them.</p>
-<p>It is not valid to reference the return value of an invoke call from
-anywhere not dominated by the normal label, since an unwind does not
-provide a return value.</p>
+<p>For the purposes of the SSA form, the definition of the value
+returned by the '<tt>invoke</tt>' instruction is deemed to occur on
+the edge from the current block to the "normal" label. If the callee
+unwinds then no return value is available.</p>
<h5>Example:</h5>
<pre>
@@ -4518,6 +4519,11 @@ may be used as the label arguments.</p>
block and the PHI instructions: i.e. PHI instructions must be first in
a basic block.</p>
+<p>For the purposes of the SSA form, the use of each incoming value is
+deemed to occur on the edge from the corresponding predecessor block
+to the current block (but after any definition of an '<tt>invoke</tt>'
+instruction's return value on the same edge).</p>
+
<h5>Semantics:</h5>
<p>At runtime, the '<tt>phi</tt>' instruction logically takes on the value
@@ -7104,7 +7110,7 @@ declare void @llvm.stackprotector( i8* &lt;guard&gt;, i8** &lt;slot&gt; )
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2009-05-30 18:08:30 +0200 (Sat, 30 May 2009) $
+ Last modified: $Date: 2009-06-03 12:20:10 +0200 (Wed, 03 Jun 2009) $
</address>
</body>
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
index 9eb7005..b95e3e0 100644
--- a/include/llvm/ADT/ilist.h
+++ b/include/llvm/ADT/ilist.h
@@ -481,8 +481,8 @@ private:
L2.setTail(0);
// Remove [first, last) from its old position.
- NodeTy *First = &*first, *Prev = getPrev(First);
- NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
+ NodeTy *First = &*first, *Prev = this->getPrev(First);
+ NodeTy *Next = last.getNodePtrUnchecked(), *Last = this->getPrev(Next);
if (Prev)
this->setNext(Prev, Next);
else
@@ -491,7 +491,7 @@ private:
// Splice [first, last) into its new position.
NodeTy *PosNext = position.getNodePtrUnchecked();
- NodeTy *PosPrev = getPrev(PosNext);
+ NodeTy *PosPrev = this->getPrev(PosNext);
// Fix head of list...
if (PosPrev)
@@ -504,7 +504,7 @@ private:
this->setNext(Last, PosNext);
this->setPrev(PosNext, Last);
- transferNodesFromList(L2, First, PosNext);
+ this->transferNodesFromList(L2, First, PosNext);
// Now that everything is set, restore the pointers to the list sentinels.
L2.setTail(L2Sentinel);
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index bf360f7..5fdf6d2 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -34,7 +34,7 @@ Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0);
/// using the specified TargetData. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(ConstantExpr *CE,
- const TargetData *TD);
+ const TargetData *TD = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified operands. If successful, the constant result is returned, if not,
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 264447e..1978055 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -19,7 +19,6 @@
namespace llvm {
class ConstantInt;
class ConstantRange;
- class APInt;
class DominatorTree;
enum SCEVTypes {
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index 14f2c9b..172e4fe 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -9,8 +9,10 @@
//
// This file defines the TargetFolder class, a helper for IRBuilder.
// It provides IRBuilder with a set of methods for creating constants with
-// target dependent folding. For general constant creation and folding,
-// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
+// target dependent folding, in addition to the same target-independent
+// folding that the ConstantFolder class provides. For general constant
+// creation and folding, use ConstantExpr and the routines in
+// llvm/Analysis/ConstantFolding.h.
//
//===----------------------------------------------------------------------===//
@@ -26,18 +28,18 @@ class TargetData;
/// TargetFolder - Create constants with target dependent folding.
class TargetFolder {
- const TargetData &TD;
+ const TargetData *TD;
/// Fold - Fold the constant using target specific information.
Constant *Fold(Constant *C) const {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
- if (Constant *CF = ConstantFoldConstantExpression(CE, &TD))
+ if (Constant *CF = ConstantFoldConstantExpression(CE, TD))
return CF;
return C;
}
public:
- TargetFolder(const TargetData &TheTD) : TD(TheTD) {}
+ explicit TargetFolder(const TargetData *TheTD) : TD(TheTD) {}
//===--------------------------------------------------------------------===//
// Binary Operators
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index e5ab322..261c635 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -317,8 +317,6 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
/// result is returned, if not, null is returned.
Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
const TargetData *TD) {
- assert(TD && "ConstantFoldConstantExpression requires a valid TargetData.");
-
SmallVector<Constant*, 8> Ops;
for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
Ops.push_back(cast<Constant>(*i));
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index c33d81e..6228821 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -242,20 +242,6 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
}
}
- // There was an earlier def of a super-register. Add implicit def to that MI.
- //
- // A: EAX = ...
- // B: ... = AX
- //
- // Add implicit def to A if there isn't a use of AX (or EAX) before B.
- if (!PhysRegUse[Reg]) {
- MachineInstr *Def = PhysRegDef[Reg];
- if (Def && !Def->modifiesRegister(Reg))
- Def->addOperand(MachineOperand::CreateReg(Reg,
- true /*IsDef*/,
- true /*IsImp*/));
- }
-
// Remember this use.
PhysRegUse[Reg] = MI;
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
diff --git a/lib/CodeGen/MachO.h b/lib/CodeGen/MachO.h
new file mode 100644
index 0000000..bd9bd61
--- /dev/null
+++ b/lib/CodeGen/MachO.h
@@ -0,0 +1,423 @@
+//=== MachO.h - Mach-O structures and constants -----------------*- 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 MachO .
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MACHO_H
+#define MACHO_H
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/CodeGen/MachineRelocation.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+typedef std::vector<unsigned char> DataBuffer;
+
+/// MachOSym - This struct contains information about each symbol that is
+/// added to logical symbol table for the module. This is eventually
+/// turned into a real symbol table in the file.
+struct MachOSym {
+ const GlobalValue *GV; // The global value this corresponds to.
+ std::string GVName; // The mangled name of the global value.
+ uint32_t n_strx; // index into the string table
+ uint8_t n_type; // type flag
+ uint8_t n_sect; // section number or NO_SECT
+ int16_t n_desc; // see <mach-o/stab.h>
+ uint64_t n_value; // value for this symbol (or stab offset)
+
+ // Constants for the n_sect field
+ // see <mach-o/nlist.h>
+ enum { NO_SECT = 0 }; // symbol is not in any section
+
+ // Constants for the n_type field
+ // see <mach-o/nlist.h>
+ enum { N_UNDF = 0x0, // undefined, n_sect == NO_SECT
+ N_ABS = 0x2, // absolute, n_sect == NO_SECT
+ N_SECT = 0xe, // defined in section number n_sect
+ N_PBUD = 0xc, // prebound undefined (defined in a dylib)
+ N_INDR = 0xa // indirect
+ };
+ // The following bits are OR'd into the types above. For example, a type
+ // of 0x0f would be an external N_SECT symbol (0x0e | 0x01).
+ enum { N_EXT = 0x01, // external symbol bit
+ N_PEXT = 0x10 // private external symbol bit
+ };
+
+ // Constants for the n_desc field
+ // see <mach-o/loader.h>
+ enum { REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
+ REFERENCE_FLAG_UNDEFINED_LAZY = 1,
+ REFERENCE_FLAG_DEFINED = 2,
+ REFERENCE_FLAG_PRIVATE_DEFINED = 3,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
+ REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5
+ };
+ enum { N_NO_DEAD_STRIP = 0x0020, // symbol is not to be dead stripped
+ N_WEAK_REF = 0x0040, // symbol is weak referenced
+ N_WEAK_DEF = 0x0080 // coalesced symbol is a weak definition
+ };
+
+ MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
+ const TargetAsmInfo *TAI);
+
+ struct SymCmp {
+ // FIXME: this does not appear to be sorting 'f' after 'F'
+ bool operator()(const MachOSym &LHS, const MachOSym &RHS) {
+ return LHS.GVName < RHS.GVName;
+ }
+ };
+
+
+ /// PartitionByLocal - Simple boolean predicate that returns true if Sym is
+ /// a local symbol rather than an external symbol.
+
+ static inline bool PartitionByLocal(const MachOSym &Sym) {
+ return (Sym.n_type & (MachOSym::N_EXT | MachOSym::N_PEXT)) == 0;
+ }
+
+ /// PartitionByDefined - Simple boolean predicate that returns true if Sym is
+ /// defined in this module.
+
+ static inline bool PartitionByDefined(const MachOSym &Sym) {
+ // FIXME: Do N_ABS or N_INDR count as defined?
+ return (Sym.n_type & MachOSym::N_SECT) == MachOSym::N_SECT;
+ }
+
+}; // end struct MachOSym
+
+/// MachOHeader - This struct contains the header information about a
+/// specific architecture type/subtype pair that is emitted to the file.
+
+struct MachOHeader {
+ uint32_t magic; // mach magic number identifier
+ uint32_t filetype; // type of file
+ uint32_t ncmds; // number of load commands
+ uint32_t sizeofcmds; // the size of all the load commands
+ uint32_t flags; // flags
+ uint32_t reserved; // 64-bit only
+
+ /// HeaderData - The actual data for the header which we are building
+ /// up for emission to the file.
+ DataBuffer HeaderData;
+
+ // Constants for the filetype field
+ // see <mach-o/loader.h> for additional info on the various types
+ enum { MH_OBJECT = 1, // relocatable object file
+ MH_EXECUTE = 2, // demand paged executable file
+ MH_FVMLIB = 3, // fixed VM shared library file
+ MH_CORE = 4, // core file
+ MH_PRELOAD = 5, // preloaded executable file
+ MH_DYLIB = 6, // dynamically bound shared library
+ MH_DYLINKER = 7, // dynamic link editor
+ MH_BUNDLE = 8, // dynamically bound bundle file
+ MH_DYLIB_STUB = 9, // shared library stub for static linking only
+ MH_DSYM = 10 // companion file wiht only debug sections
+ };
+
+ // Constants for the flags field
+ enum { MH_NOUNDEFS = 1 << 0,
+ // the object file has no undefined references
+ MH_INCRLINK = 1 << 1,
+ // the object file is the output of an incremental link against
+ // a base file and cannot be link edited again
+ MH_DYLDLINK = 1 << 2,
+ // the object file is input for the dynamic linker and cannot be
+ // statically link edited again.
+ MH_BINDATLOAD = 1 << 3,
+ // the object file's undefined references are bound by the
+ // dynamic linker when loaded.
+ MH_PREBOUND = 1 << 4,
+ // the file has its dynamic undefined references prebound
+ MH_SPLIT_SEGS = 1 << 5,
+ // the file has its read-only and read-write segments split
+ // see <mach/shared_memory_server.h>
+ MH_LAZY_INIT = 1 << 6,
+ // the shared library init routine is to be run lazily via
+ // catching memory faults to its writable segments (obsolete)
+ MH_TWOLEVEL = 1 << 7,
+ // the image is using two-level namespace bindings
+ MH_FORCE_FLAT = 1 << 8,
+ // the executable is forcing all images to use flat namespace
+ // bindings.
+ MH_NOMULTIDEFS = 1 << 8,
+ // this umbrella guarantees no multiple definitions of symbols
+ // in its sub-images so the two-level namespace hints can
+ // always be used.
+ MH_NOFIXPREBINDING = 1 << 10,
+ // do not have dyld notify the prebidning agent about this
+ // executable.
+ MH_PREBINDABLE = 1 << 11,
+ // the binary is not prebound but can have its prebinding
+ // redone. only used when MH_PREBOUND is not set.
+ MH_ALLMODSBOUND = 1 << 12,
+ // indicates that this binary binds to all two-level namespace
+ // modules of its dependent libraries. Only used when
+ // MH_PREBINDABLE and MH_TWOLEVEL are both set.
+ MH_SUBSECTIONS_VIA_SYMBOLS = 1 << 13,
+ // safe to divide up the sections into sub-sections via symbols
+ // for dead code stripping.
+ MH_CANONICAL = 1 << 14,
+ // the binary has been canonicalized via the unprebind operation
+ MH_WEAK_DEFINES = 1 << 15,
+ // the final linked image contains external weak symbols
+ MH_BINDS_TO_WEAK = 1 << 16,
+ // the final linked image uses weak symbols
+ MH_ALLOW_STACK_EXECUTION = 1 << 17
+ // When this bit is set, all stacks in the task will be given
+ // stack execution privilege. Only used in MH_EXECUTE filetype
+ };
+
+ MachOHeader() : magic(0), filetype(0), ncmds(0), sizeofcmds(0), flags(0),
+ reserved(0) { }
+
+ /// cmdSize - This routine returns the size of the MachOSection as written
+ /// to disk, depending on whether the destination is a 64 bit Mach-O file.
+ unsigned cmdSize(bool is64Bit) const {
+ if (is64Bit)
+ return 8 * sizeof(uint32_t);
+ else
+ return 7 * sizeof(uint32_t);
+ }
+
+ /// setMagic - This routine sets the appropriate value for the 'magic'
+ /// field based on pointer size and endianness.
+ void setMagic(bool isLittleEndian, bool is64Bit) {
+ if (isLittleEndian)
+ if (is64Bit) magic = 0xcffaedfe;
+ else magic = 0xcefaedfe;
+ else
+ if (is64Bit) magic = 0xfeedfacf;
+ else magic = 0xfeedface;
+ }
+
+}; // end struct MachOHeader
+
+/// MachOSegment - This struct contains the necessary information to
+/// emit the load commands for each section in the file.
+struct MachOSegment {
+ uint32_t cmd; // LC_SEGMENT or LC_SEGMENT_64
+ uint32_t cmdsize; // Total size of this struct and section commands
+ std::string segname; // segment name
+ uint64_t vmaddr; // address of this segment
+ uint64_t vmsize; // size of this segment, may be larger than filesize
+ uint64_t fileoff; // offset in file
+ uint64_t filesize; // amount to read from file
+ uint32_t maxprot; // maximum VM protection
+ uint32_t initprot; // initial VM protection
+ uint32_t nsects; // number of sections in this segment
+ uint32_t flags; // flags
+
+ // The following constants are getting pulled in by one of the
+ // system headers, which creates a neat clash with the enum.
+#if !defined(VM_PROT_NONE)
+#define VM_PROT_NONE 0x00
+#endif
+#if !defined(VM_PROT_READ)
+#define VM_PROT_READ 0x01
+#endif
+#if !defined(VM_PROT_WRITE)
+#define VM_PROT_WRITE 0x02
+#endif
+#if !defined(VM_PROT_EXECUTE)
+#define VM_PROT_EXECUTE 0x04
+#endif
+#if !defined(VM_PROT_ALL)
+#define VM_PROT_ALL 0x07
+#endif
+
+ // Constants for the vm protection fields
+ // see <mach-o/vm_prot.h>
+ enum { SEG_VM_PROT_NONE = VM_PROT_NONE,
+ SEG_VM_PROT_READ = VM_PROT_READ, // read permission
+ SEG_VM_PROT_WRITE = VM_PROT_WRITE, // write permission
+ SEG_VM_PROT_EXECUTE = VM_PROT_EXECUTE,
+ SEG_VM_PROT_ALL = VM_PROT_ALL
+ };
+
+ // Constants for the cmd field
+ // see <mach-o/loader.h>
+ enum { LC_SEGMENT = 0x01, // segment of this file to be mapped
+ LC_SEGMENT_64 = 0x19 // 64-bit segment of this file to be mapped
+ };
+
+ /// cmdSize - This routine returns the size of the MachOSection as written
+ /// to disk, depending on whether the destination is a 64 bit Mach-O file.
+ unsigned cmdSize(bool is64Bit) const {
+ if (is64Bit)
+ return 6 * sizeof(uint32_t) + 4 * sizeof(uint64_t) + 16;
+ else
+ return 10 * sizeof(uint32_t) + 16; // addresses only 32 bits
+ }
+
+ MachOSegment(const std::string &seg, bool is64Bit)
+ : cmd(is64Bit ? LC_SEGMENT_64 : LC_SEGMENT), cmdsize(0), segname(seg),
+ vmaddr(0), vmsize(0), fileoff(0), filesize(0), maxprot(VM_PROT_ALL),
+ initprot(VM_PROT_ALL), nsects(0), flags(0) { }
+};
+
+/// MachOSection - This struct contains information about each section in a
+/// particular segment that is emitted to the file. This is eventually
+/// turned into the SectionCommand in the load command for a particlar
+/// segment.
+
+struct MachOSection {
+ std::string sectname; // name of this section,
+ std::string segname; // segment this section goes in
+ uint64_t addr; // memory address of this section
+ uint64_t size; // size in bytes of this section
+ uint32_t offset; // file offset of this section
+ uint32_t align; // section alignment (power of 2)
+ uint32_t reloff; // file offset of relocation entries
+ uint32_t nreloc; // number of relocation entries
+ uint32_t flags; // flags (section type and attributes)
+ uint32_t reserved1; // reserved (for offset or index)
+ uint32_t reserved2; // reserved (for count or sizeof)
+ uint32_t reserved3; // reserved (64 bit only)
+
+ /// A unique number for this section, which will be used to match symbols
+ /// to the correct section.
+ uint32_t Index;
+
+ /// SectionData - The actual data for this section which we are building
+ /// up for emission to the file.
+ DataBuffer SectionData;
+
+ /// RelocBuffer - A buffer to hold the mach-o relocations before we write
+ /// them out at the appropriate location in the file.
+ DataBuffer RelocBuffer;
+
+ /// Relocations - The relocations that we have encountered so far in this
+ /// section that we will need to convert to MachORelocation entries when
+ /// the file is written.
+ std::vector<MachineRelocation> Relocations;
+
+ // Constants for the section types (low 8 bits of flags field)
+ // see <mach-o/loader.h>
+ enum { S_REGULAR = 0,
+ // regular section
+ S_ZEROFILL = 1,
+ // zero fill on demand section
+ S_CSTRING_LITERALS = 2,
+ // section with only literal C strings
+ S_4BYTE_LITERALS = 3,
+ // section with only 4 byte literals
+ S_8BYTE_LITERALS = 4,
+ // section with only 8 byte literals
+ S_LITERAL_POINTERS = 5,
+ // section with only pointers to literals
+ S_NON_LAZY_SYMBOL_POINTERS = 6,
+ // section with only non-lazy symbol pointers
+ S_LAZY_SYMBOL_POINTERS = 7,
+ // section with only lazy symbol pointers
+ S_SYMBOL_STUBS = 8,
+ // section with only symbol stubs
+ // byte size of stub in the reserved2 field
+ S_MOD_INIT_FUNC_POINTERS = 9,
+ // section with only function pointers for initialization
+ S_MOD_TERM_FUNC_POINTERS = 10,
+ // section with only function pointers for termination
+ S_COALESCED = 11,
+ // section contains symbols that are coalesced
+ S_GB_ZEROFILL = 12,
+ // zero fill on demand section (that can be larger than 4GB)
+ S_INTERPOSING = 13,
+ // section with only pairs of function pointers for interposing
+ S_16BYTE_LITERALS = 14
+ // section with only 16 byte literals
+ };
+
+ // Constants for the section flags (high 24 bits of flags field)
+ // see <mach-o/loader.h>
+ enum { S_ATTR_PURE_INSTRUCTIONS = 1 << 31,
+ // section contains only true machine instructions
+ S_ATTR_NO_TOC = 1 << 30,
+ // section contains coalesced symbols that are not to be in a
+ // ranlib table of contents
+ S_ATTR_STRIP_STATIC_SYMS = 1 << 29,
+ // ok to strip static symbols in this section in files with the
+ // MY_DYLDLINK flag
+ S_ATTR_NO_DEAD_STRIP = 1 << 28,
+ // no dead stripping
+ S_ATTR_LIVE_SUPPORT = 1 << 27,
+ // blocks are live if they reference live blocks
+ S_ATTR_SELF_MODIFYING_CODE = 1 << 26,
+ // used with i386 code stubs written on by dyld
+ S_ATTR_DEBUG = 1 << 25,
+ // a debug section
+ S_ATTR_SOME_INSTRUCTIONS = 1 << 10,
+ // section contains some machine instructions
+ S_ATTR_EXT_RELOC = 1 << 9,
+ // section has external relocation entries
+ S_ATTR_LOC_RELOC = 1 << 8
+ // section has local relocation entries
+ };
+
+ /// cmdSize - This routine returns the size of the MachOSection as written
+ /// to disk, depending on whether the destination is a 64 bit Mach-O file.
+ unsigned cmdSize(bool is64Bit) const {
+ if (is64Bit)
+ return 7 * sizeof(uint32_t) + 2 * sizeof(uint64_t) + 32;
+ else
+ return 9 * sizeof(uint32_t) + 32; // addresses only 32 bits
+ }
+
+ MachOSection(const std::string &seg, const std::string &sect)
+ : sectname(sect), segname(seg), addr(0), size(0), offset(0), align(2),
+ reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0),
+ reserved3(0) { }
+
+}; // end struct MachOSection
+
+ /// MachOSymTab - This struct contains information about the offsets and
+ /// size of symbol table information.
+ /// segment.
+ struct MachODySymTab {
+ uint32_t cmd; // LC_DYSYMTAB
+ uint32_t cmdsize; // sizeof( MachODySymTab )
+ uint32_t ilocalsym; // index to local symbols
+ uint32_t nlocalsym; // number of local symbols
+ uint32_t iextdefsym; // index to externally defined symbols
+ uint32_t nextdefsym; // number of externally defined symbols
+ uint32_t iundefsym; // index to undefined symbols
+ uint32_t nundefsym; // number of undefined symbols
+ uint32_t tocoff; // file offset to table of contents
+ uint32_t ntoc; // number of entries in table of contents
+ uint32_t modtaboff; // file offset to module table
+ uint32_t nmodtab; // number of module table entries
+ uint32_t extrefsymoff; // offset to referenced symbol table
+ uint32_t nextrefsyms; // number of referenced symbol table entries
+ uint32_t indirectsymoff; // file offset to the indirect symbol table
+ uint32_t nindirectsyms; // number of indirect symbol table entries
+ uint32_t extreloff; // offset to external relocation entries
+ uint32_t nextrel; // number of external relocation entries
+ uint32_t locreloff; // offset to local relocation entries
+ uint32_t nlocrel; // number of local relocation entries
+
+ // Constants for the cmd field
+ // see <mach-o/loader.h>
+ enum { LC_DYSYMTAB = 0x0B // dynamic link-edit symbol table info
+ };
+
+ MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)),
+ ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0),
+ iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0),
+ nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0),
+ nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) { }
+ };
+
+} // end namespace llvm
+
+#endif
+
diff --git a/lib/CodeGen/MachOCodeEmitter.cpp b/lib/CodeGen/MachOCodeEmitter.cpp
new file mode 100644
index 0000000..02b02de
--- /dev/null
+++ b/lib/CodeGen/MachOCodeEmitter.cpp
@@ -0,0 +1,207 @@
+//===-- MachOEmitter.cpp - Target-independent Mach-O Emitter code --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MachOCodeEmitter.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/Support/Mangler.h"
+#include "llvm/Support/OutputBuffer.h"
+
+//===----------------------------------------------------------------------===//
+// MachOCodeEmitter Implementation
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+/// startFunction - This callback is invoked when a new machine function is
+/// about to be emitted.
+
+void MachOCodeEmitter::startFunction(MachineFunction &MF) {
+ const TargetData *TD = TM.getTargetData();
+ const Function *F = MF.getFunction();
+
+ // Align the output buffer to the appropriate alignment, power of 2.
+ unsigned FnAlign = F->getAlignment();
+ unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
+ unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
+ assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
+
+ // Get the Mach-O Section that this function belongs in.
+ MachOSection *MOS = MOW.getTextSection();
+
+ // FIXME: better memory management
+ MOS->SectionData.reserve(4096);
+ BufferBegin = &MOS->SectionData[0];
+ BufferEnd = BufferBegin + MOS->SectionData.capacity();
+
+ // Upgrade the section alignment if required.
+ if (MOS->align < Align) MOS->align = Align;
+
+ // Round the size up to the correct alignment for starting the new function.
+ if ((MOS->size & ((1 << Align) - 1)) != 0) {
+ MOS->size += (1 << Align);
+ MOS->size &= ~((1 << Align) - 1);
+ }
+
+ // FIXME: Using MOS->size directly here instead of calculating it from the
+ // output buffer size (impossible because the code emitter deals only in raw
+ // bytes) forces us to manually synchronize size and write padding zero bytes
+ // to the output buffer for all non-text sections. For text sections, we do
+ // not synchonize the output buffer, and we just blow up if anyone tries to
+ // write non-code to it. An assert should probably be added to
+ // AddSymbolToSection to prevent calling it on the text section.
+ CurBufferPtr = BufferBegin + MOS->size;
+}
+
+/// finishFunction - This callback is invoked after the function is completely
+/// finished.
+
+bool MachOCodeEmitter::finishFunction(MachineFunction &MF) {
+
+ // Get the Mach-O Section that this function belongs in.
+ MachOSection *MOS = MOW.getTextSection();
+
+ // Get a symbol for the function to add to the symbol table
+ // FIXME: it seems like we should call something like AddSymbolToSection
+ // in startFunction rather than changing the section size and symbol n_value
+ // here.
+ const GlobalValue *FuncV = MF.getFunction();
+ MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TAI);
+ FnSym.n_value = MOS->size;
+ MOS->size = CurBufferPtr - BufferBegin;
+
+ // Emit constant pool to appropriate section(s)
+ emitConstantPool(MF.getConstantPool());
+
+ // Emit jump tables to appropriate section
+ emitJumpTables(MF.getJumpTableInfo());
+
+ // If we have emitted any relocations to function-specific objects such as
+ // basic blocks, constant pools entries, or jump tables, record their
+ // addresses now so that we can rewrite them with the correct addresses
+ // later.
+ for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
+ MachineRelocation &MR = Relocations[i];
+ intptr_t Addr;
+
+ if (MR.isBasicBlock()) {
+ Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
+ MR.setConstantVal(MOS->Index);
+ MR.setResultPointer((void*)Addr);
+ } else if (MR.isJumpTableIndex()) {
+ Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
+ MR.setConstantVal(MOW.getJumpTableSection()->Index);
+ MR.setResultPointer((void*)Addr);
+ } else if (MR.isConstantPoolIndex()) {
+ Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
+ MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
+ MR.setResultPointer((void*)Addr);
+ } else if (MR.isGlobalValue()) {
+ // FIXME: This should be a set or something that uniques
+ MOW.PendingGlobals.push_back(MR.getGlobalValue());
+ } else {
+ assert(0 && "Unhandled relocation type");
+ }
+ MOS->Relocations.push_back(MR);
+ }
+ Relocations.clear();
+
+ // Finally, add it to the symtab.
+ MOW.SymbolTable.push_back(FnSym);
+
+ // Clear per-function data structures.
+ CPLocations.clear();
+ CPSections.clear();
+ JTLocations.clear();
+ MBBLocations.clear();
+
+ return false;
+}
+
+/// emitConstantPool - For each constant pool entry, figure out which section
+/// the constant should live in, allocate space for it, and emit it to the
+/// Section data buffer.
+void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
+ const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
+ if (CP.empty()) return;
+
+ // FIXME: handle PIC codegen
+ assert(TM.getRelocationModel() != Reloc::PIC_ &&
+ "PIC codegen not yet handled for mach-o jump tables!");
+
+ // Although there is no strict necessity that I am aware of, we will do what
+ // gcc for OS X does and put each constant pool entry in a section of constant
+ // objects of a certain size. That means that float constants go in the
+ // literal4 section, and double objects go in literal8, etc.
+ //
+ // FIXME: revisit this decision if we ever do the "stick everything into one
+ // "giant object for PIC" optimization.
+ for (unsigned i = 0, e = CP.size(); i != e; ++i) {
+ const Type *Ty = CP[i].getType();
+ unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
+
+ MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
+ OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
+
+ CPLocations.push_back(Sec->SectionData.size());
+ CPSections.push_back(Sec->Index);
+
+ // FIXME: remove when we have unified size + output buffer
+ Sec->size += Size;
+
+ // Allocate space in the section for the global.
+ // FIXME: need alignment?
+ // FIXME: share between here and AddSymbolToSection?
+ for (unsigned j = 0; j < Size; ++j)
+ SecDataOut.outbyte(0);
+
+ MOW.InitMem(CP[i].Val.ConstVal, &Sec->SectionData[0], CPLocations[i],
+ TM.getTargetData(), Sec->Relocations);
+ }
+}
+
+/// emitJumpTables - Emit all the jump tables for a given jump table info
+/// record to the appropriate section.
+
+void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ if (JT.empty()) return;
+
+ // FIXME: handle PIC codegen
+ assert(TM.getRelocationModel() != Reloc::PIC_ &&
+ "PIC codegen not yet handled for mach-o jump tables!");
+
+ MachOSection *Sec = MOW.getJumpTableSection();
+ unsigned TextSecIndex = MOW.getTextSection()->Index;
+ OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
+
+ for (unsigned i = 0, e = JT.size(); i != e; ++i) {
+ // For each jump table, record its offset from the start of the section,
+ // reserve space for the relocations to the MBBs, and add the relocations.
+ const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
+ JTLocations.push_back(Sec->SectionData.size());
+ for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
+ MachineRelocation MR(MOW.GetJTRelocation(Sec->SectionData.size(),
+ MBBs[mi]));
+ MR.setResultPointer((void *)JTLocations[i]);
+ MR.setConstantVal(TextSecIndex);
+ Sec->Relocations.push_back(MR);
+ SecDataOut.outaddr(0);
+ }
+ }
+ // FIXME: remove when we have unified size + output buffer
+ Sec->size = Sec->SectionData.size();
+}
+
+} // end namespace llvm
+
diff --git a/lib/CodeGen/MachOCodeEmitter.h b/lib/CodeGen/MachOCodeEmitter.h
new file mode 100644
index 0000000..0a6e4e4
--- /dev/null
+++ b/lib/CodeGen/MachOCodeEmitter.h
@@ -0,0 +1,129 @@
+//===-- MachOEmitter.h - Target-independent Mach-O Emitter class ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MACHOCODEEMITTER_H
+#define MACHOCODEEMITTER_H
+
+#include "MachOWriter.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include <vector>
+
+namespace llvm {
+
+/// MachOCodeEmitter - This class is used by the MachOWriter to emit the code
+/// for functions to the Mach-O file.
+
+class MachOCodeEmitter : public MachineCodeEmitter {
+ MachOWriter &MOW;
+
+ /// Target machine description.
+ TargetMachine &TM;
+
+ /// is64Bit/isLittleEndian - This information is inferred from the target
+ /// machine directly, indicating what header values and flags to set.
+ bool is64Bit, isLittleEndian;
+
+ const TargetAsmInfo *TAI;
+
+ /// Relocations - These are the relocations that the function needs, as
+ /// emitted.
+ std::vector<MachineRelocation> Relocations;
+
+ /// CPLocations - This is a map of constant pool indices to offsets from the
+ /// start of the section for that constant pool index.
+ std::vector<uintptr_t> CPLocations;
+
+ /// CPSections - This is a map of constant pool indices to the MachOSection
+ /// containing the constant pool entry for that index.
+ std::vector<unsigned> CPSections;
+
+ /// JTLocations - This is a map of jump table indices to offsets from the
+ /// start of the section for that jump table index.
+ std::vector<uintptr_t> JTLocations;
+
+ /// MBBLocations - This vector is a mapping from MBB ID's to their address.
+ /// It is filled in by the StartMachineBasicBlock callback and queried by
+ /// the getMachineBasicBlockAddress callback.
+ std::vector<uintptr_t> MBBLocations;
+
+public:
+ MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM)
+ {
+ is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
+ isLittleEndian = TM.getTargetData()->isLittleEndian();
+ TAI = TM.getTargetAsmInfo();
+ }
+
+ virtual void startFunction(MachineFunction &MF);
+ virtual bool finishFunction(MachineFunction &MF);
+
+ virtual void addRelocation(const MachineRelocation &MR) {
+ Relocations.push_back(MR);
+ }
+
+ void emitConstantPool(MachineConstantPool *MCP);
+ void emitJumpTables(MachineJumpTableInfo *MJTI);
+
+ virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
+ assert(CPLocations.size() > Index && "CP not emitted!");
+ return CPLocations[Index];
+ }
+ virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
+ assert(JTLocations.size() > Index && "JT not emitted!");
+ return JTLocations[Index];
+ }
+
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
+ if (MBBLocations.size() <= (unsigned)MBB->getNumber())
+ MBBLocations.resize((MBB->getNumber()+1)*2);
+ MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
+ }
+
+ virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
+ assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
+ MBBLocations[MBB->getNumber()] && "MBB not emitted!");
+ return MBBLocations[MBB->getNumber()];
+ }
+
+ virtual uintptr_t getLabelAddress(uint64_t Label) const {
+ assert(0 && "get Label not implemented");
+ abort();
+ return 0;
+ }
+
+ virtual void emitLabel(uint64_t LabelID) {
+ assert(0 && "emit Label not implemented");
+ abort();
+ }
+
+ virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
+ /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
+ virtual void startGVStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment = 1) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ }
+ virtual void startGVStub(const GlobalValue* F, void *Buffer,
+ unsigned StubSize) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ }
+ virtual void *finishGVStub(const GlobalValue* F) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ return 0;
+ }
+
+}; // end class MachOCodeEmitter
+
+} // end namespace llvm
+
+#endif
+
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp
index 4332627..163df69 100644
--- a/lib/CodeGen/MachOWriter.cpp
+++ b/lib/CodeGen/MachOWriter.cpp
@@ -23,6 +23,7 @@
//===----------------------------------------------------------------------===//
#include "MachOWriter.h"
+#include "MachOCodeEmitter.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
@@ -40,11 +41,12 @@
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
-using namespace llvm;
+
+namespace llvm {
/// AddMachOWriter - Concrete function to add the Mach-O writer to the function
/// pass manager.
-MachineCodeEmitter *llvm::AddMachOWriter(PassManagerBase &PM,
+MachineCodeEmitter *AddMachOWriter(PassManagerBase &PM,
raw_ostream &O,
TargetMachine &TM) {
MachOWriter *MOW = new MachOWriter(O, TM);
@@ -53,304 +55,74 @@ MachineCodeEmitter *llvm::AddMachOWriter(PassManagerBase &PM,
}
//===----------------------------------------------------------------------===//
-// MachOCodeEmitter Implementation
+// MachOWriter Implementation
//===----------------------------------------------------------------------===//
-namespace llvm {
- /// MachOCodeEmitter - This class is used by the MachOWriter to emit the code
- /// for functions to the Mach-O file.
- class MachOCodeEmitter : public MachineCodeEmitter {
- MachOWriter &MOW;
-
- /// Target machine description.
- TargetMachine &TM;
-
- /// is64Bit/isLittleEndian - This information is inferred from the target
- /// machine directly, indicating what header values and flags to set.
- bool is64Bit, isLittleEndian;
-
- /// Relocations - These are the relocations that the function needs, as
- /// emitted.
- std::vector<MachineRelocation> Relocations;
-
- /// CPLocations - This is a map of constant pool indices to offsets from the
- /// start of the section for that constant pool index.
- std::vector<uintptr_t> CPLocations;
-
- /// CPSections - This is a map of constant pool indices to the MachOSection
- /// containing the constant pool entry for that index.
- std::vector<unsigned> CPSections;
-
- /// JTLocations - This is a map of jump table indices to offsets from the
- /// start of the section for that jump table index.
- std::vector<uintptr_t> JTLocations;
-
- /// MBBLocations - This vector is a mapping from MBB ID's to their address.
- /// It is filled in by the StartMachineBasicBlock callback and queried by
- /// the getMachineBasicBlockAddress callback.
- std::vector<uintptr_t> MBBLocations;
-
- public:
- MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM) {
- is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
- isLittleEndian = TM.getTargetData()->isLittleEndian();
- }
-
- virtual void startFunction(MachineFunction &MF);
- virtual bool finishFunction(MachineFunction &MF);
-
- virtual void addRelocation(const MachineRelocation &MR) {
- Relocations.push_back(MR);
- }
-
- void emitConstantPool(MachineConstantPool *MCP);
- void emitJumpTables(MachineJumpTableInfo *MJTI);
-
- virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- assert(CPLocations.size() > Index && "CP not emitted!");
- return CPLocations[Index];
- }
- virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
- assert(JTLocations.size() > Index && "JT not emitted!");
- return JTLocations[Index];
- }
-
- virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
- if (MBBLocations.size() <= (unsigned)MBB->getNumber())
- MBBLocations.resize((MBB->getNumber()+1)*2);
- MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
- }
-
- virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
- assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
- MBBLocations[MBB->getNumber()] && "MBB not emitted!");
- return MBBLocations[MBB->getNumber()];
- }
+char MachOWriter::ID = 0;
- virtual uintptr_t getLabelAddress(uint64_t Label) const {
- assert(0 && "get Label not implemented");
- abort();
- return 0;
- }
+MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm)
+ : MachineFunctionPass(&ID), O(o), TM(tm) {
+ is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
+ isLittleEndian = TM.getTargetData()->isLittleEndian();
- virtual void emitLabel(uint64_t LabelID) {
- assert(0 && "emit Label not implemented");
- abort();
- }
+ TAI = TM.getTargetAsmInfo();
+ // Create the machine code emitter object for this target.
- virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+ MCE = new MachOCodeEmitter(*this);
+}
- /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
- virtual void startGVStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment = 1) {
- assert(0 && "JIT specific function called!");
- abort();
- }
- virtual void startGVStub(const GlobalValue* F, void *Buffer,
- unsigned StubSize) {
- assert(0 && "JIT specific function called!");
- abort();
- }
- virtual void *finishGVStub(const GlobalValue* F) {
- assert(0 && "JIT specific function called!");
- abort();
- return 0;
- }
- };
+MachOWriter::~MachOWriter() {
+ delete MCE;
}
-/// startFunction - This callback is invoked when a new machine function is
-/// about to be emitted.
-void MachOCodeEmitter::startFunction(MachineFunction &MF) {
- const TargetData *TD = TM.getTargetData();
- const Function *F = MF.getFunction();
-
- // Align the output buffer to the appropriate alignment, power of 2.
- unsigned FnAlign = F->getAlignment();
- unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
- unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
- assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
-
- // Get the Mach-O Section that this function belongs in.
- MachOWriter::MachOSection *MOS = MOW.getTextSection();
-
- // FIXME: better memory management
- MOS->SectionData.reserve(4096);
- BufferBegin = &MOS->SectionData[0];
- BufferEnd = BufferBegin + MOS->SectionData.capacity();
-
- // Upgrade the section alignment if required.
- if (MOS->align < Align) MOS->align = Align;
-
- // Round the size up to the correct alignment for starting the new function.
- if ((MOS->size & ((1 << Align) - 1)) != 0) {
- MOS->size += (1 << Align);
- MOS->size &= ~((1 << Align) - 1);
- }
+bool MachOWriter::doInitialization(Module &M) {
+ // Set the magic value, now that we know the pointer size and endianness
+ Header.setMagic(isLittleEndian, is64Bit);
- // FIXME: Using MOS->size directly here instead of calculating it from the
- // output buffer size (impossible because the code emitter deals only in raw
- // bytes) forces us to manually synchronize size and write padding zero bytes
- // to the output buffer for all non-text sections. For text sections, we do
- // not synchonize the output buffer, and we just blow up if anyone tries to
- // write non-code to it. An assert should probably be added to
- // AddSymbolToSection to prevent calling it on the text section.
- CurBufferPtr = BufferBegin + MOS->size;
-
- // Clear per-function data structures.
- CPLocations.clear();
- CPSections.clear();
- JTLocations.clear();
- MBBLocations.clear();
-}
+ // Set the file type
+ // FIXME: this only works for object files, we do not support the creation
+ // of dynamic libraries or executables at this time.
+ Header.filetype = MachOHeader::MH_OBJECT;
-/// finishFunction - This callback is invoked after the function is completely
-/// finished.
-bool MachOCodeEmitter::finishFunction(MachineFunction &MF) {
- // Get the Mach-O Section that this function belongs in.
- MachOWriter::MachOSection *MOS = MOW.getTextSection();
-
- // Get a symbol for the function to add to the symbol table
- // FIXME: it seems like we should call something like AddSymbolToSection
- // in startFunction rather than changing the section size and symbol n_value
- // here.
- const GlobalValue *FuncV = MF.getFunction();
- MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TM);
- FnSym.n_value = MOS->size;
- MOS->size = CurBufferPtr - BufferBegin;
-
- // Emit constant pool to appropriate section(s)
- emitConstantPool(MF.getConstantPool());
-
- // Emit jump tables to appropriate section
- emitJumpTables(MF.getJumpTableInfo());
-
- // If we have emitted any relocations to function-specific objects such as
- // basic blocks, constant pools entries, or jump tables, record their
- // addresses now so that we can rewrite them with the correct addresses
- // later.
- for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
- MachineRelocation &MR = Relocations[i];
- intptr_t Addr;
-
- if (MR.isBasicBlock()) {
- Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
- MR.setConstantVal(MOS->Index);
- MR.setResultPointer((void*)Addr);
- } else if (MR.isJumpTableIndex()) {
- Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
- MR.setConstantVal(MOW.getJumpTableSection()->Index);
- MR.setResultPointer((void*)Addr);
- } else if (MR.isConstantPoolIndex()) {
- Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
- MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
- MR.setResultPointer((void*)Addr);
- } else if (MR.isGlobalValue()) {
- // FIXME: This should be a set or something that uniques
- MOW.PendingGlobals.push_back(MR.getGlobalValue());
- } else {
- assert(0 && "Unhandled relocation type");
- }
- MOS->Relocations.push_back(MR);
- }
- Relocations.clear();
-
- // Finally, add it to the symtab.
- MOW.SymbolTable.push_back(FnSym);
+ Mang = new Mangler(M);
return false;
}
-/// emitConstantPool - For each constant pool entry, figure out which section
-/// the constant should live in, allocate space for it, and emit it to the
-/// Section data buffer.
-void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
- const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
- if (CP.empty()) return;
-
- // FIXME: handle PIC codegen
- assert(TM.getRelocationModel() != Reloc::PIC_ &&
- "PIC codegen not yet handled for mach-o jump tables!");
-
- // Although there is no strict necessity that I am aware of, we will do what
- // gcc for OS X does and put each constant pool entry in a section of constant
- // objects of a certain size. That means that float constants go in the
- // literal4 section, and double objects go in literal8, etc.
- //
- // FIXME: revisit this decision if we ever do the "stick everything into one
- // "giant object for PIC" optimization.
- for (unsigned i = 0, e = CP.size(); i != e; ++i) {
- const Type *Ty = CP[i].getType();
- unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
-
- MachOWriter::MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
- OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
-
- CPLocations.push_back(Sec->SectionData.size());
- CPSections.push_back(Sec->Index);
-
- // FIXME: remove when we have unified size + output buffer
- Sec->size += Size;
-
- // Allocate space in the section for the global.
- // FIXME: need alignment?
- // FIXME: share between here and AddSymbolToSection?
- for (unsigned j = 0; j < Size; ++j)
- SecDataOut.outbyte(0);
-
- MOW.InitMem(CP[i].Val.ConstVal, &Sec->SectionData[0], CPLocations[i],
- TM.getTargetData(), Sec->Relocations);
- }
+bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
+ return false;
}
-/// emitJumpTables - Emit all the jump tables for a given jump table info
-/// record to the appropriate section.
-void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
- const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
- if (JT.empty()) return;
-
- // FIXME: handle PIC codegen
- assert(TM.getRelocationModel() != Reloc::PIC_ &&
- "PIC codegen not yet handled for mach-o jump tables!");
+/// doFinalization - Now that the module has been completely processed, emit
+/// the Mach-O file to 'O'.
+bool MachOWriter::doFinalization(Module &M) {
+ // FIXME: we don't handle debug info yet, we should probably do that.
- MachOWriter::MachOSection *Sec = MOW.getJumpTableSection();
- unsigned TextSecIndex = MOW.getTextSection()->Index;
- OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
+ // Okay, the.text section has been completed, build the .data, .bss, and
+ // "common" sections next.
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
+ EmitGlobal(I);
- for (unsigned i = 0, e = JT.size(); i != e; ++i) {
- // For each jump table, record its offset from the start of the section,
- // reserve space for the relocations to the MBBs, and add the relocations.
- const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
- JTLocations.push_back(Sec->SectionData.size());
- for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
- MachineRelocation MR(MOW.GetJTRelocation(Sec->SectionData.size(),
- MBBs[mi]));
- MR.setResultPointer((void *)JTLocations[i]);
- MR.setConstantVal(TextSecIndex);
- Sec->Relocations.push_back(MR);
- SecDataOut.outaddr(0);
- }
- }
- // FIXME: remove when we have unified size + output buffer
- Sec->size = Sec->SectionData.size();
-}
+ // Emit the header and load commands.
+ EmitHeaderAndLoadCommands();
-//===----------------------------------------------------------------------===//
-// MachOWriter Implementation
-//===----------------------------------------------------------------------===//
+ // Emit the various sections and their relocation info.
+ EmitSections();
+ EmitRelocations();
-char MachOWriter::ID = 0;
-MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm)
- : MachineFunctionPass(&ID), O(o), TM(tm) {
- is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
- isLittleEndian = TM.getTargetData()->isLittleEndian();
+ // Write the symbol table and the string table to the end of the file.
+ O.write((char*)&SymT[0], SymT.size());
+ O.write((char*)&StrT[0], StrT.size());
- // Create the machine code emitter object for this target.
- MCE = new MachOCodeEmitter(*this);
-}
+ // We are done with the abstract symbols.
+ SectionList.clear();
+ SymbolTable.clear();
+ DynamicSymbolTable.clear();
-MachOWriter::~MachOWriter() {
- delete MCE;
+ // Release the name mangler object.
+ delete Mang; Mang = 0;
+ return false;
}
void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
@@ -368,7 +140,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
Align = Log2_32(Align);
Sec->align = std::max(unsigned(Sec->align), Align);
Sec->size = (Sec->size + Align - 1) & ~(Align-1);
-
+
// Add alignment padding to buffer as well.
// FIXME: remove when we have unified size + output buffer
unsigned AlignedSize = Sec->size - OrigSize;
@@ -377,7 +149,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
}
// Globals without external linkage apparently do not go in the symbol table.
if (!GV->hasLocalLinkage()) {
- MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM);
+ MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TAI);
Sym.n_value = Sec->size;
SymbolTable.push_back(Sym);
}
@@ -385,14 +157,14 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
// Record the offset of the symbol, and then allocate space for it.
// FIXME: remove when we have unified size + output buffer
Sec->size += Size;
-
- // Now that we know what section the GlovalVariable is going to be emitted
+
+ // Now that we know what section the GlovalVariable is going to be emitted
// into, update our mappings.
// FIXME: We may also need to update this when outputting non-GlobalVariable
// GlobalValues such as functions.
GVSection[GV] = Sec;
GVOffset[GV] = Sec->SectionData.size();
-
+
// Allocate space in the section for the global.
for (unsigned i = 0; i < Size; ++i)
SecDataOut.outbyte(0);
@@ -402,7 +174,7 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) {
const Type *Ty = GV->getType()->getElementType();
unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
bool NoInit = !GV->hasInitializer();
-
+
// If this global has a zero initializer, it is part of the .bss or common
// section.
if (NoInit || GV->getInitializer()->isNullValue()) {
@@ -411,7 +183,8 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) {
// merged with other symbols.
if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
GV->hasCommonLinkage()) {
- MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT,TM);
+ MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV),
+ MachOSym::NO_SECT, TAI);
// For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
// bytes of the symbol.
ExtOrCommonSym.n_value = Size;
@@ -425,11 +198,11 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) {
AddSymbolToSection(BSS, GV);
return;
}
-
+
// Scalar read-only data goes in a literal section if the scalar is 4, 8, or
// 16 bytes, or a cstring. Other read only data goes into a regular const
// section. Read-write data goes in the data section.
- MachOSection *Sec = GV->isConstant() ? getConstSection(GV->getInitializer()) :
+ MachOSection *Sec = GV->isConstant() ? getConstSection(GV->getInitializer()) :
getDataSection();
AddSymbolToSection(Sec, GV);
InitMem(GV->getInitializer(), &Sec->SectionData[0], GVOffset[GV],
@@ -437,73 +210,25 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) {
}
-bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
- // Nothing to do here, this is all done through the MCE object.
- return false;
-}
-
-bool MachOWriter::doInitialization(Module &M) {
- // Set the magic value, now that we know the pointer size and endianness
- Header.setMagic(isLittleEndian, is64Bit);
-
- // Set the file type
- // FIXME: this only works for object files, we do not support the creation
- // of dynamic libraries or executables at this time.
- Header.filetype = MachOHeader::MH_OBJECT;
-
- Mang = new Mangler(M);
- return false;
-}
-
-/// doFinalization - Now that the module has been completely processed, emit
-/// the Mach-O file to 'O'.
-bool MachOWriter::doFinalization(Module &M) {
- // FIXME: we don't handle debug info yet, we should probably do that.
-
- // Okay, the.text section has been completed, build the .data, .bss, and
- // "common" sections next.
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- EmitGlobal(I);
-
- // Emit the header and load commands.
- EmitHeaderAndLoadCommands();
-
- // Emit the various sections and their relocation info.
- EmitSections();
-
- // Write the symbol table and the string table to the end of the file.
- O.write((char*)&SymT[0], SymT.size());
- O.write((char*)&StrT[0], StrT.size());
-
- // We are done with the abstract symbols.
- SectionList.clear();
- SymbolTable.clear();
- DynamicSymbolTable.clear();
-
- // Release the name mangler object.
- delete Mang; Mang = 0;
- return false;
-}
void MachOWriter::EmitHeaderAndLoadCommands() {
// Step #0: Fill in the segment load command size, since we need it to figure
// out the rest of the header fields
MachOSegment SEG("", is64Bit);
SEG.nsects = SectionList.size();
- SEG.cmdsize = SEG.cmdSize(is64Bit) +
+ SEG.cmdsize = SEG.cmdSize(is64Bit) +
SEG.nsects * SectionList[0]->cmdSize(is64Bit);
-
+
// Step #1: calculate the number of load commands. We always have at least
// one, for the LC_SEGMENT load command, plus two for the normal
// and dynamic symbol tables, if there are any symbols.
Header.ncmds = SymbolTable.empty() ? 1 : 3;
-
+
// Step #2: calculate the size of the load commands
Header.sizeofcmds = SEG.cmdsize;
if (!SymbolTable.empty())
Header.sizeofcmds += SymTab.cmdsize + DySymTab.cmdsize;
-
+
// Step #3: write the header to the file
// Local alias to shortenify coming code.
DataBuffer &FH = Header.HeaderData;
@@ -518,7 +243,7 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
FHOut.outword(Header.flags);
if (is64Bit)
FHOut.outword(Header.reserved);
-
+
// Step #4: Finish filling in the segment load command and write it out
for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
E = SectionList.end(); I != E; ++I)
@@ -526,7 +251,7 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
SEG.vmsize = SEG.filesize;
SEG.fileoff = Header.cmdSize(is64Bit) + Header.sizeofcmds;
-
+
FHOut.outword(SEG.cmd);
FHOut.outword(SEG.cmdsize);
FHOut.outstring(SEG.segname, 16);
@@ -538,8 +263,8 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
FHOut.outword(SEG.initprot);
FHOut.outword(SEG.nsects);
FHOut.outword(SEG.flags);
-
- // Step #5: Finish filling in the fields of the MachOSections
+
+ // Step #5: Finish filling in the fields of the MachOSections
uint64_t currentAddr = 0;
for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
E = SectionList.end(); I != E; ++I) {
@@ -550,13 +275,13 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
// FIXME: do we need to do something with alignment here?
currentAddr += MOS->size;
}
-
+
// Step #6: Emit the symbol table to temporary buffers, so that we know the
// size of the string table when we write the next load command. This also
// sorts and assigns indices to each of the symbols, which is necessary for
// emitting relocations to externally-defined objects.
BufferSymbolAndStringTable();
-
+
// Step #7: Calculate the number of relocations for each section and write out
// the section commands for each section
currentAddr += SEG.fileoff;
@@ -568,7 +293,7 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
CalculateRelocations(*MOS);
MOS->reloff = MOS->nreloc ? currentAddr : 0;
currentAddr += MOS->nreloc * 8;
-
+
// write the finalized section command to the output buffer
FHOut.outstring(MOS->sectname, 16);
FHOut.outstring(MOS->segname, 16);
@@ -584,7 +309,7 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
if (is64Bit)
FHOut.outword(MOS->reserved3);
}
-
+
// Step #8: Emit LC_SYMTAB/LC_DYSYMTAB load commands
SymTab.symoff = currentAddr;
SymTab.nsyms = SymbolTable.size();
@@ -620,94 +345,92 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
FHOut.outword(DySymTab.nextrel);
FHOut.outword(DySymTab.locreloff);
FHOut.outword(DySymTab.nlocrel);
-
+
O.write((char*)&FH[0], FH.size());
}
/// EmitSections - Now that we have constructed the file header and load
/// commands, emit the data for each section to the file.
+
void MachOWriter::EmitSections() {
for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
E = SectionList.end(); I != E; ++I)
// Emit the contents of each section
O.write((char*)&(*I)->SectionData[0], (*I)->size);
+}
+void MachOWriter::EmitRelocations() {
for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
E = SectionList.end(); I != E; ++I)
// Emit the relocation entry data for each section.
O.write((char*)&(*I)->RelocBuffer[0], (*I)->RelocBuffer.size());
}
-/// PartitionByLocal - Simple boolean predicate that returns true if Sym is
-/// a local symbol rather than an external symbol.
-bool MachOWriter::PartitionByLocal(const MachOSym &Sym) {
- return (Sym.n_type & (MachOSym::N_EXT | MachOSym::N_PEXT)) == 0;
-}
-
-/// PartitionByDefined - Simple boolean predicate that returns true if Sym is
-/// defined in this module.
-bool MachOWriter::PartitionByDefined(const MachOSym &Sym) {
- // FIXME: Do N_ABS or N_INDR count as defined?
- return (Sym.n_type & MachOSym::N_SECT) == MachOSym::N_SECT;
-}
-
/// BufferSymbolAndStringTable - Sort the symbols we encountered and assign them
/// each a string table index so that they appear in the correct order in the
/// output file.
+
void MachOWriter::BufferSymbolAndStringTable() {
// The order of the symbol table is:
// 1. local symbols
// 2. defined external symbols (sorted by name)
// 3. undefined external symbols (sorted by name)
-
+
// Before sorting the symbols, check the PendingGlobals for any undefined
// globals that need to be put in the symbol table.
+
for (std::vector<GlobalValue*>::iterator I = PendingGlobals.begin(),
E = PendingGlobals.end(); I != E; ++I) {
if (GVOffset[*I] == 0 && GVSection[*I] == 0) {
- MachOSym UndfSym(*I, Mang->getValueName(*I), MachOSym::NO_SECT, TM);
+ MachOSym UndfSym(*I, Mang->getValueName(*I), MachOSym::NO_SECT, TAI);
SymbolTable.push_back(UndfSym);
GVOffset[*I] = -1;
}
}
-
+
// Sort the symbols by name, so that when we partition the symbols by scope
// of definition, we won't have to sort by name within each partition.
- std::sort(SymbolTable.begin(), SymbolTable.end(), MachOSymCmp());
- // Parition the symbol table entries so that all local symbols come before
+ std::sort(SymbolTable.begin(), SymbolTable.end(), MachOSym::SymCmp());
+
+ // Parition the symbol table entries so that all local symbols come before
// all symbols with external linkage. { 1 | 2 3 }
- std::partition(SymbolTable.begin(), SymbolTable.end(), PartitionByLocal);
-
+
+ std::partition(SymbolTable.begin(), SymbolTable.end(),
+ MachOSym::PartitionByLocal);
+
// Advance iterator to beginning of external symbols and partition so that
// all external symbols defined in this module come before all external
// symbols defined elsewhere. { 1 | 2 | 3 }
+
for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
E = SymbolTable.end(); I != E; ++I) {
- if (!PartitionByLocal(*I)) {
- std::partition(I, E, PartitionByDefined);
+ if (!MachOSym::PartitionByLocal(*I)) {
+ std::partition(I, E, MachOSym::PartitionByDefined);
break;
}
}
- // Calculate the starting index for each of the local, extern defined, and
+ // Calculate the starting index for each of the local, extern defined, and
// undefined symbols, as well as the number of each to put in the LC_DYSYMTAB
// load command.
+
for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
E = SymbolTable.end(); I != E; ++I) {
- if (PartitionByLocal(*I)) {
+ if (MachOSym::PartitionByLocal(*I)) {
++DySymTab.nlocalsym;
++DySymTab.iextdefsym;
++DySymTab.iundefsym;
- } else if (PartitionByDefined(*I)) {
+ } else if (MachOSym::PartitionByDefined(*I)) {
++DySymTab.nextdefsym;
++DySymTab.iundefsym;
} else {
++DySymTab.nundefsym;
}
}
-
+
// Write out a leading zero byte when emitting string table, for n_strx == 0
// which means an empty string.
+
OutputBuffer StrTOut(StrT, is64Bit, isLittleEndian);
StrTOut.outbyte(0);
@@ -716,6 +439,7 @@ void MachOWriter::BufferSymbolAndStringTable() {
// 2. strings for local symbols
// Since this is the opposite order from the symbol table, which we have just
// sorted, we can walk the symbol table backwards to output the string table.
+
for (std::vector<MachOSym>::reverse_iterator I = SymbolTable.rbegin(),
E = SymbolTable.rend(); I != E; ++I) {
if (I->GVName == "") {
@@ -739,7 +463,7 @@ void MachOWriter::BufferSymbolAndStringTable() {
I->n_value += GVSection[GV]->addr;
if (GV && (GVOffset[GV] == -1))
GVOffset[GV] = index;
-
+
// Emit nlist to buffer
SymTOut.outword(I->n_strx);
SymTOut.outbyte(I->n_type);
@@ -754,6 +478,7 @@ void MachOWriter::BufferSymbolAndStringTable() {
/// and the offset into that section. From this information, create the
/// appropriate target-specific MachORelocation type and add buffer it to be
/// written out after we are finished writing out sections.
+
void MachOWriter::CalculateRelocations(MachOSection &MOS) {
for (unsigned i = 0, e = MOS.Relocations.size(); i != e; ++i) {
MachineRelocation &MR = MOS.Relocations[i];
@@ -763,19 +488,22 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) {
// This is a scattered relocation entry if it points to a global value with
// a non-zero offset.
+
bool Scattered = false;
bool Extern = false;
// Since we may not have seen the GlobalValue we were interested in yet at
// the time we emitted the relocation for it, fix it up now so that it
// points to the offset into the correct section.
+
if (MR.isGlobalValue()) {
GlobalValue *GV = MR.getGlobalValue();
MachOSection *MOSPtr = GVSection[GV];
intptr_t Offset = GVOffset[GV];
-
+
// If we have never seen the global before, it must be to a symbol
// defined in another module (N_UNDF).
+
if (!MOSPtr) {
// FIXME: need to append stub suffix
Extern = true;
@@ -787,9 +515,10 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) {
}
MR.setResultPointer((void*)Offset);
}
-
+
// If the symbol is locally defined, pass in the address of the section and
// the section index to the code which will generate the target relocation.
+
if (!Extern) {
MachOSection &To = *SectionList[TargetSection - 1];
TargetAddr = To.addr;
@@ -798,7 +527,7 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) {
OutputBuffer RelocOut(MOS.RelocBuffer, is64Bit, isLittleEndian);
OutputBuffer SecOut(MOS.SectionData, is64Bit, isLittleEndian);
-
+
MOS.nreloc += GetTargetRelocation(MR, MOS.Index, TargetAddr, TargetIndex,
RelocOut, SecOut, Scattered, Extern);
}
@@ -806,21 +535,22 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) {
// InitMem - Write the value of a Constant to the specified memory location,
// converting it into bytes and relocations.
+
void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
- const TargetData *TD,
+ const TargetData *TD,
std::vector<MachineRelocation> &MRs) {
typedef std::pair<const Constant*, intptr_t> CPair;
std::vector<CPair> WorkList;
-
+
WorkList.push_back(CPair(C,(intptr_t)Addr + Offset));
-
+
intptr_t ScatteredOffset = 0;
-
+
while (!WorkList.empty()) {
const Constant *PC = WorkList.back().first;
intptr_t PA = WorkList.back().second;
WorkList.pop_back();
-
+
if (isa<UndefValue>(PC)) {
continue;
} else if (const ConstantVector *CP = dyn_cast<ConstantVector>(PC)) {
@@ -847,7 +577,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
break;
}
} else if (PC->getType()->isSingleValueType()) {
- uint8_t *ptr = (uint8_t *)PA;
+ unsigned char *ptr = (unsigned char *)PA;
switch (PC->getType()->getTypeID()) {
case Type::IntegerTyID: {
unsigned NumBits = cast<IntegerType>(PC->getType())->getBitWidth();
@@ -945,13 +675,15 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset,
}
}
+//===----------------------------------------------------------------------===//
+// MachOSym Implementation
+//===----------------------------------------------------------------------===//
+
MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
- TargetMachine &TM) :
+ const TargetAsmInfo *TAI) :
GV(gv), n_strx(0), n_type(sect == NO_SECT ? N_UNDF : N_SECT), n_sect(sect),
n_desc(0), n_value(0) {
- const TargetAsmInfo *TAI = TM.getTargetAsmInfo();
-
switch (GV->getLinkage()) {
default:
assert(0 && "Unexpected linkage type!");
@@ -974,3 +706,6 @@ MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
break;
}
}
+
+} // end namespace llvm
+
diff --git a/lib/CodeGen/MachOWriter.h b/lib/CodeGen/MachOWriter.h
index 6ab66ee..3af2b0a 100644
--- a/lib/CodeGen/MachOWriter.h
+++ b/lib/CodeGen/MachOWriter.h
@@ -14,10 +14,8 @@
#ifndef MACHOWRITER_H
#define MACHOWRITER_H
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
+#include "MachO.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachOWriterInfo.h"
@@ -31,53 +29,6 @@ namespace llvm {
class OutputBuffer;
class raw_ostream;
- /// MachOSym - This struct contains information about each symbol that is
- /// added to logical symbol table for the module. This is eventually
- /// turned into a real symbol table in the file.
- struct MachOSym {
- const GlobalValue *GV; // The global value this corresponds to.
- std::string GVName; // The mangled name of the global value.
- uint32_t n_strx; // index into the string table
- uint8_t n_type; // type flag
- uint8_t n_sect; // section number or NO_SECT
- int16_t n_desc; // see <mach-o/stab.h>
- uint64_t n_value; // value for this symbol (or stab offset)
-
- // Constants for the n_sect field
- // see <mach-o/nlist.h>
- enum { NO_SECT = 0 }; // symbol is not in any section
-
- // Constants for the n_type field
- // see <mach-o/nlist.h>
- enum { N_UNDF = 0x0, // undefined, n_sect == NO_SECT
- N_ABS = 0x2, // absolute, n_sect == NO_SECT
- N_SECT = 0xe, // defined in section number n_sect
- N_PBUD = 0xc, // prebound undefined (defined in a dylib)
- N_INDR = 0xa // indirect
- };
- // The following bits are OR'd into the types above. For example, a type
- // of 0x0f would be an external N_SECT symbol (0x0e | 0x01).
- enum { N_EXT = 0x01, // external symbol bit
- N_PEXT = 0x10 // private external symbol bit
- };
-
- // Constants for the n_desc field
- // see <mach-o/loader.h>
- enum { REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
- REFERENCE_FLAG_UNDEFINED_LAZY = 1,
- REFERENCE_FLAG_DEFINED = 2,
- REFERENCE_FLAG_PRIVATE_DEFINED = 3,
- REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
- REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5
- };
- enum { N_NO_DEAD_STRIP = 0x0020, // symbol is not to be dead stripped
- N_WEAK_REF = 0x0040, // symbol is weak referenced
- N_WEAK_DEF = 0x0080 // coalesced symbol is a weak definition
- };
-
- MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
- TargetMachine &TM);
- };
/// MachOWriter - This class implements the common target-independent code for
/// writing Mach-O files. Targets should derive a class from this to
@@ -98,7 +49,6 @@ namespace llvm {
return "Mach-O Writer";
}
- typedef std::vector<uint8_t> DataBuffer;
protected:
/// Output stream to send the resultant object file to.
///
@@ -114,326 +64,61 @@ namespace llvm {
/// MCE - The MachineCodeEmitter object that we are exposing to emit machine
/// code for functions to the .o file.
+
MachOCodeEmitter *MCE;
/// is64Bit/isLittleEndian - This information is inferred from the target
/// machine directly, indicating what header values and flags to set.
- bool is64Bit, isLittleEndian;
- /// doInitialization - Emit the file header and all of the global variables
- /// for the module to the Mach-O file.
- bool doInitialization(Module &M);
+ bool is64Bit, isLittleEndian;
- bool runOnMachineFunction(MachineFunction &MF);
+ // Target Asm Info
- /// doFinalization - Now that the module has been completely processed, emit
- /// the Mach-O file to 'O'.
- bool doFinalization(Module &M);
+ const TargetAsmInfo *TAI;
- /// MachOHeader - This struct contains the header information about a
- /// specific architecture type/subtype pair that is emitted to the file.
- struct MachOHeader {
- uint32_t magic; // mach magic number identifier
- uint32_t filetype; // type of file
- uint32_t ncmds; // number of load commands
- uint32_t sizeofcmds; // the size of all the load commands
- uint32_t flags; // flags
- uint32_t reserved; // 64-bit only
-
- /// HeaderData - The actual data for the header which we are building
- /// up for emission to the file.
- DataBuffer HeaderData;
-
- // Constants for the filetype field
- // see <mach-o/loader.h> for additional info on the various types
- enum { MH_OBJECT = 1, // relocatable object file
- MH_EXECUTE = 2, // demand paged executable file
- MH_FVMLIB = 3, // fixed VM shared library file
- MH_CORE = 4, // core file
- MH_PRELOAD = 5, // preloaded executable file
- MH_DYLIB = 6, // dynamically bound shared library
- MH_DYLINKER = 7, // dynamic link editor
- MH_BUNDLE = 8, // dynamically bound bundle file
- MH_DYLIB_STUB = 9, // shared library stub for static linking only
- MH_DSYM = 10 // companion file wiht only debug sections
- };
-
- // Constants for the flags field
- enum { MH_NOUNDEFS = 1 << 0,
- // the object file has no undefined references
- MH_INCRLINK = 1 << 1,
- // the object file is the output of an incremental link against
- // a base file and cannot be link edited again
- MH_DYLDLINK = 1 << 2,
- // the object file is input for the dynamic linker and cannot be
- // statically link edited again.
- MH_BINDATLOAD = 1 << 3,
- // the object file's undefined references are bound by the
- // dynamic linker when loaded.
- MH_PREBOUND = 1 << 4,
- // the file has its dynamic undefined references prebound
- MH_SPLIT_SEGS = 1 << 5,
- // the file has its read-only and read-write segments split
- // see <mach/shared_memory_server.h>
- MH_LAZY_INIT = 1 << 6,
- // the shared library init routine is to be run lazily via
- // catching memory faults to its writable segments (obsolete)
- MH_TWOLEVEL = 1 << 7,
- // the image is using two-level namespace bindings
- MH_FORCE_FLAT = 1 << 8,
- // the executable is forcing all images to use flat namespace
- // bindings.
- MH_NOMULTIDEFS = 1 << 8,
- // this umbrella guarantees no multiple definitions of symbols
- // in its sub-images so the two-level namespace hints can
- // always be used.
- MH_NOFIXPREBINDING = 1 << 10,
- // do not have dyld notify the prebidning agent about this
- // executable.
- MH_PREBINDABLE = 1 << 11,
- // the binary is not prebound but can have its prebinding
- // redone. only used when MH_PREBOUND is not set.
- MH_ALLMODSBOUND = 1 << 12,
- // indicates that this binary binds to all two-level namespace
- // modules of its dependent libraries. Only used when
- // MH_PREBINDABLE and MH_TWOLEVEL are both set.
- MH_SUBSECTIONS_VIA_SYMBOLS = 1 << 13,
- // safe to divide up the sections into sub-sections via symbols
- // for dead code stripping.
- MH_CANONICAL = 1 << 14,
- // the binary has been canonicalized via the unprebind operation
- MH_WEAK_DEFINES = 1 << 15,
- // the final linked image contains external weak symbols
- MH_BINDS_TO_WEAK = 1 << 16,
- // the final linked image uses weak symbols
- MH_ALLOW_STACK_EXECUTION = 1 << 17
- // When this bit is set, all stacks in the task will be given
- // stack execution privilege. Only used in MH_EXECUTE filetype
- };
-
- MachOHeader() : magic(0), filetype(0), ncmds(0), sizeofcmds(0), flags(0),
- reserved(0) { }
-
- /// cmdSize - This routine returns the size of the MachOSection as written
- /// to disk, depending on whether the destination is a 64 bit Mach-O file.
- unsigned cmdSize(bool is64Bit) const {
- if (is64Bit)
- return 8 * sizeof(uint32_t);
- else
- return 7 * sizeof(uint32_t);
- }
-
- /// setMagic - This routine sets the appropriate value for the 'magic'
- /// field based on pointer size and endianness.
- void setMagic(bool isLittleEndian, bool is64Bit) {
- if (isLittleEndian)
- if (is64Bit) magic = 0xcffaedfe;
- else magic = 0xcefaedfe;
- else
- if (is64Bit) magic = 0xfeedfacf;
- else magic = 0xfeedface;
- }
- };
-
/// Header - An instance of MachOHeader that we will update while we build
/// the file, and then emit during finalization.
- MachOHeader Header;
- /// MachOSegment - This struct contains the necessary information to
- /// emit the load commands for each section in the file.
- struct MachOSegment {
- uint32_t cmd; // LC_SEGMENT or LC_SEGMENT_64
- uint32_t cmdsize; // Total size of this struct and section commands
- std::string segname; // segment name
- uint64_t vmaddr; // address of this segment
- uint64_t vmsize; // size of this segment, may be larger than filesize
- uint64_t fileoff; // offset in file
- uint64_t filesize; // amount to read from file
- uint32_t maxprot; // maximum VM protection
- uint32_t initprot; // initial VM protection
- uint32_t nsects; // number of sections in this segment
- uint32_t flags; // flags
-
- // The following constants are getting pulled in by one of the
- // system headers, which creates a neat clash with the enum.
-#if !defined(VM_PROT_NONE)
-#define VM_PROT_NONE 0x00
-#endif
-#if !defined(VM_PROT_READ)
-#define VM_PROT_READ 0x01
-#endif
-#if !defined(VM_PROT_WRITE)
-#define VM_PROT_WRITE 0x02
-#endif
-#if !defined(VM_PROT_EXECUTE)
-#define VM_PROT_EXECUTE 0x04
-#endif
-#if !defined(VM_PROT_ALL)
-#define VM_PROT_ALL 0x07
-#endif
-
- // Constants for the vm protection fields
- // see <mach-o/vm_prot.h>
- enum { SEG_VM_PROT_NONE = VM_PROT_NONE,
- SEG_VM_PROT_READ = VM_PROT_READ, // read permission
- SEG_VM_PROT_WRITE = VM_PROT_WRITE, // write permission
- SEG_VM_PROT_EXECUTE = VM_PROT_EXECUTE,
- SEG_VM_PROT_ALL = VM_PROT_ALL
- };
-
- // Constants for the cmd field
- // see <mach-o/loader.h>
- enum { LC_SEGMENT = 0x01, // segment of this file to be mapped
- LC_SEGMENT_64 = 0x19 // 64-bit segment of this file to be mapped
- };
-
- /// cmdSize - This routine returns the size of the MachOSection as written
- /// to disk, depending on whether the destination is a 64 bit Mach-O file.
- unsigned cmdSize(bool is64Bit) const {
- if (is64Bit)
- return 6 * sizeof(uint32_t) + 4 * sizeof(uint64_t) + 16;
- else
- return 10 * sizeof(uint32_t) + 16; // addresses only 32 bits
- }
+ MachOHeader Header;
- MachOSegment(const std::string &seg, bool is64Bit)
- : cmd(is64Bit ? LC_SEGMENT_64 : LC_SEGMENT), cmdsize(0), segname(seg),
- vmaddr(0), vmsize(0), fileoff(0), filesize(0), maxprot(VM_PROT_ALL),
- initprot(VM_PROT_ALL), nsects(0), flags(0) { }
- };
+ /// doInitialization - Emit the file header and all of the global variables
+ /// for the module to the Mach-O file.
- /// MachOSection - This struct contains information about each section in a
- /// particular segment that is emitted to the file. This is eventually
- /// turned into the SectionCommand in the load command for a particlar
- /// segment.
- struct MachOSection {
- std::string sectname; // name of this section,
- std::string segname; // segment this section goes in
- uint64_t addr; // memory address of this section
- uint64_t size; // size in bytes of this section
- uint32_t offset; // file offset of this section
- uint32_t align; // section alignment (power of 2)
- uint32_t reloff; // file offset of relocation entries
- uint32_t nreloc; // number of relocation entries
- uint32_t flags; // flags (section type and attributes)
- uint32_t reserved1; // reserved (for offset or index)
- uint32_t reserved2; // reserved (for count or sizeof)
- uint32_t reserved3; // reserved (64 bit only)
-
- /// A unique number for this section, which will be used to match symbols
- /// to the correct section.
- uint32_t Index;
-
- /// SectionData - The actual data for this section which we are building
- /// up for emission to the file.
- DataBuffer SectionData;
+ bool doInitialization(Module &M);
- /// RelocBuffer - A buffer to hold the mach-o relocations before we write
- /// them out at the appropriate location in the file.
- DataBuffer RelocBuffer;
-
- /// Relocations - The relocations that we have encountered so far in this
- /// section that we will need to convert to MachORelocation entries when
- /// the file is written.
- std::vector<MachineRelocation> Relocations;
-
- // Constants for the section types (low 8 bits of flags field)
- // see <mach-o/loader.h>
- enum { S_REGULAR = 0,
- // regular section
- S_ZEROFILL = 1,
- // zero fill on demand section
- S_CSTRING_LITERALS = 2,
- // section with only literal C strings
- S_4BYTE_LITERALS = 3,
- // section with only 4 byte literals
- S_8BYTE_LITERALS = 4,
- // section with only 8 byte literals
- S_LITERAL_POINTERS = 5,
- // section with only pointers to literals
- S_NON_LAZY_SYMBOL_POINTERS = 6,
- // section with only non-lazy symbol pointers
- S_LAZY_SYMBOL_POINTERS = 7,
- // section with only lazy symbol pointers
- S_SYMBOL_STUBS = 8,
- // section with only symbol stubs
- // byte size of stub in the reserved2 field
- S_MOD_INIT_FUNC_POINTERS = 9,
- // section with only function pointers for initialization
- S_MOD_TERM_FUNC_POINTERS = 10,
- // section with only function pointers for termination
- S_COALESCED = 11,
- // section contains symbols that are coalesced
- S_GB_ZEROFILL = 12,
- // zero fill on demand section (that can be larger than 4GB)
- S_INTERPOSING = 13,
- // section with only pairs of function pointers for interposing
- S_16BYTE_LITERALS = 14
- // section with only 16 byte literals
- };
-
- // Constants for the section flags (high 24 bits of flags field)
- // see <mach-o/loader.h>
- enum { S_ATTR_PURE_INSTRUCTIONS = 1 << 31,
- // section contains only true machine instructions
- S_ATTR_NO_TOC = 1 << 30,
- // section contains coalesced symbols that are not to be in a
- // ranlib table of contents
- S_ATTR_STRIP_STATIC_SYMS = 1 << 29,
- // ok to strip static symbols in this section in files with the
- // MY_DYLDLINK flag
- S_ATTR_NO_DEAD_STRIP = 1 << 28,
- // no dead stripping
- S_ATTR_LIVE_SUPPORT = 1 << 27,
- // blocks are live if they reference live blocks
- S_ATTR_SELF_MODIFYING_CODE = 1 << 26,
- // used with i386 code stubs written on by dyld
- S_ATTR_DEBUG = 1 << 25,
- // a debug section
- S_ATTR_SOME_INSTRUCTIONS = 1 << 10,
- // section contains some machine instructions
- S_ATTR_EXT_RELOC = 1 << 9,
- // section has external relocation entries
- S_ATTR_LOC_RELOC = 1 << 8
- // section has local relocation entries
- };
+ bool runOnMachineFunction(MachineFunction &MF);
- /// cmdSize - This routine returns the size of the MachOSection as written
- /// to disk, depending on whether the destination is a 64 bit Mach-O file.
- unsigned cmdSize(bool is64Bit) const {
- if (is64Bit)
- return 7 * sizeof(uint32_t) + 2 * sizeof(uint64_t) + 32;
- else
- return 9 * sizeof(uint32_t) + 32; // addresses only 32 bits
- }
+ /// doFinalization - Now that the module has been completely processed, emit
+ /// the Mach-O file to 'O'.
- MachOSection(const std::string &seg, const std::string &sect)
- : sectname(sect), segname(seg), addr(0), size(0), offset(0), align(2),
- reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0),
- reserved3(0) { }
- };
+ bool doFinalization(Module &M);
private:
/// SectionList - This is the list of sections that we have emitted to the
/// file. Once the file has been completely built, the segment load command
/// SectionCommands are constructed from this info.
+
std::vector<MachOSection*> SectionList;
/// SectionLookup - This is a mapping from section name to SectionList entry
+
std::map<std::string, MachOSection*> SectionLookup;
/// GVSection - This is a mapping from a GlobalValue to a MachOSection,
/// to aid in emitting relocations.
+
std::map<GlobalValue*, MachOSection*> GVSection;
/// GVOffset - This is a mapping from a GlobalValue to an offset from the
/// start of the section in which the GV resides, to aid in emitting
/// relocations.
+
std::map<GlobalValue*, intptr_t> GVOffset;
/// getSection - Return the section with the specified name, creating a new
/// section if one does not already exist.
+
MachOSection *getSection(const std::string &seg, const std::string &sect,
unsigned Flags = 0) {
MachOSection *MOS = SectionLookup[seg+sect];
@@ -511,63 +196,11 @@ namespace llvm {
nsyms(0), stroff(0), strsize(0) { }
};
- /// MachOSymTab - This struct contains information about the offsets and
- /// size of symbol table information.
- /// segment.
- struct MachODySymTab {
- uint32_t cmd; // LC_DYSYMTAB
- uint32_t cmdsize; // sizeof( MachODySymTab )
- uint32_t ilocalsym; // index to local symbols
- uint32_t nlocalsym; // number of local symbols
- uint32_t iextdefsym; // index to externally defined symbols
- uint32_t nextdefsym; // number of externally defined symbols
- uint32_t iundefsym; // index to undefined symbols
- uint32_t nundefsym; // number of undefined symbols
- uint32_t tocoff; // file offset to table of contents
- uint32_t ntoc; // number of entries in table of contents
- uint32_t modtaboff; // file offset to module table
- uint32_t nmodtab; // number of module table entries
- uint32_t extrefsymoff; // offset to referenced symbol table
- uint32_t nextrefsyms; // number of referenced symbol table entries
- uint32_t indirectsymoff; // file offset to the indirect symbol table
- uint32_t nindirectsyms; // number of indirect symbol table entries
- uint32_t extreloff; // offset to external relocation entries
- uint32_t nextrel; // number of external relocation entries
- uint32_t locreloff; // offset to local relocation entries
- uint32_t nlocrel; // number of local relocation entries
-
- // Constants for the cmd field
- // see <mach-o/loader.h>
- enum { LC_DYSYMTAB = 0x0B // dynamic link-edit symbol table info
- };
-
- MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)),
- ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0),
- iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0),
- nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0),
- nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) { }
- };
-
/// SymTab - The "stab" style symbol table information
MachOSymTab SymTab;
/// DySymTab - symbol table info for the dynamic link editor
MachODySymTab DySymTab;
- struct MachOSymCmp {
- // FIXME: this does not appear to be sorting 'f' after 'F'
- bool operator()(const MachOSym &LHS, const MachOSym &RHS) {
- return LHS.GVName < RHS.GVName;
- }
- };
-
- /// PartitionByLocal - Simple boolean predicate that returns true if Sym is
- /// a local symbol rather than an external symbol.
- static bool PartitionByLocal(const MachOSym &Sym);
-
- /// PartitionByDefined - Simple boolean predicate that returns true if Sym
- /// is defined in this module.
- static bool PartitionByDefined(const MachOSym &Sym);
-
protected:
/// SymbolTable - This is the list of symbols we have emitted to the file.
@@ -601,6 +234,7 @@ namespace llvm {
void EmitGlobal(GlobalVariable *GV);
void EmitHeaderAndLoadCommands();
void EmitSections();
+ void EmitRelocations();
void BufferSymbolAndStringTable();
void CalculateRelocations(MachOSection &MOS);
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index ee118de..8520888 100644
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -312,93 +312,6 @@ namespace {
static RegisterPass<RALinScan>
X("linearscan-regalloc", "Linear Scan Register Allocator");
-bool validateRegAlloc(MachineFunction *mf, LiveIntervals *lis,
- VirtRegMap *vrm) {
-
- MachineRegisterInfo *mri = &mf->getRegInfo();
- const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo();
- bool allocationValid = true;
-
-
- for (LiveIntervals::iterator itr = lis->begin(), end = lis->end();
- itr != end; ++itr) {
-
- LiveInterval *li = itr->second;
-
- if (TargetRegisterInfo::isPhysicalRegister(li->reg)) {
- continue;
- }
-
- if (vrm->hasPhys(li->reg)) {
- const TargetRegisterClass *trc = mri->getRegClass(li->reg);
-
- if (lis->hasInterval(vrm->getPhys(li->reg))) {
- if (li->overlaps(lis->getInterval(vrm->getPhys(li->reg)))) {
- std::cerr << "vreg " << li->reg << " overlaps its assigned preg "
- << vrm->getPhys(li->reg) << "(" << tri->getName(vrm->getPhys(li->reg)) << ")\n";
- }
- }
-
- TargetRegisterClass::iterator fReg =
- std::find(trc->allocation_order_begin(*mf), trc->allocation_order_end(*mf),
- vrm->getPhys(li->reg));
-
- if (fReg == trc->allocation_order_end(*mf)) {
- std::cerr << "preg " << vrm->getPhys(li->reg)
- << "(" << tri->getName(vrm->getPhys(li->reg)) << ") is not in the allocation set for vreg "
- << li->reg << "\n";
- allocationValid &= false;
- }
- }
- else {
- std::cerr << "No preg for vreg " << li->reg << "\n";
- // What about conflicting loads/stores?
- continue;
- }
-
- for (LiveIntervals::iterator itr2 = next(itr); itr2 != end; ++itr2) {
-
- LiveInterval *li2 = itr2->second;
-
- if (li2->empty())
- continue;
-
- if (TargetRegisterInfo::isPhysicalRegister(li2->reg)) {
- if (li->overlaps(*li2)) {
- if (vrm->getPhys(li->reg) == li2->reg ||
- tri->areAliases(vrm->getPhys(li->reg), li2->reg)) {
- std::cerr << "vreg " << li->reg << " overlaps preg "
- << li2->reg << "(" << tri->getName(li2->reg) << ") which aliases "
- << vrm->getPhys(li->reg) << "(" << tri->getName(vrm->getPhys(li->reg)) << ")\n";
- allocationValid &= false;
- }
- }
- }
- else {
-
- if (!vrm->hasPhys(li2->reg)) {
- continue;
- }
-
- if (li->overlaps(*li2)) {
- if (vrm->getPhys(li->reg) == vrm->getPhys(li2->reg) ||
- tri->areAliases(vrm->getPhys(li->reg), vrm->getPhys(li2->reg))) {
- std::cerr << "vreg " << li->reg << " (preg " << vrm->getPhys(li->reg)
- << ") overlaps vreg " << li2->reg << " (preg " << vrm->getPhys(li2->reg)
- << ") and " << vrm->getPhys(li->reg) << " aliases " << vrm->getPhys(li2->reg) << "\n";
- allocationValid &= false;
- }
- }
- }
- }
-
- }
-
- return allocationValid;
-
-}
-
-
void RALinScan::ComputeRelatedRegClasses() {
// First pass, add all reg classes to the union, and determine at least one
// reg class that each register is in.
@@ -526,10 +439,6 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) {
linearScan();
- if (NewSpillFramework) {
- bool allocValid = validateRegAlloc(mf_, li_, vrm_);
- }
-
// Rewrite spill code and update the PhysRegsUsed set.
rewriter_->runOnMachineFunction(*mf_, *vrm_, li_);
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index b4c8bc1..c31f622 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -411,9 +411,11 @@ static void InvalidateKill(unsigned Reg,
std::vector<MachineOperand*> &KillOps) {
if (RegKills[Reg]) {
KillOps[Reg]->setIsKill(false);
- KillOps[Reg] = NULL;
- RegKills.reset(Reg);
- for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) {
+ // KillOps[Reg] might be a def of a super-register.
+ unsigned KReg = KillOps[Reg]->getReg();
+ KillOps[KReg] = NULL;
+ RegKills.reset(KReg);
+ for (const unsigned *SR = TRI->getSubRegisters(KReg); *SR; ++SR) {
if (RegKills[*SR]) {
KillOps[*SR]->setIsKill(false);
KillOps[*SR] = NULL;
@@ -516,8 +518,18 @@ static void UpdateKills(MachineInstr &MI, const TargetRegisterInfo* TRI,
// That can't be right. Register is killed but not re-defined and it's
// being reused. Let's fix that.
KillOps[Reg]->setIsKill(false);
- KillOps[Reg] = NULL;
- RegKills.reset(Reg);
+ // KillOps[Reg] might be a def of a super-register.
+ unsigned KReg = KillOps[Reg]->getReg();
+ KillOps[KReg] = NULL;
+ RegKills.reset(KReg);
+
+ // Must be a def of a super-register. Its other sub-regsters are no
+ // longer killed as well.
+ for (const unsigned *SR = TRI->getSubRegisters(KReg); *SR; ++SR) {
+ KillOps[*SR] = NULL;
+ RegKills.reset(*SR);
+ }
+
if (!MI.isRegTiedToDefOperand(i))
// Unless it's a two-address operand, this is the new kill.
MO.setIsKill();
@@ -1090,6 +1102,8 @@ private:
VRM.RemoveMachineInstrFromMaps(&NextMI);
MBB.erase(&NextMI);
++NumModRefUnfold;
+ if (NextMII == MBB.end())
+ break;
} while (FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, VRM));
// Store the value back into SS.
diff --git a/lib/System/Atomic.cpp b/lib/System/Atomic.cpp
index cefd0bb..2827d88 100644
--- a/lib/System/Atomic.cpp
+++ b/lib/System/Atomic.cpp
@@ -50,4 +50,4 @@ sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
#else
# error No compare-and-swap implementation for your platform!
#endif
-} \ No newline at end of file
+}
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 047552f..09b8ce0 100644
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -697,7 +697,7 @@ bool ARMLoadStoreOpt::LoadStoreMultipleOpti(MachineBasicBlock &MBB) {
// LDM/STM ops.
for (unsigned i = 0, e = MBBII.size(); i < e; ++i)
if (mergeBaseUpdateLSMultiple(MBB, MBBII[i], Advance, MBBI))
- NumMerges++;
+ ++NumMerges;
NumMerges += MBBII.size();
// Try folding preceeding/trailing base inc/dec into those load/store
@@ -705,7 +705,7 @@ bool ARMLoadStoreOpt::LoadStoreMultipleOpti(MachineBasicBlock &MBB) {
for (unsigned i = 0; i != NumMemOps; ++i)
if (!MemOps[i].Merged)
if (mergeBaseUpdateLoadStore(MBB, MemOps[i].MBBI, TII,Advance,MBBI))
- NumMerges++;
+ ++NumMerges;
// RS may be pointing to an instruction that's deleted.
RS->skipTo(prior(MBBI));
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index b3667be..33332e4 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -321,7 +321,7 @@ bool X86FastISel::X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT,
/// X86SelectAddress - Attempt to fill in an address from the given value.
///
bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) {
- User *U;
+ User *U = NULL;
unsigned Opcode = Instruction::UserOp1;
if (Instruction *I = dyn_cast<Instruction>(V)) {
Opcode = I->getOpcode();
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp
index 342b1e5..42978e7 100644
--- a/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -624,8 +624,11 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
// Add in the base register.
if (AddrMode.BaseReg) {
Value *V = AddrMode.BaseReg;
- if (V->getType() != IntPtrTy)
+ if (isa<PointerType>(V->getType()))
V = new PtrToIntInst(V, IntPtrTy, "sunkaddr", InsertPt);
+ if (V->getType() != IntPtrTy)
+ V = CastInst::CreateIntegerCast(V, IntPtrTy, /*isSigned=*/true,
+ "sunkaddr", InsertPt);
if (Result)
Result = BinaryOperator::CreateAdd(Result, V, "sunkaddr", InsertPt);
else
diff --git a/test/Archive/GNU.a b/test/Archive/GNU.a
new file mode 100644
index 0000000..4c09881
--- /dev/null
+++ b/test/Archive/GNU.a
Binary files differ
diff --git a/test/Archive/IsNAN.o b/test/Archive/IsNAN.o
new file mode 100644
index 0000000..7b3a12a
--- /dev/null
+++ b/test/Archive/IsNAN.o
Binary files differ
diff --git a/test/Archive/MacOSX.a b/test/Archive/MacOSX.a
new file mode 100644
index 0000000..77f88a2
--- /dev/null
+++ b/test/Archive/MacOSX.a
Binary files differ
diff --git a/test/Archive/SVR4.a b/test/Archive/SVR4.a
new file mode 100644
index 0000000..3947813
--- /dev/null
+++ b/test/Archive/SVR4.a
Binary files differ
diff --git a/test/Archive/xpg4.a b/test/Archive/xpg4.a
new file mode 100644
index 0000000..b2bdb51
--- /dev/null
+++ b/test/Archive/xpg4.a
Binary files differ
diff --git a/test/CodeGen/ARM/str_pre-2.ll b/test/CodeGen/ARM/str_pre-2.ll
new file mode 100644
index 0000000..247465f
--- /dev/null
+++ b/test/CodeGen/ARM/str_pre-2.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -mtriple=arm-linux-gnu | grep {str.*\\!}
+; RUN: llvm-as < %s | llc -mtriple=arm-linux-gnu | grep {ldr.*\\\[.*\], #+4}
+; XFAIL: *
+
+@b = external global i64*
+
+define i64 @t(i64 %a) nounwind readonly {
+entry:
+ %0 = load i64** @b, align 4
+ %1 = load i64* %0, align 4
+ %2 = mul i64 %1, %a
+ ret i64 %2
+}
diff --git a/test/CodeGen/X86/2009-06-02-RewriterBug.ll b/test/CodeGen/X86/2009-06-02-RewriterBug.ll
new file mode 100644
index 0000000..ea33b16
--- /dev/null
+++ b/test/CodeGen/X86/2009-06-02-RewriterBug.ll
@@ -0,0 +1,362 @@
+; RUN: llvm-as < %s | llc -mtriple=x86_64-undermydesk-freebsd8.0 -relocation-model=pic -disable-fp-elim
+; PR4225
+
+define void @sha256_block1(i32* nocapture %arr, i8* nocapture %in, i64 %num) nounwind {
+entry:
+ br i1 undef, label %while.end, label %bb.nph
+
+bb.nph: ; preds = %entry
+ br label %while.body
+
+while.body: ; preds = %for.end, %bb.nph
+ %indvar2787 = phi i64 [ 0, %bb.nph ], [ %indvar.next2788, %for.end ] ; <i64> [#uses=2]
+ %tmp2791 = mul i64 %indvar2787, 44 ; <i64> [#uses=0]
+ %ctg22996 = getelementptr i8* %in, i64 0 ; <i8*> [#uses=1]
+ %conv = zext i32 undef to i64 ; <i64> [#uses=1]
+ %conv11 = zext i32 undef to i64 ; <i64> [#uses=1]
+ %tmp18 = load i32* undef ; <i32> [#uses=1]
+ %conv19 = zext i32 %tmp18 to i64 ; <i64> [#uses=1]
+ %tmp30 = load i32* undef ; <i32> [#uses=1]
+ %conv31 = zext i32 %tmp30 to i64 ; <i64> [#uses=4]
+ %ptrincdec3065 = load i8* null ; <i8> [#uses=1]
+ %conv442709 = zext i8 %ptrincdec3065 to i64 ; <i64> [#uses=1]
+ %shl45 = shl i64 %conv442709, 16 ; <i64> [#uses=1]
+ %conv632707 = zext i8 undef to i64 ; <i64> [#uses=1]
+ %or = or i64 %shl45, 0 ; <i64> [#uses=1]
+ %or55 = or i64 %or, %conv632707 ; <i64> [#uses=1]
+ %or64 = or i64 %or55, 0 ; <i64> [#uses=1]
+ %shr85 = lshr i64 %conv31, 25 ; <i64> [#uses=0]
+ %add = add i64 %conv11, 1508970993 ; <i64> [#uses=1]
+ %add95 = add i64 %add, 0 ; <i64> [#uses=1]
+ %add98 = add i64 %add95, 0 ; <i64> [#uses=1]
+ %add99 = add i64 %add98, %or64 ; <i64> [#uses=1]
+ %add134 = add i64 %add99, 0 ; <i64> [#uses=4]
+ store i32 undef, i32* undef
+ %shl187 = shl i64 %add134, 21 ; <i64> [#uses=0]
+ %and203 = and i64 %add134, %conv31 ; <i64> [#uses=1]
+ %xor208 = xor i64 0, %and203 ; <i64> [#uses=1]
+ %add212 = add i64 0, %xor208 ; <i64> [#uses=1]
+ %add213 = add i64 %add212, 0 ; <i64> [#uses=1]
+ %add248 = add i64 %add213, 0 ; <i64> [#uses=3]
+ %conv2852690 = zext i8 undef to i64 ; <i64> [#uses=1]
+ %or277 = or i64 0, %conv2852690 ; <i64> [#uses=1]
+ %or286 = or i64 %or277, 0 ; <i64> [#uses=1]
+ %neg319 = xor i64 %add248, 4294967295 ; <i64> [#uses=1]
+ %and321 = and i64 %neg319, %conv31 ; <i64> [#uses=1]
+ %xor322 = xor i64 %and321, 0 ; <i64> [#uses=1]
+ %add314 = add i64 %conv, 2870763221 ; <i64> [#uses=1]
+ %add323 = add i64 %add314, %or286 ; <i64> [#uses=1]
+ %add326 = add i64 %add323, %xor322 ; <i64> [#uses=1]
+ %add327 = add i64 %add326, 0 ; <i64> [#uses=2]
+ %add362 = add i64 %add327, %conv19 ; <i64> [#uses=4]
+ %add365 = add i64 0, %add327 ; <i64> [#uses=3]
+ %shl409 = shl i64 %add362, 26 ; <i64> [#uses=0]
+ %and431 = and i64 %add362, %add248 ; <i64> [#uses=1]
+ %neg433 = xor i64 %add362, -1 ; <i64> [#uses=1]
+ %and435 = and i64 %add134, %neg433 ; <i64> [#uses=1]
+ %xor436 = xor i64 %and431, %and435 ; <i64> [#uses=1]
+ %add428 = add i64 %conv31, 3624381080 ; <i64> [#uses=1]
+ %add437 = add i64 %add428, 0 ; <i64> [#uses=1]
+ %add440 = add i64 %add437, %xor436 ; <i64> [#uses=1]
+ %add441 = add i64 %add440, 0 ; <i64> [#uses=1]
+ %shl443 = shl i64 %add365, 30 ; <i64> [#uses=1]
+ %and445 = lshr i64 %add365, 2 ; <i64> [#uses=1]
+ %shr446 = and i64 %and445, 1073741823 ; <i64> [#uses=1]
+ %or447 = or i64 %shr446, %shl443 ; <i64> [#uses=1]
+ %xor461 = xor i64 0, %or447 ; <i64> [#uses=1]
+ %add473 = add i64 %xor461, 0 ; <i64> [#uses=1]
+ %add479 = add i64 %add473, %add441 ; <i64> [#uses=3]
+ %conv4932682 = zext i8 undef to i64 ; <i64> [#uses=1]
+ %shl494 = shl i64 %conv4932682, 16 ; <i64> [#uses=1]
+ %ptrincdec4903012 = load i8* null ; <i8> [#uses=1]
+ %conv5032681 = zext i8 %ptrincdec4903012 to i64 ; <i64> [#uses=1]
+ %shl504 = shl i64 %conv5032681, 8 ; <i64> [#uses=1]
+ %ptrincdec5003009 = load i8* null ; <i8> [#uses=1]
+ %conv5132680 = zext i8 %ptrincdec5003009 to i64 ; <i64> [#uses=1]
+ %or495 = or i64 %shl494, 0 ; <i64> [#uses=1]
+ %or505 = or i64 %or495, %conv5132680 ; <i64> [#uses=1]
+ %or514 = or i64 %or505, %shl504 ; <i64> [#uses=1]
+ store i32 undef, i32* undef
+ %or540 = or i64 undef, 0 ; <i64> [#uses=0]
+ %add542 = add i64 %add134, 310598401 ; <i64> [#uses=1]
+ %add551 = add i64 %add542, %or514 ; <i64> [#uses=1]
+ %add554 = add i64 %add551, 0 ; <i64> [#uses=1]
+ %add555 = add i64 %add554, 0 ; <i64> [#uses=1]
+ %or561 = or i64 undef, undef ; <i64> [#uses=1]
+ %or567 = or i64 undef, undef ; <i64> [#uses=1]
+ %and572 = lshr i64 %add479, 22 ; <i64> [#uses=1]
+ %shr573 = and i64 %and572, 1023 ; <i64> [#uses=1]
+ %or574 = or i64 %shr573, 0 ; <i64> [#uses=1]
+ %xor568 = xor i64 %or567, %or574 ; <i64> [#uses=1]
+ %xor575 = xor i64 %xor568, %or561 ; <i64> [#uses=1]
+ %add587 = add i64 %xor575, 0 ; <i64> [#uses=1]
+ %add593 = add i64 %add587, %add555 ; <i64> [#uses=1]
+ %ptrincdec6043000 = load i8* null ; <i8> [#uses=1]
+ %conv6172676 = zext i8 %ptrincdec6043000 to i64 ; <i64> [#uses=1]
+ %shl618 = shl i64 %conv6172676, 8 ; <i64> [#uses=1]
+ %ptrincdec6142997 = load i8* %ctg22996 ; <i8> [#uses=1]
+ %conv6272675 = zext i8 %ptrincdec6142997 to i64 ; <i64> [#uses=1]
+ %or619 = or i64 0, %conv6272675 ; <i64> [#uses=1]
+ %or628 = or i64 %or619, %shl618 ; <i64> [#uses=1]
+ %add656 = add i64 %add248, 607225278 ; <i64> [#uses=1]
+ %add665 = add i64 %add656, %or628 ; <i64> [#uses=1]
+ %add668 = add i64 %add665, 0 ; <i64> [#uses=1]
+ %add669 = add i64 %add668, 0 ; <i64> [#uses=1]
+ %and699 = and i64 %add479, %add365 ; <i64> [#uses=1]
+ %xor700 = xor i64 0, %and699 ; <i64> [#uses=1]
+ %add701 = add i64 0, %xor700 ; <i64> [#uses=1]
+ %add707 = add i64 %add701, %add669 ; <i64> [#uses=4]
+ %ptrincdec6242994 = load i8* null ; <i8> [#uses=1]
+ %conv7122673 = zext i8 %ptrincdec6242994 to i64 ; <i64> [#uses=1]
+ %shl713 = shl i64 %conv7122673, 24 ; <i64> [#uses=1]
+ %conv7412670 = zext i8 undef to i64 ; <i64> [#uses=1]
+ %or723 = or i64 0, %shl713 ; <i64> [#uses=1]
+ %or733 = or i64 %or723, %conv7412670 ; <i64> [#uses=1]
+ %or742 = or i64 %or733, 0 ; <i64> [#uses=2]
+ %conv743 = trunc i64 %or742 to i32 ; <i32> [#uses=1]
+ store i32 %conv743, i32* undef
+ %xor762 = xor i64 undef, 0 ; <i64> [#uses=0]
+ %add770 = add i64 %add362, 1426881987 ; <i64> [#uses=1]
+ %add779 = add i64 %add770, %or742 ; <i64> [#uses=1]
+ %add782 = add i64 %add779, 0 ; <i64> [#uses=1]
+ %add783 = add i64 %add782, 0 ; <i64> [#uses=1]
+ %shl785 = shl i64 %add707, 30 ; <i64> [#uses=1]
+ %and787 = lshr i64 %add707, 2 ; <i64> [#uses=1]
+ %shr788 = and i64 %and787, 1073741823 ; <i64> [#uses=1]
+ %or789 = or i64 %shr788, %shl785 ; <i64> [#uses=1]
+ %shl791 = shl i64 %add707, 19 ; <i64> [#uses=0]
+ %xor803 = xor i64 0, %or789 ; <i64> [#uses=1]
+ %and813 = and i64 %add593, %add479 ; <i64> [#uses=1]
+ %xor814 = xor i64 0, %and813 ; <i64> [#uses=1]
+ %add815 = add i64 %xor803, %xor814 ; <i64> [#uses=1]
+ %add821 = add i64 %add815, %add783 ; <i64> [#uses=1]
+ %add1160 = add i64 0, %add707 ; <i64> [#uses=0]
+ %add1157 = add i64 undef, undef ; <i64> [#uses=0]
+ %ptrincdec11742940 = load i8* null ; <i8> [#uses=1]
+ %conv11872651 = zext i8 %ptrincdec11742940 to i64 ; <i64> [#uses=1]
+ %shl1188 = shl i64 %conv11872651, 8 ; <i64> [#uses=1]
+ %or1198 = or i64 0, %shl1188 ; <i64> [#uses=1]
+ store i32 undef, i32* undef
+ %add1226 = add i64 %or1198, 3248222580 ; <i64> [#uses=1]
+ %add1235 = add i64 %add1226, 0 ; <i64> [#uses=1]
+ %add1238 = add i64 %add1235, 0 ; <i64> [#uses=1]
+ %add1239 = add i64 %add1238, 0 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %while.body
+ %add821.pn = phi i64 [ %add821, %while.body ], [ undef, %for.body ] ; <i64> [#uses=0]
+ %add1239.pn = phi i64 [ %add1239, %while.body ], [ 0, %for.body ] ; <i64> [#uses=0]
+ br i1 undef, label %for.end, label %for.body
+
+for.body: ; preds = %for.cond
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ %indvar.next2788 = add i64 %indvar2787, 1 ; <i64> [#uses=1]
+ br i1 undef, label %while.end, label %while.body
+
+while.end: ; preds = %for.end, %entry
+ ret void
+}
+
+define void @sha256_block2(i32* nocapture %arr, i8* nocapture %in, i64 %num) nounwind {
+entry:
+ br i1 undef, label %while.end, label %bb.nph
+
+bb.nph: ; preds = %entry
+ %arrayidx5 = getelementptr i32* %arr, i64 1 ; <i32*> [#uses=1]
+ %arrayidx9 = getelementptr i32* %arr, i64 2 ; <i32*> [#uses=2]
+ %arrayidx13 = getelementptr i32* %arr, i64 3 ; <i32*> [#uses=2]
+ %arrayidx25 = getelementptr i32* %arr, i64 6 ; <i32*> [#uses=1]
+ %arrayidx29 = getelementptr i32* %arr, i64 7 ; <i32*> [#uses=1]
+ br label %while.body
+
+while.body: ; preds = %for.end, %bb.nph
+ %tmp3 = load i32* %arr ; <i32> [#uses=2]
+ %conv = zext i32 %tmp3 to i64 ; <i64> [#uses=1]
+ %tmp10 = load i32* %arrayidx9 ; <i32> [#uses=1]
+ %conv11 = zext i32 %tmp10 to i64 ; <i64> [#uses=1]
+ %tmp14 = load i32* %arrayidx13 ; <i32> [#uses=3]
+ %conv15 = zext i32 %tmp14 to i64 ; <i64> [#uses=2]
+ %tmp18 = load i32* undef ; <i32> [#uses=2]
+ %conv19 = zext i32 %tmp18 to i64 ; <i64> [#uses=1]
+ %conv23 = zext i32 undef to i64 ; <i64> [#uses=1]
+ %tmp26 = load i32* %arrayidx25 ; <i32> [#uses=1]
+ %conv27 = zext i32 %tmp26 to i64 ; <i64> [#uses=1]
+ %tmp30 = load i32* %arrayidx29 ; <i32> [#uses=2]
+ %conv31 = zext i32 %tmp30 to i64 ; <i64> [#uses=5]
+ %shl72 = shl i64 %conv31, 26 ; <i64> [#uses=1]
+ %shr = lshr i64 %conv31, 6 ; <i64> [#uses=1]
+ %or74 = or i64 %shl72, %shr ; <i64> [#uses=1]
+ %shr85 = lshr i64 %conv31, 25 ; <i64> [#uses=0]
+ %xor87 = xor i64 0, %or74 ; <i64> [#uses=1]
+ %and902706 = and i32 %tmp30, %tmp3 ; <i32> [#uses=1]
+ %and90 = zext i32 %and902706 to i64 ; <i64> [#uses=1]
+ %xor94 = xor i64 0, %and90 ; <i64> [#uses=1]
+ %add = add i64 %conv11, 1508970993 ; <i64> [#uses=1]
+ %add95 = add i64 %add, %xor94 ; <i64> [#uses=1]
+ %add98 = add i64 %add95, %xor87 ; <i64> [#uses=1]
+ %add99 = add i64 %add98, 0 ; <i64> [#uses=2]
+ %xor130 = zext i32 undef to i64 ; <i64> [#uses=1]
+ %add134 = add i64 %add99, %conv27 ; <i64> [#uses=2]
+ %add131 = add i64 %xor130, 0 ; <i64> [#uses=1]
+ %add137 = add i64 %add131, %add99 ; <i64> [#uses=5]
+ %conv1422700 = zext i8 undef to i64 ; <i64> [#uses=1]
+ %shl143 = shl i64 %conv1422700, 24 ; <i64> [#uses=1]
+ %ptrincdec1393051 = load i8* undef ; <i8> [#uses=1]
+ %conv1512699 = zext i8 %ptrincdec1393051 to i64 ; <i64> [#uses=1]
+ %shl152 = shl i64 %conv1512699, 16 ; <i64> [#uses=1]
+ %conv1712697 = zext i8 undef to i64 ; <i64> [#uses=1]
+ %or153 = or i64 %shl152, %shl143 ; <i64> [#uses=1]
+ %or163 = or i64 %or153, %conv1712697 ; <i64> [#uses=1]
+ %or172 = or i64 %or163, 0 ; <i64> [#uses=1]
+ %and203 = and i64 %add134, %conv31 ; <i64> [#uses=1]
+ %xor208 = xor i64 0, %and203 ; <i64> [#uses=1]
+ %add200 = add i64 0, 2453635748 ; <i64> [#uses=1]
+ %add209 = add i64 %add200, %or172 ; <i64> [#uses=1]
+ %add212 = add i64 %add209, %xor208 ; <i64> [#uses=1]
+ %add213 = add i64 %add212, 0 ; <i64> [#uses=2]
+ %shl228 = shl i64 %add137, 10 ; <i64> [#uses=1]
+ %and230 = lshr i64 %add137, 22 ; <i64> [#uses=1]
+ %shr231 = and i64 %and230, 1023 ; <i64> [#uses=1]
+ %or232 = or i64 %shr231, %shl228 ; <i64> [#uses=1]
+ %xor226 = xor i64 0, %or232 ; <i64> [#uses=1]
+ %xor233 = xor i64 %xor226, 0 ; <i64> [#uses=1]
+ %and2362695 = zext i32 undef to i64 ; <i64> [#uses=1]
+ %xor240 = and i64 %add137, %and2362695 ; <i64> [#uses=1]
+ %and2432694 = and i32 %tmp18, %tmp14 ; <i32> [#uses=1]
+ %and243 = zext i32 %and2432694 to i64 ; <i64> [#uses=1]
+ %xor244 = xor i64 %xor240, %and243 ; <i64> [#uses=1]
+ %add248 = add i64 %add213, %conv23 ; <i64> [#uses=2]
+ %add245 = add i64 %xor233, %xor244 ; <i64> [#uses=1]
+ %add251 = add i64 %add245, %add213 ; <i64> [#uses=1]
+ %conv2752691 = zext i8 undef to i64 ; <i64> [#uses=1]
+ %shl276 = shl i64 %conv2752691, 8 ; <i64> [#uses=0]
+ %and317 = and i64 %add248, %add134 ; <i64> [#uses=1]
+ %neg319 = xor i64 %add248, 4294967295 ; <i64> [#uses=1]
+ %and321 = and i64 %neg319, %conv31 ; <i64> [#uses=1]
+ %xor322 = xor i64 %and321, %and317 ; <i64> [#uses=1]
+ %add314 = add i64 %conv, 2870763221 ; <i64> [#uses=1]
+ %add323 = add i64 %add314, 0 ; <i64> [#uses=1]
+ %add326 = add i64 %add323, %xor322 ; <i64> [#uses=1]
+ %add327 = add i64 %add326, 0 ; <i64> [#uses=2]
+ %and3502689 = xor i64 %add137, %conv15 ; <i64> [#uses=1]
+ %xor354 = and i64 %add251, %and3502689 ; <i64> [#uses=1]
+ %and357 = and i64 %add137, %conv15 ; <i64> [#uses=1]
+ %xor358 = xor i64 %xor354, %and357 ; <i64> [#uses=1]
+ %add362 = add i64 %add327, %conv19 ; <i64> [#uses=1]
+ %add359 = add i64 0, %xor358 ; <i64> [#uses=1]
+ %add365 = add i64 %add359, %add327 ; <i64> [#uses=1]
+ %add770 = add i64 %add362, 1426881987 ; <i64> [#uses=1]
+ %add779 = add i64 %add770, 0 ; <i64> [#uses=1]
+ %add782 = add i64 %add779, 0 ; <i64> [#uses=1]
+ %add783 = add i64 %add782, 0 ; <i64> [#uses=2]
+ %add818 = add i64 %add783, %add365 ; <i64> [#uses=1]
+ %add821 = add i64 0, %add783 ; <i64> [#uses=1]
+ store i32 undef, i32* undef
+ %add1046 = add i64 undef, undef ; <i64> [#uses=1]
+ %add1160 = add i64 undef, undef ; <i64> [#uses=1]
+ store i32 0, i32* undef
+ %add1235 = add i64 0, %add818 ; <i64> [#uses=1]
+ %add1238 = add i64 %add1235, 0 ; <i64> [#uses=1]
+ %add1239 = add i64 %add1238, 0 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %while.body
+ %h.0 = phi i64 [ undef, %while.body ], [ %add2035, %for.body ] ; <i64> [#uses=1]
+ %g.0 = phi i64 [ %add1046, %while.body ], [ undef, %for.body ] ; <i64> [#uses=1]
+ %f.0 = phi i64 [ %add1160, %while.body ], [ undef, %for.body ] ; <i64> [#uses=1]
+ %add821.pn = phi i64 [ %add821, %while.body ], [ undef, %for.body ] ; <i64> [#uses=0]
+ %add1239.pn2648 = phi i64 [ %add1239, %while.body ], [ undef, %for.body ] ; <i64> [#uses=0]
+ %d.0 = phi i64 [ undef, %while.body ], [ %add2038, %for.body ] ; <i64> [#uses=2]
+ br i1 undef, label %for.end, label %for.body
+
+for.body: ; preds = %for.cond
+ %conv1390 = zext i32 undef to i64 ; <i64> [#uses=1]
+ %add1375 = add i64 0, %h.0 ; <i64> [#uses=1]
+ %add1384 = add i64 %add1375, 0 ; <i64> [#uses=1]
+ %add1391 = add i64 %add1384, %conv1390 ; <i64> [#uses=1]
+ %add1392 = add i64 %add1391, 0 ; <i64> [#uses=2]
+ %or1411 = or i64 0, undef ; <i64> [#uses=1]
+ %xor1405 = xor i64 0, %or1411 ; <i64> [#uses=1]
+ %xor1412 = xor i64 %xor1405, 0 ; <i64> [#uses=1]
+ %add1427 = add i64 %add1392, %d.0 ; <i64> [#uses=1]
+ %add1424 = add i64 %xor1412, 0 ; <i64> [#uses=1]
+ %add1430 = add i64 %add1424, %add1392 ; <i64> [#uses=5]
+ %tmp1438 = load i32* undef ; <i32> [#uses=1]
+ %conv1439 = zext i32 %tmp1438 to i64 ; <i64> [#uses=4]
+ %shl1441 = shl i64 %conv1439, 25 ; <i64> [#uses=1]
+ %shr1444 = lshr i64 %conv1439, 7 ; <i64> [#uses=1]
+ %or1445 = or i64 %shl1441, %shr1444 ; <i64> [#uses=1]
+ %shr1450 = lshr i64 %conv1439, 18 ; <i64> [#uses=1]
+ %or1451 = or i64 0, %shr1450 ; <i64> [#uses=1]
+ %shr1454 = lshr i64 %conv1439, 3 ; <i64> [#uses=1]
+ %xor1452 = xor i64 %or1451, %shr1454 ; <i64> [#uses=1]
+ %xor1455 = xor i64 %xor1452, %or1445 ; <i64> [#uses=1]
+ %conv1464 = zext i32 undef to i64 ; <i64> [#uses=4]
+ %shl1466 = shl i64 %conv1464, 15 ; <i64> [#uses=1]
+ %shr1469 = lshr i64 %conv1464, 17 ; <i64> [#uses=1]
+ %or1470 = or i64 %shl1466, %shr1469 ; <i64> [#uses=1]
+ %shr1475 = lshr i64 %conv1464, 19 ; <i64> [#uses=1]
+ %or1476 = or i64 0, %shr1475 ; <i64> [#uses=1]
+ %shr1479 = lshr i64 %conv1464, 10 ; <i64> [#uses=1]
+ %xor1477 = xor i64 %or1476, %shr1479 ; <i64> [#uses=1]
+ %xor1480 = xor i64 %xor1477, %or1470 ; <i64> [#uses=1]
+ %tmp1499 = load i32* null ; <i32> [#uses=1]
+ %conv1500 = zext i32 %tmp1499 to i64 ; <i64> [#uses=1]
+ %add1491 = add i64 %conv1500, 0 ; <i64> [#uses=1]
+ %add1501 = add i64 %add1491, %xor1455 ; <i64> [#uses=1]
+ %add1502 = add i64 %add1501, %xor1480 ; <i64> [#uses=1]
+ %conv1504 = and i64 %add1502, 4294967295 ; <i64> [#uses=1]
+ %tmp1541 = load i32* undef ; <i32> [#uses=1]
+ %conv1542 = zext i32 %tmp1541 to i64 ; <i64> [#uses=1]
+ %add1527 = add i64 %conv1542, %g.0 ; <i64> [#uses=1]
+ %add1536 = add i64 %add1527, 0 ; <i64> [#uses=1]
+ %add1543 = add i64 %add1536, %conv1504 ; <i64> [#uses=1]
+ %add1544 = add i64 %add1543, 0 ; <i64> [#uses=1]
+ %shl1546 = shl i64 %add1430, 30 ; <i64> [#uses=1]
+ %and1548 = lshr i64 %add1430, 2 ; <i64> [#uses=1]
+ %shr1549 = and i64 %and1548, 1073741823 ; <i64> [#uses=1]
+ %or1550 = or i64 %shr1549, %shl1546 ; <i64> [#uses=1]
+ %shl1552 = shl i64 %add1430, 19 ; <i64> [#uses=1]
+ %or1556 = or i64 0, %shl1552 ; <i64> [#uses=1]
+ %shl1559 = shl i64 %add1430, 10 ; <i64> [#uses=1]
+ %or1563 = or i64 0, %shl1559 ; <i64> [#uses=1]
+ %xor1557 = xor i64 %or1556, %or1563 ; <i64> [#uses=1]
+ %xor1564 = xor i64 %xor1557, %or1550 ; <i64> [#uses=1]
+ %add1576 = add i64 %xor1564, 0 ; <i64> [#uses=1]
+ %add1582 = add i64 %add1576, %add1544 ; <i64> [#uses=3]
+ store i32 undef, i32* undef
+ %tmp1693 = load i32* undef ; <i32> [#uses=1]
+ %conv1694 = zext i32 %tmp1693 to i64 ; <i64> [#uses=1]
+ %add1679 = add i64 %conv1694, %f.0 ; <i64> [#uses=1]
+ %add1688 = add i64 %add1679, 0 ; <i64> [#uses=1]
+ %add1695 = add i64 %add1688, 0 ; <i64> [#uses=1]
+ %add1696 = add i64 %add1695, 0 ; <i64> [#uses=1]
+ %shl1698 = shl i64 %add1582, 30 ; <i64> [#uses=0]
+ %shl1704 = shl i64 %add1582, 19 ; <i64> [#uses=0]
+ %add1734 = add i64 0, %add1696 ; <i64> [#uses=1]
+ %add1983 = add i64 0, %add1427 ; <i64> [#uses=1]
+ %add1992 = add i64 %add1983, 0 ; <i64> [#uses=1]
+ %add1999 = add i64 %add1992, 0 ; <i64> [#uses=1]
+ %add2000 = add i64 %add1999, 0 ; <i64> [#uses=2]
+ %and2030 = and i64 %add1734, %add1582 ; <i64> [#uses=1]
+ %xor2031 = xor i64 0, %and2030 ; <i64> [#uses=1]
+ %add2035 = add i64 %add2000, %add1430 ; <i64> [#uses=1]
+ %add2032 = add i64 0, %xor2031 ; <i64> [#uses=1]
+ %add2038 = add i64 %add2032, %add2000 ; <i64> [#uses=1]
+ store i32 0, i32* undef
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ store i32 undef, i32* %arrayidx5
+ store i32 undef, i32* %arrayidx9
+ %d.02641 = trunc i64 %d.0 to i32 ; <i32> [#uses=1]
+ %conv2524 = add i32 %tmp14, %d.02641 ; <i32> [#uses=1]
+ store i32 %conv2524, i32* %arrayidx13
+ %exitcond2789 = icmp eq i64 undef, %num ; <i1> [#uses=1]
+ br i1 %exitcond2789, label %while.end, label %while.body
+
+while.end: ; preds = %for.end, %entry
+ ret void
+}
diff --git a/test/CodeGen/X86/codegen-prepare-cast.ll b/test/CodeGen/X86/codegen-prepare-cast.ll
new file mode 100644
index 0000000..ae3eb5f
--- /dev/null
+++ b/test/CodeGen/X86/codegen-prepare-cast.ll
@@ -0,0 +1,24 @@
+; RUN: llvm-as < %s | llc -march=x86-64
+; PR4297
+
+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-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+ %"byte[]" = type { i64, i8* }
+ %"char[][]" = type { i64, %"byte[]"* }
+@.str = external constant [7 x i8] ; <[7 x i8]*> [#uses=1]
+
+define fastcc i32 @_Dmain(%"char[][]" %unnamed) {
+entry:
+ %tmp = getelementptr [7 x i8]* @.str, i32 0, i32 0 ; <i8*> [#uses=1]
+ br i1 undef, label %foreachbody, label %foreachend
+
+foreachbody: ; preds = %entry
+ %tmp4 = getelementptr i8* %tmp, i32 undef ; <i8*> [#uses=1]
+ %tmp5 = load i8* %tmp4 ; <i8> [#uses=0]
+ unreachable
+
+foreachend: ; preds = %entry
+ ret i32 0
+}
+
diff --git a/test/CodeGen/X86/x86-store-gv-addr.ll b/test/CodeGen/X86/x86-store-gv-addr.ll
new file mode 100644
index 0000000..799340d
--- /dev/null
+++ b/test/CodeGen/X86/x86-store-gv-addr.ll
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin -relocation-model=static | not grep lea
+; RUN: llvm-as < %s | llc -mtriple=x86_64-pc-linux-gnu -relocation-model=static | not grep lea
+
+@v = external global i32, align 8
+@v_addr = external global i32*, align 8
+
+define void @t() nounwind optsize {
+ store i32* @v, i32** @v_addr, align 8
+ unreachable
+}
diff --git a/utils/NewNightlyTest.pl b/utils/NewNightlyTest.pl
index 9672632..a40b3f1 100755
--- a/utils/NewNightlyTest.pl
+++ b/utils/NewNightlyTest.pl
@@ -22,10 +22,7 @@ use Socket;
# -noremoveresults Do not remove the WEBDIR after it has been built.
# -nobuild Do not build llvm. If tests are enabled perform them
# on the llvm build specified in the build directory
-# -notest Do not even attempt to run the test programs. Implies
-# -norunningtests.
-# -norunningtests Do not run the Olden benchmark suite with
-# LARGE_PROBLEM_SIZE enabled.
+# -notest Do not even attempt to run the test programs.
# -nodejagnu Do not run feature or regression tests
# -parallel Run parallel jobs with GNU Make (see -parallel-jobs).
# -parallel-jobs The number of parallel Make jobs to use (default is two).
@@ -128,7 +125,6 @@ $CONFIGUREARGS="";
$nickname="";
$NOTEST=0;
$USESVN=1;
-$NORUNNINGTESTS=0;
$MAKECMD="make";
$SUBMITSERVER = "llvm.org";
$SUBMITSCRIPT = "/nightlytest/NightlyTestAccept.php";
@@ -145,8 +141,8 @@ while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
if (/^-nocvsstats$/) { $NOCVSSTATS = 1; next; }
if (/^-noremove$/) { $NOREMOVE = 1; next; }
if (/^-noremoveresults$/){ $NOREMOVERESULTS = 1; next; }
- if (/^-notest$/) { $NOTEST = 1; $NORUNNINGTESTS = 1; next; }
- if (/^-norunningtests$/) { $NORUNNINGTESTS = 1; next; }
+ if (/^-notest$/) { $NOTEST = 1; next; }
+ if (/^-norunningtests$/) { next; } # Backward compatibility, ignored.
if (/^-parallel-jobs$/) { $PARALLELJOBS = "$ARGV[0]"; shift; next;}
if (/^-parallel$/) { $MAKEOPTS = "$MAKEOPTS -j$PARALLELJOBS -l3.0"; next; }
if (/^-release$/) { $MAKEOPTS = "$MAKEOPTS ENABLE_OPTIMIZED=1 ".
@@ -252,7 +248,6 @@ if ($BUILDTYPE ne "release" && $BUILDTYPE ne "release-asserts") {
my $Prefix = "$WebDir/$DATE";
my $BuildLog = "$Prefix-Build-Log.txt";
my $COLog = "$Prefix-CVS-Log.txt";
-my $OldenTestsLog = "$Prefix-Olden-tests.txt";
my $SingleSourceLog = "$Prefix-SingleSource-ProgramTest.txt.gz";
my $MultiSourceLog = "$Prefix-MultiSource-ProgramTest.txt.gz";
my $ExternalLog = "$Prefix-External-ProgramTest.txt.gz";
@@ -1006,38 +1001,6 @@ if (!$BuildError) {
} #end if !$BuildError
-
-##############################################################
-#
-# If we built the tree successfully, runs of the Olden suite with
-# LARGE_PROBLEM_SIZE on so that we can get some "running" statistics.
-#
-##############################################################
-if (!$BuildError) {
- if ( $VERBOSE ) { print "OLDEN TEST SUITE STAGE\n"; }
- my ($NATTime, $CBETime, $LLCTime, $JITTime, $OptTime, $BytecodeSize,
- $MachCodeSize) = ("","","","","","","");
- if (!$NORUNNINGTESTS) {
- ChangeDir( "$BuildDir/llvm/projects/llvm-test/MultiSource/Benchmarks/Olden",
- "Olden Test Directory");
-
- # Clean out previous results...
- system "$NICE $MAKECMD $MAKEOPTS clean > /dev/null 2>&1";
-
- # Run the nightly test in this directory, with LARGE_PROBLEM_SIZE and
- # GET_STABLE_NUMBERS enabled!
- if( $VERBOSE ) {
- print "$MAKECMD -k $MAKEOPTS $PROGTESTOPTS report.nightly.csv.out " .
- "TEST=nightly LARGE_PROBLEM_SIZE=1 GET_STABLE_NUMBERS=1 " .
- "> /dev/null 2>&1\n";
- }
- system "$MAKECMD -k $MAKEOPTS $PROGTESTOPTS report.nightly.csv.out " .
- "TEST=nightly LARGE_PROBLEM_SIZE=1 GET_STABLE_NUMBERS=1 " .
- "> /dev/null 2>&1";
- system "cp report.nightly.csv $OldenTestsLog";
- }
-}
-
##############################################################
#
# Getting end timestamp
OpenPOWER on IntegriCloud