public:
virtual ~TargetJITInfo() {}
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast code generator for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM) = 0;
-
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
/// overwriting OLD with a branch to NEW. This is used for self-modifying
//
//===----------------------------------------------------------------------===//
//
-// This file describes the general parts of a Target machine.
+// This file defines the TargetMachine and LLVMTargetMachine classes.
//
//===----------------------------------------------------------------------===//
/// through this interface.
///
class TargetMachine {
- TargetMachine(const TargetMachine&); // DO NOT IMPLEMENT
- void operator=(const TargetMachine&); // DO NOT IMPLEMENT
+ TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT
+ void operator=(const TargetMachine &); // DO NOT IMPLEMENT
protected: // Can only create subclasses.
TargetMachine() { }
/// code as fast as possible, without regard for compile time. This method
/// should return true if emission of this file type is not supported.
///
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
+ virtual bool addPassesToEmitFile(FunctionPassManager &PM, std::ostream &Out,
CodeGenFileType FileType, bool Fast) {
return true;
}
+
+ /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+ /// get machine code emitted. This uses a MachineCodeEmitter object to handle
+ /// actually outputting the machine code and resolving things like the address
+ /// of functions. This method returns true if machine code emission is
+ /// not supported.
+ ///
+ virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
+ MachineCodeEmitter &MCE, bool Fast) {
+ return true;
+ }
+
+ /// addPassesToEmitWholeFile - This method can be implemented by targets that
+ /// require having the entire module at once. This is not recommended, do not
+ /// use this.
+ virtual bool WantsWholeFile() const { return false; }
+ virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
+ CodeGenFileType FileType, bool Fast) {
+ return true;
+ }
+};
+
+/// LLVMTargetMachine - This class describes a target machine that is
+/// implemented with the LLVM target-independent code generator.
+///
+class LLVMTargetMachine : public TargetMachine {
+protected: // Can only create subclasses.
+ LLVMTargetMachine() { }
+public:
+
+ /// addPassesToEmitFile - Add passes to the specified pass manager to get
+ /// the specified file emitted. Typically this will involve several steps of
+ /// code generation. If Fast is set to true, the code generator should emit
+ /// code as fast as possible, without regard for compile time. This method
+ /// should return true if emission of this file type is not supported.
+ ///
+ /// The default implementation of this method adds components from the
+ /// LLVM retargetable code generator, invoking the methods below to get
+ /// target-specific passes in standard locations.
+ ///
+ virtual bool addPassesToEmitFile(FunctionPassManager &PM, std::ostream &Out,
+ CodeGenFileType FileType, bool Fast);
+
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted. This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
- /// of functions. This method should returns true if machine code emission is
+ /// of functions. This method returns true if machine code emission is
/// not supported.
///
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
+ MachineCodeEmitter &MCE, bool Fast);
+
+ /// Target-Independent Code Generator Pass Configuration Options.
+
+ /// addInstSelector - This method should add any "last minute" LLVM->LLVM
+ /// passes, then install an instruction selector pass, which converts from
+ /// LLVM code to machine instructions.
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast) {
+ return true;
+ }
+
+ /// addPostRegAllocPasses - This method may be implemented by targets that
+ /// want to run passes after register allocation but before prolog-epilog
+ /// insertion. This should return true if -print-machineinstrs should print
+ /// after these passes.
+ virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
+ return false;
+ }
+
+ /// addPreEmitPass - This pass may be implemented by targets that want to run
+ /// passes immediately before machine code is emitted. This should return
+ /// true if -print-machineinstrs should print out the code after the passes.
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast) {
+ return false;
+ }
+
+
+ /// addAssemblyEmitter - This pass should be overridden by the target to add
+ /// the asmprinter, if asm emission is supported. If this is not supported,
+ /// 'true' should be returned.
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ return true;
+ }
+
+ /// addObjectWriter - This pass should be overridden by the target to add
+ /// the object-file writer, if supported. If this is not supported,
+ /// 'true' should be returned.
+ virtual bool addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ return true;
+ }
+
+ /// addCodeEmitter - This pass should be overridden by the target to add a
+ /// code emitter, if supported. If this is not supported, 'true' should be
+ /// returned.
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
return true;
}
};
// Add target data
MutexGuard locked(lock);
- FunctionPassManager& PM = state.getPM(locked);
+ FunctionPassManager &PM = state.getPM(locked);
PM.add(new TargetData(*TM.getTargetData()));
- // Compile LLVM Code down to machine code in the intermediate representation
- TJI.addPassesToJITCompile(PM);
-
// Turn the machine code intermediate representation into bytes in memory that
// may be executed.
- if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
+ if (TM.addPassesToEmitMachineCode(PM, *MCE, false /*fast*/)) {
std::cerr << "Target does not support machine code emission!\n";
abort();
}
+
+ // Initialize passes.
+ PM.doInitialization();
}
JIT::~JIT() {
#include "ARMTargetMachine.h"
#include "ARMFrameInfo.h"
#include "ARM.h"
-#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include <iostream>
using namespace llvm;
namespace {
return 0;
}
-/// addPassesToEmitFile - Add passes to the specified pass manager
-/// to implement a static compiler for this target.
-///
-bool ARMTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile)
- return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast)
- PM.add(createLoopStrengthReducePass());
-
- if (!Fast)
- PM.add(createCFGSimplificationPass());
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Print LLVM code input to instruction selector:
- if (PrintMachineCode)
- PM.add(new PrintFunctionPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+// Pass Pipeline Configuration
+bool ARMTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createARMISelDag(*this));
-
- // Print machine instructions as they were initially generated.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Print machine instructions after register allocation and prolog/epilog
- // insertion.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+ return false;
+}
+bool ARMTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
// Output assembly language.
PM.add(createARMCodePrinterPass(Out, *this));
-
- // Delete the MachineInstrs we generated, since they're no longer needed.
- PM.add(createMachineCodeDeleter());
return false;
}
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "ARMInstrInfo.h"
#include "ARMFrameInfo.h"
class Module;
-class ARMTargetMachine : public TargetMachine {
+class ARMTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
ARMInstrInfo InstrInfo;
ARMFrameInfo FrameInfo;
virtual const TargetData *getTargetData() const { return &DataLayout; }
static unsigned getModuleMatchQuality(const Module &M);
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
};
} // end namespace llvm
AlphaJITInfo(TargetMachine &tm) : TM(tm)
{ useGOT = true; }
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast dynamic compiler for this target. Return true if this
- /// is not supported for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM);
-
virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
virtual void relocate(void *Function, MachineRelocation *MR,
#include "AlphaJITInfo.h"
#include "AlphaTargetMachine.h"
#include "llvm/Module.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
+#include "llvm/PassManager.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/Debug.h"
-#include <iostream>
using namespace llvm;
: DataLayout("e"),
FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
JITInfo(*this),
- Subtarget(M, FS)
-{
- DEBUG(std::cerr << "FS is " << FS << "\n");
+ Subtarget(M, FS) {
}
-/// addPassesToEmitFile - Add passes to the specified pass manager to implement
-/// a static compiler for this target.
-///
-bool AlphaTargetMachine::addPassesToEmitFile(PassManager &PM,
- std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile) return true;
- PM.add(createLoopStrengthReducePass());
- PM.add(createCFGSimplificationPass());
-
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
+bool AlphaTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createAlphaISelDag(*this));
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createPrologEpilogCodeInserter());
-
- // Must run branch selection immediately preceding the asm printer
- //PM.add(createAlphaBranchSelectionPass());
-
- PM.add(createAlphaCodePrinterPass(Out, *this));
-
- PM.add(createMachineCodeDeleter());
return false;
}
-
-void AlphaJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
-
- PM.add(createLoopStrengthReducePass());
- PM.add(createCFGSimplificationPass());
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- PM.add(createAlphaISelDag(TM));
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createPrologEpilogCodeInserter());
-
+bool AlphaTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
// Must run branch selection immediately preceding the asm printer
//PM.add(createAlphaBranchSelectionPass());
-
+ return false;
}
-
-bool AlphaTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
+bool AlphaTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createAlphaCodePrinterPass(Out, *this));
+ return false;
+}
+bool AlphaTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
PM.add(createAlphaCodeEmitterPass(*this, MCE));
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
return false;
}
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "AlphaInstrInfo.h"
#include "AlphaJITInfo.h"
#include "AlphaSubtarget.h"
class GlobalValue;
-class AlphaTargetMachine : public TargetMachine {
+class AlphaTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
AlphaInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
}
static unsigned getJITMatchQuality();
-
- virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE);
-
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
-
static unsigned getModuleMatchQuality(const Module &M);
+
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE);
};
} // end namespace llvm
// External Interface declaration
//===----------------------------------------------------------------------===//
-bool CTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o,
- CodeGenFileType FileType, bool Fast) {
+bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
+ std::ostream &o,
+ CodeGenFileType FileType,
+ bool Fast) {
if (FileType != TargetMachine::AssemblyFile) return true;
PM.add(createLowerGCPass());
CTargetMachine(const Module &M, const std::string &FS)
: DataLayout(&M) {}
- // This is the only thing that actually does anything here.
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
+ virtual bool WantsWholeFile() const { return true; }
+ virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
+ CodeGenFileType FileType, bool Fast);
// This class always works, but shouldn't be the default in most cases.
static unsigned getModuleMatchQuality(const Module &M) { return 1; }
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const TargetData *getTargetData() const { return &DataLayout; }
};
} // End llvm namespace
// External Interface declaration
//===----------------------------------------------------------------------===//
-bool CTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o,
- CodeGenFileType FileType, bool Fast) {
+bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
+ std::ostream &o,
+ CodeGenFileType FileType,
+ bool Fast) {
if (FileType != TargetMachine::AssemblyFile) return true;
PM.add(createLowerGCPass());
//
//===----------------------------------------------------------------------===//
//
-// This file defines the IA64 specific subclass of TargetMachine.
+// This file implements the IA64 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
#include "IA64.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/Statistic.h"
-#include <iostream>
using namespace llvm;
/// IA64TargetMachineModule - Note that this is used on hosts that cannot link
int IA64TargetMachineModule = 0;
namespace {
- cl::opt<bool> DisableOutput("disable-ia64-llc-output", cl::Hidden,
- cl::desc("Disable the IA64 asm printer, for use "
- "when profiling the code generator."));
-
- cl::opt<bool> EnableDAGIsel("enable-ia64-dag-isel", cl::Hidden,
- cl::desc("Enable the IA64 DAG->DAG isel"));
-
- // Register the target.
RegisterTarget<IA64TargetMachine> X("ia64", " IA-64 (Itanium)");
}
TLInfo(*this) { // FIXME? check this stuff
}
-// addPassesToEmitFile - We currently use all of the same passes as the JIT
-// does to emit statically compiled machine code.
-bool IA64TargetMachine::addPassesToEmitFile(PassManager &PM,
- std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile) return true;
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass(704, 16)); // on ia64 linux, jmpbufs are 704
- // bytes and must be 16byte aligned
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
- // Add an instruction selector
-// FIXME: reap this option one day: if(EnableDAGIsel)
+bool IA64TargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createIA64DAGToDAGInstructionSelector(*this));
-
-/* XXX not yet. ;)
- // Run optional SSA-based machine code optimizations next...
- if (!NoSSAPeephole)
- PM.add(createIA64SSAPeepholeOptimizerPass());
-*/
-
- // Print the instruction selected machine code...
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Perform register allocation to convert to a concrete IA64 representation
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- PM.add(createPrologEpilogCodeInserter());
-
-/* XXX no, not just yet */
-// PM.add(createIA64PeepholeOptimizerPass());
+ return false;
+}
+bool IA64TargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
// Make sure everything is bundled happily
PM.add(createIA64BundlingPass(*this));
-
- if (PrintMachineCode) // Print the register-allocated code
- PM.add(createIA64CodePrinterPass(std::cerr, *this));
-
- if (!DisableOutput)
- PM.add(createIA64CodePrinterPass(Out, *this));
-
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
-
- return false; // success!
+ return true;
+}
+bool IA64TargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createIA64CodePrinterPass(Out, *this));
+ return false;
}
//
//===----------------------------------------------------------------------===//
-#ifndef IA64TARGETMACHINE_H
-#define IA64TARGETMACHINE_H
+#ifndef LLVM_TARGET_IA64TARGETMACHINE_H
+#define LLVM_TARGET_IA64TARGETMACHINE_H
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "IA64InstrInfo.h"
#include "IA64ISelLowering.h"
namespace llvm {
-class IA64TargetMachine : public TargetMachine {
+class IA64TargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
IA64InstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
-
static unsigned getModuleMatchQuality(const Module &M);
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
};
} // End llvm namespace
-//===-- PowerPC.h - Top-level interface for PowerPC representation -*- C++ -*-//
+//===-- PPC.h - Top-level interface for PowerPC Target ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#ifndef TARGET_POWERPC_H
-#define TARGET_POWERPC_H
+#ifndef LLVM_TARGET_POWERPC_H
+#define LLVM_TARGET_POWERPC_H
#include <iosfwd>
namespace llvm {
class PPCTargetMachine;
-class PassManager;
+class FunctionPassManager;
class FunctionPass;
class MachineCodeEmitter;
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, PPCTargetMachine &TM);
FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM,
MachineCodeEmitter &MCE);
-void addPPCMachOObjectWriterPass(PassManager &FPM, std::ostream &o,
+void addPPCMachOObjectWriterPass(FunctionPassManager &FPM, std::ostream &o,
PPCTargetMachine &tm);
} // end namespace llvm;
is64Bit = tmIs64Bit;
}
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast dynamic compiler for this target. Return true if this
- /// is not supported for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM);
-
virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
virtual void relocate(void *Function, MachineRelocation *MR,
/// addPPCMachOObjectWriterPass - Returns a pass that outputs the generated code
/// as a Mach-O object file.
///
-void llvm::addPPCMachOObjectWriterPass(PassManager &FPM,
+void llvm::addPPCMachOObjectWriterPass(FunctionPassManager &FPM,
std::ostream &O, PPCTargetMachine &TM) {
PPCMachOWriter *EW = new PPCMachOWriter(O, TM);
FPM.add(EW);
//===----------------------------------------------------------------------===//
#include "PPC.h"
-#include "PPCFrameInfo.h"
#include "PPCTargetMachine.h"
-#include "PPCJITInfo.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/CommandLine.h"
-#include <iostream>
using namespace llvm;
namespace {
: PPCTargetMachine(M, FS, true) {
}
-/// addPassesToEmitFile - Add passes to the specified pass manager to implement
-/// a static compiler for this target.
-///
-bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile &&
- FileType != TargetMachine::ObjectFile) return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast) PM.add(createLoopStrengthReducePass(&TLInfo));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Clean up after other passes, e.g. merging critical edges.
- if (!Fast) PM.add(createCFGSimplificationPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
+bool PPCTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
// Install an instruction selector.
PM.add(createPPCISelDag(*this));
+ return false;
+}
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createPrologEpilogCodeInserter());
-
- // Must run branch selection immediately preceding the asm printer
+bool PPCTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
+
+ // Must run branch selection immediately preceding the asm printer.
PM.add(createPPCBranchSelectionPass());
-
- if (FileType == TargetMachine::AssemblyFile)
- PM.add(createDarwinAsmPrinter(Out, *this));
- else
- // FIXME: support PPC ELF files at some point
- addPPCMachOObjectWriterPass(PM, Out, *this);
-
- PM.add(createMachineCodeDeleter());
return false;
}
-void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
- // The JIT should use the static relocation model.
- TM.setRelocationModel(Reloc::Static);
-
- // Run loop strength reduction before anything else.
- PM.add(createLoopStrengthReducePass(TM.getTargetLowering()));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Clean up after other passes, e.g. merging critical edges.
- PM.add(createCFGSimplificationPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- // Install an instruction selector.
- PM.add(createPPCISelDag(TM));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Must run branch selection immediately preceding the asm printer
- PM.add(createPPCBranchSelectionPass());
+bool PPCTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createDarwinAsmPrinter(Out, *this));
+ return false;
+}
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
+bool PPCTargetMachine::addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ // FIXME: support PPC ELF files at some point
+ addPPCMachOObjectWriterPass(PM, Out, *this);
+ return true;
}
-/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
-/// machine code emitted. This uses a MachineCodeEmitter object to handle
-/// actually outputting the machine code and resolving things like the address
-/// of functions. This method should returns true if machine code emission is
-/// not supported.
-///
-bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
- // Machine code emitter pass for PowerPC
+bool PPCTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
+ // The JIT should use the static relocation model.
+ // FIXME: This should be moved to TargetJITInfo!!
+ setRelocationModel(Reloc::Static);
+
+
+
+ // Machine code emitter pass for PowerPC.
PM.add(createPPCCodeEmitterPass(*this, MCE));
- // Delete machine code for this function after emitting it
- PM.add(createMachineCodeDeleter());
return false;
}
+
/// PPCTargetMachine - Common code between 32-bit and 64-bit PowerPC targets.
///
-class PPCTargetMachine : public TargetMachine {
+class PPCTargetMachine : public LLVMTargetMachine {
PPCSubtarget Subtarget;
const TargetData DataLayout; // Calculates type size & alignment
PPCInstrInfo InstrInfo;
return InstrItins;
}
-
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
- bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE);
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE);
};
/// PPC32TargetMachine - PowerPC 32-bit target machine.
#include "SparcTargetMachine.h"
#include "Sparc.h"
-#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
#include <iostream>
using namespace llvm;
return 0;
}
-/// addPassesToEmitFile - Add passes to the specified pass manager
-/// to implement a static compiler for this target.
-///
-bool SparcTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile) return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast) PM.add(createLoopStrengthReducePass());
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Print LLVM code input to instruction selector:
- if (PrintMachineCode)
- PM.add(new PrintFunctionPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
+bool SparcTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createSparcISelDag(*this));
+ return false;
+}
- // Print machine instructions as they were initially generated.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Print machine instructions after register allocation and prolog/epilog
- // insertion.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+/// addPreEmitPass - This pass may be implemented by targets that want to run
+/// passes immediately before machine code is emitted. This should return
+/// true if -print-machineinstrs should print out the code after the passes.
+bool SparcTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
PM.add(createSparcFPMoverPass(*this));
-
PM.add(createSparcDelaySlotFillerPass(*this));
+ return true;
+}
- // Print machine instructions after filling delay slots.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+bool SparcTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
// Output assembly language.
PM.add(createSparcCodePrinterPass(Out, *this));
-
- // Delete the MachineInstrs we generated, since they're no longer needed.
- PM.add(createMachineCodeDeleter());
return false;
}
-
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "SparcInstrInfo.h"
#include "SparcSubtarget.h"
class Module;
-class SparcTargetMachine : public TargetMachine {
+class SparcTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
SparcSubtarget Subtarget;
SparcInstrInfo InstrInfo;
virtual const TargetData *getTargetData() const { return &DataLayout; }
static unsigned getModuleMatchQuality(const Module &M);
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
+
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
};
} // end namespace llvm
namespace llvm {
class X86TargetMachine;
-class PassManager;
+class FunctionPassManager;
class FunctionPass;
class IntrinsicLowering;
class MachineCodeEmitter;
/// addX86ELFObjectWriterPass - Add passes to the FPM that output the generated
/// code as an ELF object file.
///
-void addX86ELFObjectWriterPass(PassManager &FPM,
+void addX86ELFObjectWriterPass(FunctionPassManager &FPM,
std::ostream &o, X86TargetMachine &tm);
/// createX86EmitCodeToMemory - Returns a pass that converts a register
/// addX86ELFObjectWriterPass - Returns a pass that outputs the generated code
/// as an ELF object file.
///
-void llvm::addX86ELFObjectWriterPass(PassManager &FPM,
+void llvm::addX86ELFObjectWriterPass(FunctionPassManager &FPM,
std::ostream &O, X86TargetMachine &TM) {
X86ELFWriter *EW = new X86ELFWriter(O, TM);
FPM.add(EW);
public:
X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;}
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast dynamic compiler for this target. Return true if this
- /// is not supported for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM);
-
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
/// overwriting OLD with a branch to NEW. This is used for self-modifying
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/Statistic.h"
#include <iostream>
using namespace llvm;
int X86TargetMachineModule = 0;
namespace {
- cl::opt<bool> DisableOutput("disable-x86-llc-output", cl::Hidden,
- cl::desc("Disable the X86 asm printer, for use "
- "when profiling the code generator."));
// Register the target.
RegisterTarget<X86TargetMachine> X("x86", " IA-32 (Pentium and above)");
}
setRelocationModel(Reloc::PIC_);
}
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
-// addPassesToEmitFile - We currently use all of the same passes as the JIT
-// does to emit statically compiled machine code.
-bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile &&
- FileType != TargetMachine::ObjectFile) return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast) PM.add(createLoopStrengthReducePass(&TLInfo));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
+bool X86TargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
// Install an instruction selector.
PM.add(createX86ISelDag(*this, Fast));
-
- // Print the instruction selected machine code...
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Perform register allocation to convert to a concrete x86 representation
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createX86FloatingPointStackifierPass());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- PM.add(createPrologEpilogCodeInserter());
-
- if (PrintMachineCode) // Print the register-allocated code
- PM.add(createX86CodePrinterPass(std::cerr, *this));
-
- if (!DisableOutput)
- switch (FileType) {
- default:
- assert(0 && "Unexpected filetype here!");
- case TargetMachine::AssemblyFile:
- PM.add(createX86CodePrinterPass(Out, *this));
- break;
- case TargetMachine::ObjectFile:
- // FIXME: We only support emission of ELF files for now, this should check
- // the target triple and decide on the format to write (e.g. COFF on
- // win32 or Mach-O on darwin).
- addX86ELFObjectWriterPass(PM, Out, *this);
- break;
- }
-
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
-
- return false; // success!
+ return false;
}
-/// addPassesToJITCompile - Add passes to the specified pass manager to
-/// implement a fast dynamic compiler for this target. Return true if this is
-/// not supported for this target.
-///
-void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
- // The JIT should use static relocation model.
- TM.setRelocationModel(Reloc::Static);
-
- // Run loop strength reduction before anything else.
- PM.add(createLoopStrengthReducePass(TM.getTargetLowering()));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- // Install an instruction selector.
- PM.add(createX86ISelDag(TM, false));
-
- // Print the instruction selected machine code...
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Perform register allocation to convert to a concrete x86 representation
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+bool X86TargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
PM.add(createX86FloatingPointStackifierPass());
+ return true; // -print-machineinstr should print after this.
+}
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- PM.add(createPrologEpilogCodeInserter());
+bool X86TargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createX86CodePrinterPass(Out, *this));
+ return false;
+}
- if (PrintMachineCode) // Print the register-allocated code
- PM.add(createX86CodePrinterPass(std::cerr, TM));
+bool X86TargetMachine::addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ if (Subtarget.isTargetELF()) {
+ addX86ELFObjectWriterPass(PM, Out, *this);
+ return false;
+ }
+ return true;
}
-bool X86TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
+bool X86TargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
PM.add(createX86CodeEmitterPass(*this, MCE));
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
return false;
}
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "X86.h"
#include "X86InstrInfo.h"
#include "X86JITInfo.h"
namespace llvm {
-class X86TargetMachine : public TargetMachine {
+class X86TargetMachine : public LLVMTargetMachine {
X86Subtarget Subtarget;
const TargetData DataLayout; // Calculates type size & alignment
TargetFrameInfo FrameInfo;
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
- virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE);
-
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
-
static unsigned getModuleMatchQuality(const Module &M);
static unsigned getJITMatchQuality();
+
+
+ // Set up the pass pipeline.
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE);
};
} // End llvm namespace
return outputFilename;
}
+static std::ostream *GetOutputStream(const char *ProgName) {
+ if (OutputFilename != "") {
+ if (OutputFilename == "-")
+ return &std::cout;
+
+ // Specified an output filename?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << ProgName << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 0;
+ }
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ return new std::ofstream(OutputFilename.c_str());
+ }
+
+ if (InputFilename == "-") {
+ OutputFilename = "-";
+ return &std::cout;
+ }
+
+ OutputFilename = GetFileNameRoot(InputFilename);
+
+ switch (FileType) {
+ case TargetMachine::AssemblyFile:
+ if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
+ OutputFilename += ".s";
+ else
+ OutputFilename += ".cbe.c";
+ break;
+ case TargetMachine::ObjectFile:
+ OutputFilename += ".o";
+ break;
+ case TargetMachine::DynamicLibrary:
+ OutputFilename += LTDL_SHLIB_EXT;
+ break;
+ }
+
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << ProgName << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 0;
+ }
+
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ std::ostream *Out = new std::ofstream(OutputFilename.c_str());
+ if (!Out->good()) {
+ std::cerr << ProgName << ": error opening " << OutputFilename << "!\n";
+ delete Out;
+ return 0;
+ }
+
+ return Out;
+}
// main - Entry point for the llc compiler.
//
assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get();
- // Build up all of the passes that we want to do to the module...
- PassManager Passes;
- Passes.add(new TargetData(*Target.getTargetData()));
-
-#ifndef NDEBUG
- if(!NoVerify)
- Passes.add(createVerifierPass());
-#endif
-
// Figure out where we are going to send the output...
- std::ostream *Out = 0;
- if (OutputFilename != "") {
- if (OutputFilename != "-") {
- // Specified an output filename?
- if (!Force && std::ifstream(OutputFilename.c_str())) {
- // If force is not specified, make sure not to overwrite a file!
- std::cerr << argv[0] << ": error opening '" << OutputFilename
- << "': file exists!\n"
- << "Use -f command line argument to force output\n";
- return 1;
- }
- Out = new std::ofstream(OutputFilename.c_str());
-
- // Make sure that the Out file gets unlinked from the disk if we get a
- // SIGINT
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
- } else {
- Out = &std::cout;
+ std::ostream *Out = GetOutputStream(argv[0]);
+ if (Out == 0) return 1;
+
+ // If this target requires addPassesToEmitWholeFile, do it now. This is
+ // used by strange things like the C backend.
+ if (Target.WantsWholeFile()) {
+ PassManager PM;
+ PM.add(new TargetData(*Target.getTargetData()));
+ if (!NoVerify)
+ PM.add(createVerifierPass());
+
+ // Ask the target to add backend passes as necessary.
+ if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) {
+ std::cerr << argv[0] << ": target does not support generation of this"
+ << " file type!\n";
+ if (Out != &std::cout) delete Out;
+ // And the Out file is empty and useless, so remove it now.
+ sys::Path(OutputFilename).eraseFromDisk();
+ return 1;
}
+ PM.run(mod);
} else {
- if (InputFilename == "-") {
- OutputFilename = "-";
- Out = &std::cout;
- } else {
- OutputFilename = GetFileNameRoot(InputFilename);
-
- switch (FileType) {
- case TargetMachine::AssemblyFile:
- if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
- OutputFilename += ".s";
- else
- OutputFilename += ".cbe.c";
- break;
- case TargetMachine::ObjectFile:
- OutputFilename += ".o";
- break;
- case TargetMachine::DynamicLibrary:
- OutputFilename += LTDL_SHLIB_EXT;
- break;
- }
-
- if (!Force && std::ifstream(OutputFilename.c_str())) {
- // If force is not specified, make sure not to overwrite a file!
- std::cerr << argv[0] << ": error opening '" << OutputFilename
- << "': file exists!\n"
- << "Use -f command line argument to force output\n";
- return 1;
- }
-
- Out = new std::ofstream(OutputFilename.c_str());
- if (!Out->good()) {
- std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
- delete Out;
- return 1;
- }
-
- // Make sure that the Out file gets unlinked from the disk if we get a
- // SIGINT
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ // Build up all of the passes that we want to do to the module.
+ FunctionPassManager Passes(new ExistingModuleProvider(M.get()));
+ Passes.add(new TargetData(*Target.getTargetData()));
+
+#ifndef NDEBUG
+ if (!NoVerify)
+ Passes.add(createVerifierPass());
+#endif
+
+ // Ask the target to add backend passes as necessary.
+ if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
+ std::cerr << argv[0] << ": target does not support generation of this"
+ << " file type!\n";
+ if (Out != &std::cout) delete Out;
+ // And the Out file is empty and useless, so remove it now.
+ sys::Path(OutputFilename).eraseFromDisk();
+ return 1;
}
- }
-
- // Ask the target to add backend passes as necessary.
- if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
- std::cerr << argv[0] << ": target does not support generation of this"
- << " file type!\n";
- if (Out != &std::cout) delete Out;
- // And the Out file is empty and useless, so remove it now.
- sys::Path(OutputFilename).eraseFromDisk();
- return 1;
- } else {
+
+ Passes.doInitialization();
+
// Run our queue of passes all at once now, efficiently.
- Passes.run(*M.get());
+ // TODO: this could lazily stream functions out of the module.
+ for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
+ if (!I->isExternal())
+ Passes.run(*I);
+
+ Passes.doFinalization();
}
-
+
// Delete the ostream if it's not a stdout stream
if (Out != &std::cout) delete Out;