ARMTargetMachine.cpp revision 263508
1139749Simp//===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
253553Stanimura//
353553Stanimura//                     The LLVM Compiler Infrastructure
453553Stanimura//
553553Stanimura// This file is distributed under the University of Illinois Open Source
653553Stanimura// License. See LICENSE.TXT for details.
753553Stanimura//
853553Stanimura//===----------------------------------------------------------------------===//
953553Stanimura//
1053553Stanimura//
1153553Stanimura//===----------------------------------------------------------------------===//
1253553Stanimura
1353553Stanimura#include "ARMTargetMachine.h"
1453553Stanimura#include "ARM.h"
1553553Stanimura#include "ARMFrameLowering.h"
1653553Stanimura#include "llvm/CodeGen/Passes.h"
1753553Stanimura#include "llvm/MC/MCAsmInfo.h"
1853553Stanimura#include "llvm/PassManager.h"
1953553Stanimura#include "llvm/Support/CommandLine.h"
2053553Stanimura#include "llvm/Support/FormattedStream.h"
2153553Stanimura#include "llvm/Support/TargetRegistry.h"
2253553Stanimura#include "llvm/Target/TargetOptions.h"
2353553Stanimura#include "llvm/Transforms/Scalar.h"
2453553Stanimurausing namespace llvm;
2553553Stanimura
2653553Stanimurastatic cl::opt<bool>
2753553StanimuraEnableGlobalMerge("global-merge", cl::Hidden,
2853553Stanimura                  cl::desc("Enable global merge pass"),
2953553Stanimura                  cl::init(true));
3053553Stanimura
3153553Stanimurastatic cl::opt<bool>
3253553StanimuraDisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
3353553Stanimura                   cl::desc("Inhibit optimization of S->D register accesses on A15"),
3453553Stanimura                   cl::init(false));
3553553Stanimura
3653553Stanimuraextern "C" void LLVMInitializeARMTarget() {
37193640Sariff  // Register the target.
38193640Sariff  RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
39193640Sariff  RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
40193640Sariff}
41193640Sariff
4253553Stanimura
4353553Stanimura/// TargetMachine ctor - Create an ARM architecture model.
4453553Stanimura///
4553553StanimuraARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
4653553Stanimura                                           StringRef CPU, StringRef FS,
4753553Stanimura                                           const TargetOptions &Options,
4853553Stanimura                                           Reloc::Model RM, CodeModel::Model CM,
4982180Scg                                           CodeGenOpt::Level OL)
5082180Scg  : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
5153682Stanimura    Subtarget(TT, CPU, FS, Options),
5253682Stanimura    JITInfo(),
5353682Stanimura    InstrItins(Subtarget.getInstrItineraryData()) {
5453682Stanimura  // Default to soft float ABI
5553553Stanimura  if (Options.FloatABIType == FloatABI::Default)
5662947Stanimura    this->Options.FloatABIType = FloatABI::Soft;
5762947Stanimura}
5862947Stanimura
5962947Stanimuravoid ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
6062947Stanimura  // Add first the target-independent BasicTTI pass, then our ARM pass. This
6162947Stanimura  // allows the ARM pass to delegate to the target independent layer when
6262947Stanimura  // appropriate.
6353553Stanimura  PM.add(createBasicTargetTransformInfoPass(this));
6453553Stanimura  PM.add(createARMTargetTransformInfoPass(this));
6553553Stanimura}
6653553Stanimura
6753553Stanimura
6853553Stanimuravoid ARMTargetMachine::anchor() { }
6953553Stanimura
7053553StanimuraARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
7153553Stanimura                                   StringRef CPU, StringRef FS,
7253553Stanimura                                   const TargetOptions &Options,
7353553Stanimura                                   Reloc::Model RM, CodeModel::Model CM,
7453553Stanimura                                   CodeGenOpt::Level OL)
7553553Stanimura  : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
7653553Stanimura    InstrInfo(Subtarget),
7753553Stanimura    DL(Subtarget.isAPCS_ABI() ?
7853553Stanimura               std::string("e-p:32:32-f64:32:64-i64:32:64-"
7953553Stanimura                           "v128:32:128-v64:32:64-n32-S32") :
8053553Stanimura               Subtarget.isAAPCS_ABI() ?
8153553Stanimura               std::string("e-p:32:32-f64:64:64-i64:64:64-"
8253553Stanimura                           "v128:64:128-v64:64:64-n32-S64") :
8353553Stanimura               std::string("e-p:32:32-f64:64:64-i64:64:64-"
8453553Stanimura                           "v128:64:128-v64:64:64-n32-S32")),
8553553Stanimura    TLInfo(*this),
8653553Stanimura    TSInfo(*this),
8753553Stanimura    FrameLowering(Subtarget) {
8853553Stanimura  initAsmInfo();
8953553Stanimura  if (!Subtarget.hasARMOps())
9053553Stanimura    report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
9153553Stanimura                       "support ARM mode execution!");
9253553Stanimura}
9353553Stanimura
9453553Stanimuravoid ThumbTargetMachine::anchor() { }
9553553Stanimura
9653553StanimuraThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
9753553Stanimura                                       StringRef CPU, StringRef FS,
9853553Stanimura                                       const TargetOptions &Options,
9953553Stanimura                                       Reloc::Model RM, CodeModel::Model CM,
10053553Stanimura                                       CodeGenOpt::Level OL)
10153553Stanimura  : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
10253553Stanimura    InstrInfo(Subtarget.hasThumb2()
10353553Stanimura              ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
10453553Stanimura              : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
10553553Stanimura    DL(Subtarget.isAPCS_ABI() ?
10653553Stanimura               std::string("e-p:32:32-f64:32:64-i64:32:64-"
10754073Smdodd                           "i16:16:32-i8:8:32-i1:8:32-"
10862947Stanimura                           "v128:32:128-v64:32:64-a:0:32-n32-S32") :
10953553Stanimura               Subtarget.isAAPCS_ABI() ?
11053553Stanimura               std::string("e-p:32:32-f64:64:64-i64:64:64-"
11162947Stanimura                           "i16:16:32-i8:8:32-i1:8:32-"
11253553Stanimura                           "v128:64:128-v64:64:64-a:0:32-n32-S64") :
11353553Stanimura               std::string("e-p:32:32-f64:64:64-i64:64:64-"
11453553Stanimura                           "i16:16:32-i8:8:32-i1:8:32-"
11553553Stanimura                           "v128:64:128-v64:64:64-a:0:32-n32-S32")),
11662947Stanimura    TLInfo(*this),
11762947Stanimura    TSInfo(*this),
11862947Stanimura    FrameLowering(Subtarget.hasThumb2()
11962947Stanimura              ? new ARMFrameLowering(Subtarget)
12062947Stanimura              : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
12162947Stanimura  initAsmInfo();
12253553Stanimura}
12353553Stanimura
12462947Stanimuranamespace {
12562947Stanimura/// ARM Code Generator Pass Configuration Options.
12662947Stanimuraclass ARMPassConfig : public TargetPassConfig {
12778564Sgreidpublic:
12862947Stanimura  ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
12962947Stanimura    : TargetPassConfig(TM, PM) {}
13062947Stanimura
13162947Stanimura  ARMBaseTargetMachine &getARMTargetMachine() const {
13262947Stanimura    return getTM<ARMBaseTargetMachine>();
13362947Stanimura  }
13462947Stanimura
13562947Stanimura  const ARMSubtarget &getARMSubtarget() const {
13678564Sgreid    return *getARMTargetMachine().getSubtargetImpl();
13762947Stanimura  }
13862947Stanimura
13962947Stanimura  virtual bool addPreISel();
14062947Stanimura  virtual bool addInstSelector();
14162947Stanimura  virtual bool addPreRegAlloc();
14262947Stanimura  virtual bool addPreSched2();
14362947Stanimura  virtual bool addPreEmitPass();
14462947Stanimura};
14578564Sgreid} // namespace
14662947Stanimura
14762947StanimuraTargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
14862947Stanimura  return new ARMPassConfig(this, PM);
14962947Stanimura}
15062947Stanimura
15162947Stanimurabool ARMPassConfig::addPreISel() {
15262947Stanimura  if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
15362947Stanimura    addPass(createGlobalMergePass(TM));
15453553Stanimura
15553553Stanimura  return false;
15653553Stanimura}
15753553Stanimura
15853553Stanimurabool ARMPassConfig::addInstSelector() {
15953553Stanimura  addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
16053553Stanimura
16153553Stanimura  const ARMSubtarget *Subtarget = &getARMSubtarget();
16253553Stanimura  if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
16353553Stanimura      TM->Options.EnableFastISel)
16453553Stanimura    addPass(createARMGlobalBaseRegPass());
16553553Stanimura  return false;
16653553Stanimura}
16753553Stanimura
16853553Stanimurabool ARMPassConfig::addPreRegAlloc() {
16953553Stanimura  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
17053553Stanimura  if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
17153553Stanimura    addPass(createARMLoadStoreOptimizationPass(true));
17253553Stanimura  if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
17353553Stanimura    addPass(createMLxExpansionPass());
17453553Stanimura  // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
17553553Stanimura  // enabled when NEON is available.
17653553Stanimura  if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() &&
17753553Stanimura    getARMSubtarget().hasNEON() && !DisableA15SDOptimization) {
17853553Stanimura    addPass(createA15SDOptimizerPass());
17953553Stanimura  }
18053553Stanimura  return true;
18154073Smdodd}
18253553Stanimura
18353553Stanimurabool ARMPassConfig::addPreSched2() {
18453553Stanimura  // FIXME: temporarily disabling load / store optimization pass for Thumb1.
18553553Stanimura  if (getOptLevel() != CodeGenOpt::None) {
18653553Stanimura    if (!getARMSubtarget().isThumb1Only()) {
18753553Stanimura      addPass(createARMLoadStoreOptimizationPass());
18853553Stanimura      printAndVerify("After ARM load / store optimizer");
18953553Stanimura    }
19053553Stanimura    if (getARMSubtarget().hasNEON())
19153553Stanimura      addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
19253553Stanimura  }
19353553Stanimura
19453553Stanimura  // Expand some pseudo instructions into multiple instructions to allow
19553553Stanimura  // proper scheduling.
19653553Stanimura  addPass(createARMExpandPseudoPass());
19753553Stanimura
19853553Stanimura  if (getOptLevel() != CodeGenOpt::None) {
19953553Stanimura    if (!getARMSubtarget().isThumb1Only()) {
20053553Stanimura      // in v8, IfConversion depends on Thumb instruction widths
20153553Stanimura      if (getARMSubtarget().restrictIT() &&
20253553Stanimura          !getARMSubtarget().prefers32BitThumb())
20353553Stanimura        addPass(createThumb2SizeReductionPass());
20453553Stanimura      addPass(&IfConverterID);
20553553Stanimura    }
20653553Stanimura  }
20753553Stanimura  if (getARMSubtarget().isThumb2())
20853553Stanimura    addPass(createThumb2ITBlockPass());
20953553Stanimura
21053553Stanimura  return true;
21153553Stanimura}
21253553Stanimura
21353553Stanimurabool ARMPassConfig::addPreEmitPass() {
21453553Stanimura  if (getARMSubtarget().isThumb2()) {
21553553Stanimura    if (!getARMSubtarget().prefers32BitThumb())
21653553Stanimura      addPass(createThumb2SizeReductionPass());
21753553Stanimura
21853553Stanimura    // Constant island pass work on unbundled instructions.
21953553Stanimura    addPass(&UnpackMachineBundlesID);
22053553Stanimura  }
22153553Stanimura
22253553Stanimura  addPass(createARMConstantIslandPass());
22353553Stanimura
22453553Stanimura  return true;
22553553Stanimura}
22653553Stanimura
22753553Stanimurabool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
22853553Stanimura                                          JITCodeEmitter &JCE) {
22953553Stanimura  // Machine code emitter pass for ARM.
23053553Stanimura  PM.add(createARMJITCodeEmitterPass(*this, JCE));
23153553Stanimura  return false;
23253553Stanimura}
23353553Stanimura