2006-09-04 12:16:09 +08:00
|
|
|
//===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-09-04 12:16:09 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the LLVMTargetMachine class.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-02-04 10:56:59 +08:00
|
|
|
#include "llvm/Transforms/Scalar.h"
|
2006-09-04 12:16:09 +08:00
|
|
|
#include "llvm/PassManager.h"
|
2009-08-14 07:48:47 +08:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
2010-03-14 04:55:24 +08:00
|
|
|
#include "llvm/CodeGen/Passes.h"
|
2012-02-04 10:56:59 +08:00
|
|
|
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
|
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
|
|
|
#include "llvm/Target/TargetLowering.h"
|
|
|
|
#include "llvm/Target/TargetLoweringObjectFile.h"
|
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2006-09-04 12:16:09 +08:00
|
|
|
#include "llvm/Target/TargetOptions.h"
|
2012-02-04 10:56:59 +08:00
|
|
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
|
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
2009-08-23 04:48:53 +08:00
|
|
|
#include "llvm/MC/MCAsmInfo.h"
|
2012-02-04 10:56:48 +08:00
|
|
|
#include "llvm/MC/MCContext.h"
|
2011-07-11 11:57:24 +08:00
|
|
|
#include "llvm/MC/MCInstrInfo.h"
|
2010-02-03 07:37:42 +08:00
|
|
|
#include "llvm/MC/MCStreamer.h"
|
2011-07-11 11:57:24 +08:00
|
|
|
#include "llvm/MC/MCSubtargetInfo.h"
|
2010-02-03 07:45:17 +08:00
|
|
|
#include "llvm/ADT/OwningPtr.h"
|
2007-03-31 08:24:43 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2009-07-15 04:18:05 +08:00
|
|
|
#include "llvm/Support/FormattedStream.h"
|
2012-02-04 10:56:48 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2011-08-25 02:08:43 +08:00
|
|
|
#include "llvm/Support/TargetRegistry.h"
|
2006-09-04 12:16:09 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2012-02-04 10:56:59 +08:00
|
|
|
// Enable or disable FastISel. Both options are needed, because
|
|
|
|
// FastISel is enabled by default with -fast, and we wish to be
|
|
|
|
// able to enable or disable fast-isel independently from -O0.
|
|
|
|
static cl::opt<cl::boolOrDefault>
|
|
|
|
EnableFastISelOption("fast-isel", cl::Hidden,
|
|
|
|
cl::desc("Enable the \"fast\" instruction selector"));
|
|
|
|
|
2010-05-19 01:22:19 +08:00
|
|
|
static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
|
|
|
|
cl::desc("Show encoding in .s output"));
|
|
|
|
static cl::opt<bool> ShowMCInst("show-mc-inst", cl::Hidden,
|
|
|
|
cl::desc("Show instruction structure in .s output"));
|
2007-06-19 13:47:49 +08:00
|
|
|
|
2010-02-03 06:54:51 +08:00
|
|
|
static cl::opt<cl::boolOrDefault>
|
|
|
|
AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
|
|
|
|
cl::init(cl::BOU_UNSET));
|
|
|
|
|
2010-02-03 06:58:13 +08:00
|
|
|
static bool getVerboseAsm() {
|
2010-02-03 06:54:51 +08:00
|
|
|
switch (AsmVerbose) {
|
2010-02-03 06:58:13 +08:00
|
|
|
case cl::BOU_UNSET: return TargetMachine::getAsmVerbosityDefault();
|
|
|
|
case cl::BOU_TRUE: return true;
|
|
|
|
case cl::BOU_FALSE: return false;
|
2010-08-14 00:55:08 +08:00
|
|
|
}
|
2012-01-11 02:08:01 +08:00
|
|
|
llvm_unreachable("Invalid verbose asm state");
|
2010-02-03 06:54:51 +08:00
|
|
|
}
|
2010-01-13 08:30:23 +08:00
|
|
|
|
2011-07-08 09:53:10 +08:00
|
|
|
LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple,
|
2011-07-19 14:37:02 +08:00
|
|
|
StringRef CPU, StringRef FS,
|
2011-12-03 06:16:29 +08:00
|
|
|
TargetOptions Options,
|
2011-11-16 16:38:26 +08:00
|
|
|
Reloc::Model RM, CodeModel::Model CM,
|
|
|
|
CodeGenOpt::Level OL)
|
2011-12-03 06:16:29 +08:00
|
|
|
: TargetMachine(T, Triple, CPU, FS, Options) {
|
2011-11-16 16:38:26 +08:00
|
|
|
CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL);
|
2011-07-15 07:50:31 +08:00
|
|
|
AsmInfo = T.createMCAsmInfo(Triple);
|
2011-09-30 21:07:47 +08:00
|
|
|
// TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
|
|
|
|
// and if the old one gets included then MCAsmInfo will be NULL and
|
|
|
|
// we'll crash later.
|
|
|
|
// Provide the user with a useful error message about what's wrong.
|
|
|
|
assert(AsmInfo && "MCAsmInfo not initialized."
|
2011-10-26 04:30:48 +08:00
|
|
|
"Make sure you include the correct TargetSelect.h"
|
|
|
|
"and that InitializeAllTargetMCs() is being invoked!");
|
2009-08-12 15:22:17 +08:00
|
|
|
}
|
|
|
|
|
2012-02-04 10:56:59 +08:00
|
|
|
/// Turn exception handling constructs into something the code generators can
|
|
|
|
/// handle.
|
|
|
|
static void addPassesToHandleExceptions(TargetMachine *TM,
|
|
|
|
PassManagerBase &PM) {
|
|
|
|
switch (TM->getMCAsmInfo()->getExceptionHandlingType()) {
|
|
|
|
case ExceptionHandling::SjLj:
|
|
|
|
// SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
|
|
|
|
// Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
|
|
|
|
// catch info can get misplaced when a selector ends up more than one block
|
|
|
|
// removed from the parent invoke(s). This could happen when a landing
|
|
|
|
// pad is shared by multiple invokes and is also a target of a normal
|
|
|
|
// edge from elsewhere.
|
2012-03-14 04:04:21 +08:00
|
|
|
PM.add(createSjLjEHPreparePass(TM->getTargetLowering()));
|
2012-02-04 10:56:59 +08:00
|
|
|
// FALLTHROUGH
|
|
|
|
case ExceptionHandling::DwarfCFI:
|
|
|
|
case ExceptionHandling::ARM:
|
|
|
|
case ExceptionHandling::Win64:
|
|
|
|
PM.add(createDwarfEHPass(TM));
|
|
|
|
break;
|
|
|
|
case ExceptionHandling::None:
|
|
|
|
PM.add(createLowerInvokePass(TM->getTargetLowering()));
|
|
|
|
|
|
|
|
// The lower invoke pass may create unreachable code. Remove it.
|
|
|
|
PM.add(createUnreachableBlockEliminationPass());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// addPassesToX helper drives creation and initialization of TargetPassConfig.
|
|
|
|
static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
|
|
|
|
PassManagerBase &PM,
|
|
|
|
bool DisableVerify) {
|
|
|
|
// Targets may override createPassConfig to provide a target-specific sublass.
|
|
|
|
TargetPassConfig *PassConfig = TM->createPassConfig(PM);
|
|
|
|
|
|
|
|
// Set PassConfig options provided by TargetMachine.
|
|
|
|
PassConfig->setDisableVerify(DisableVerify);
|
|
|
|
|
2012-02-07 06:51:15 +08:00
|
|
|
PM.add(PassConfig);
|
|
|
|
|
2012-02-04 10:56:59 +08:00
|
|
|
PassConfig->addIRPasses();
|
|
|
|
|
|
|
|
addPassesToHandleExceptions(TM, PM);
|
|
|
|
|
|
|
|
PassConfig->addISelPrepare();
|
|
|
|
|
|
|
|
// Install a MachineModuleInfo class, which is an immutable pass that holds
|
|
|
|
// all the per-module stuff we're generating, including MCContext.
|
|
|
|
MachineModuleInfo *MMI =
|
|
|
|
new MachineModuleInfo(*TM->getMCAsmInfo(), *TM->getRegisterInfo(),
|
|
|
|
&TM->getTargetLowering()->getObjFileLowering());
|
|
|
|
PM.add(MMI);
|
2012-02-18 01:35:10 +08:00
|
|
|
MCContext *Context = &MMI->getContext(); // Return the MCContext by-ref.
|
2012-02-04 10:56:59 +08:00
|
|
|
|
|
|
|
// Set up a MachineFunction for the rest of CodeGen to work on.
|
|
|
|
PM.add(new MachineFunctionAnalysis(*TM));
|
|
|
|
|
|
|
|
// Enable FastISel with -fast, but allow that to be overridden.
|
|
|
|
if (EnableFastISelOption == cl::BOU_TRUE ||
|
|
|
|
(TM->getOptLevel() == CodeGenOpt::None &&
|
|
|
|
EnableFastISelOption != cl::BOU_FALSE))
|
|
|
|
TM->setFastISel(true);
|
|
|
|
|
|
|
|
// Ask the target for an isel.
|
|
|
|
if (PassConfig->addInstSelector())
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
PassConfig->addMachinePasses();
|
|
|
|
|
2012-02-09 05:22:39 +08:00
|
|
|
PassConfig->setInitialized();
|
|
|
|
|
2012-02-04 10:56:59 +08:00
|
|
|
return Context;
|
|
|
|
}
|
|
|
|
|
2010-02-03 13:55:08 +08:00
|
|
|
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
|
|
|
formatted_raw_ostream &Out,
|
|
|
|
CodeGenFileType FileType,
|
2010-02-28 08:41:59 +08:00
|
|
|
bool DisableVerify) {
|
2008-09-25 08:37:07 +08:00
|
|
|
// Add common CodeGen passes.
|
2012-02-04 10:56:59 +08:00
|
|
|
MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
|
|
|
|
if (!Context)
|
2010-02-03 13:55:08 +08:00
|
|
|
return true;
|
2007-02-08 09:36:53 +08:00
|
|
|
|
2011-03-29 06:49:19 +08:00
|
|
|
if (hasMCSaveTempLabels())
|
|
|
|
Context->setAllowTemporaryLabels(false);
|
|
|
|
|
2010-03-12 06:53:35 +08:00
|
|
|
const MCAsmInfo &MAI = *getMCAsmInfo();
|
2012-05-20 19:24:27 +08:00
|
|
|
const MCRegisterInfo &MRI = *getRegisterInfo();
|
2011-09-08 01:24:38 +08:00
|
|
|
const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
|
2010-02-03 07:45:17 +08:00
|
|
|
OwningPtr<MCStreamer> AsmStreamer;
|
|
|
|
|
2006-09-04 12:16:09 +08:00
|
|
|
switch (FileType) {
|
2010-02-03 08:29:55 +08:00
|
|
|
case CGFT_AssemblyFile: {
|
|
|
|
MCInstPrinter *InstPrinter =
|
2012-03-06 03:33:20 +08:00
|
|
|
getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI,
|
2012-04-02 14:09:36 +08:00
|
|
|
*getInstrInfo(),
|
2012-03-06 03:33:20 +08:00
|
|
|
Context->getRegisterInfo(), STI);
|
2010-05-19 01:22:19 +08:00
|
|
|
|
|
|
|
// Create a code emitter if asked to show the encoding.
|
|
|
|
MCCodeEmitter *MCE = 0;
|
2011-07-26 07:24:55 +08:00
|
|
|
MCAsmBackend *MAB = 0;
|
2010-12-16 11:05:59 +08:00
|
|
|
if (ShowMCEncoding) {
|
2011-07-11 11:57:24 +08:00
|
|
|
const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
|
2012-05-16 01:35:52 +08:00
|
|
|
MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI, STI,
|
|
|
|
*Context);
|
2011-07-26 07:24:55 +08:00
|
|
|
MAB = getTarget().createMCAsmBackend(getTargetTriple());
|
2010-12-16 11:05:59 +08:00
|
|
|
}
|
2010-05-19 01:22:19 +08:00
|
|
|
|
2010-12-10 15:39:47 +08:00
|
|
|
MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
|
|
|
|
getVerboseAsm(),
|
|
|
|
hasMCUseLoc(),
|
2011-04-30 11:44:37 +08:00
|
|
|
hasMCUseCFI(),
|
2011-10-18 07:05:28 +08:00
|
|
|
hasMCUseDwarfDirectory(),
|
2010-12-10 15:39:47 +08:00
|
|
|
InstPrinter,
|
2011-07-26 07:24:55 +08:00
|
|
|
MCE, MAB,
|
2011-06-18 04:55:01 +08:00
|
|
|
ShowMCInst);
|
2010-11-19 10:26:16 +08:00
|
|
|
AsmStreamer.reset(S);
|
2010-02-03 03:14:27 +08:00
|
|
|
break;
|
2010-02-03 08:29:55 +08:00
|
|
|
}
|
2010-02-03 07:57:42 +08:00
|
|
|
case CGFT_ObjectFile: {
|
|
|
|
// Create the code emitter for the target if it exists. If not, .o file
|
|
|
|
// emission fails.
|
2012-05-16 01:35:52 +08:00
|
|
|
MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI,
|
|
|
|
STI, *Context);
|
2011-07-26 07:24:55 +08:00
|
|
|
MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
|
|
|
|
if (MCE == 0 || MAB == 0)
|
2010-02-03 13:55:08 +08:00
|
|
|
return true;
|
2010-05-27 05:48:55 +08:00
|
|
|
|
2011-07-26 08:42:34 +08:00
|
|
|
AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(),
|
|
|
|
*Context, *MAB, Out,
|
|
|
|
MCE, hasMCRelaxAll(),
|
|
|
|
hasMCNoExecStack()));
|
2010-10-09 03:37:38 +08:00
|
|
|
AsmStreamer.get()->InitSections();
|
2010-02-03 07:57:42 +08:00
|
|
|
break;
|
2010-02-03 02:44:12 +08:00
|
|
|
}
|
2010-02-03 13:55:08 +08:00
|
|
|
case CGFT_Null:
|
|
|
|
// The Null output is intended for use for performance analysis and testing,
|
|
|
|
// not real users.
|
|
|
|
AsmStreamer.reset(createNullStreamer(*Context));
|
|
|
|
break;
|
2006-09-04 12:16:09 +08:00
|
|
|
}
|
2010-05-24 01:44:06 +08:00
|
|
|
|
2010-03-14 04:55:24 +08:00
|
|
|
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
|
2010-04-04 16:18:47 +08:00
|
|
|
FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
|
2010-02-03 07:45:17 +08:00
|
|
|
if (Printer == 0)
|
2010-02-03 13:55:08 +08:00
|
|
|
return true;
|
2010-08-14 00:55:08 +08:00
|
|
|
|
2010-03-14 04:55:24 +08:00
|
|
|
// If successful, createAsmPrinter took ownership of AsmStreamer.
|
|
|
|
AsmStreamer.take();
|
2010-08-14 00:55:08 +08:00
|
|
|
|
2010-02-03 07:45:17 +08:00
|
|
|
PM.add(Printer);
|
2010-08-14 00:55:08 +08:00
|
|
|
|
2009-07-06 13:09:34 +08:00
|
|
|
PM.add(createGCInfoDeleter());
|
2010-02-03 13:55:08 +08:00
|
|
|
return false;
|
2008-09-25 08:37:07 +08:00
|
|
|
}
|
|
|
|
|
2009-05-31 04:51:52 +08:00
|
|
|
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
|
2010-02-03 06:31:11 +08:00
|
|
|
/// get machine code emitted. This uses a JITCodeEmitter object to handle
|
2009-05-31 04:51:52 +08:00
|
|
|
/// 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 LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
|
|
|
|
JITCodeEmitter &JCE,
|
2010-02-28 08:41:59 +08:00
|
|
|
bool DisableVerify) {
|
2009-05-31 04:51:52 +08:00
|
|
|
// Add common CodeGen passes.
|
2012-02-04 10:56:59 +08:00
|
|
|
MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
|
|
|
|
if (!Context)
|
2009-05-31 04:51:52 +08:00
|
|
|
return true;
|
|
|
|
|
2011-11-16 16:38:26 +08:00
|
|
|
addCodeEmitter(PM, JCE);
|
2009-05-31 04:51:52 +08:00
|
|
|
PM.add(createGCInfoDeleter());
|
|
|
|
|
|
|
|
return false; // success!
|
|
|
|
}
|
|
|
|
|
2010-07-22 13:58:53 +08:00
|
|
|
/// addPassesToEmitMC - Add passes to the specified pass manager to get
|
|
|
|
/// machine code emitted with the MCJIT. This method returns true if machine
|
|
|
|
/// code is not supported. It fills the MCContext Ctx pointer which can be
|
|
|
|
/// used to build custom MCStreamer.
|
|
|
|
///
|
|
|
|
bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
|
|
|
|
MCContext *&Ctx,
|
2011-03-19 06:48:41 +08:00
|
|
|
raw_ostream &Out,
|
2010-07-22 13:58:53 +08:00
|
|
|
bool DisableVerify) {
|
|
|
|
// Add common CodeGen passes.
|
2012-02-04 10:56:59 +08:00
|
|
|
Ctx = addPassesToGenerateCode(this, PM, DisableVerify);
|
|
|
|
if (!Ctx)
|
2010-07-22 13:58:53 +08:00
|
|
|
return true;
|
2011-03-19 06:48:41 +08:00
|
|
|
|
2011-03-29 06:49:19 +08:00
|
|
|
if (hasMCSaveTempLabels())
|
|
|
|
Ctx->setAllowTemporaryLabels(false);
|
|
|
|
|
2011-03-19 06:48:41 +08:00
|
|
|
// Create the code emitter for the target if it exists. If not, .o file
|
|
|
|
// emission fails.
|
2012-05-21 01:24:08 +08:00
|
|
|
const MCRegisterInfo &MRI = *getRegisterInfo();
|
2011-07-11 11:57:24 +08:00
|
|
|
const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
|
2012-05-16 01:35:52 +08:00
|
|
|
MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI,
|
|
|
|
STI, *Ctx);
|
2011-07-26 07:24:55 +08:00
|
|
|
MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
|
|
|
|
if (MCE == 0 || MAB == 0)
|
2011-03-19 06:48:41 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
OwningPtr<MCStreamer> AsmStreamer;
|
2011-07-26 08:42:34 +08:00
|
|
|
AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Ctx,
|
|
|
|
*MAB, Out, MCE,
|
|
|
|
hasMCRelaxAll(),
|
|
|
|
hasMCNoExecStack()));
|
2011-03-19 06:48:41 +08:00
|
|
|
AsmStreamer.get()->InitSections();
|
|
|
|
|
|
|
|
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
|
|
|
|
FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
|
|
|
|
if (Printer == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// If successful, createAsmPrinter took ownership of AsmStreamer.
|
|
|
|
AsmStreamer.take();
|
|
|
|
|
|
|
|
PM.add(Printer);
|
|
|
|
|
2010-07-22 13:58:53 +08:00
|
|
|
return false; // success!
|
|
|
|
}
|