Home | History | Annotate | Download | only in ARM
      1 //===-- ARMTargetMachine.cpp - Define TargetMachine for ARM ---------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #include "ARMTargetMachine.h"
     14 #include "ARM.h"
     15 #include "ARMFrameLowering.h"
     16 #include "llvm/CodeGen/Passes.h"
     17 #include "llvm/MC/MCAsmInfo.h"
     18 #include "llvm/PassManager.h"
     19 #include "llvm/Support/CommandLine.h"
     20 #include "llvm/Support/FormattedStream.h"
     21 #include "llvm/Support/TargetRegistry.h"
     22 #include "llvm/Target/TargetOptions.h"
     23 #include "llvm/Transforms/Scalar.h"
     24 using namespace llvm;
     25 
     26 static cl::opt<bool>
     27 EnableGlobalMerge("global-merge", cl::Hidden,
     28                   cl::desc("Enable global merge pass"),
     29                   cl::init(true));
     30 
     31 static cl::opt<bool>
     32 DisableA15SDOptimization("disable-a15-sd-optimization", cl::Hidden,
     33                    cl::desc("Inhibit optimization of S->D register accesses on A15"),
     34                    cl::init(false));
     35 
     36 extern "C" void LLVMInitializeARMTarget() {
     37   // Register the target.
     38   RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
     39   RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
     40 }
     41 
     42 
     43 /// TargetMachine ctor - Create an ARM architecture model.
     44 ///
     45 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
     46                                            StringRef CPU, StringRef FS,
     47                                            const TargetOptions &Options,
     48                                            Reloc::Model RM, CodeModel::Model CM,
     49                                            CodeGenOpt::Level OL)
     50   : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
     51     Subtarget(TT, CPU, FS),
     52     JITInfo(),
     53     InstrItins(Subtarget.getInstrItineraryData()) {
     54   // Default to soft float ABI
     55   if (Options.FloatABIType == FloatABI::Default)
     56     this->Options.FloatABIType = FloatABI::Soft;
     57 }
     58 
     59 void ARMBaseTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
     60   // Add first the target-independent BasicTTI pass, then our ARM pass. This
     61   // allows the ARM pass to delegate to the target independent layer when
     62   // appropriate.
     63   PM.add(createBasicTargetTransformInfoPass(getTargetLowering()));
     64   PM.add(createARMTargetTransformInfoPass(this));
     65 }
     66 
     67 
     68 void ARMTargetMachine::anchor() { }
     69 
     70 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
     71                                    StringRef CPU, StringRef FS,
     72                                    const TargetOptions &Options,
     73                                    Reloc::Model RM, CodeModel::Model CM,
     74                                    CodeGenOpt::Level OL)
     75   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
     76     InstrInfo(Subtarget),
     77     DL(Subtarget.isAPCS_ABI() ?
     78                std::string("e-p:32:32-f64:32:64-i64:32:64-"
     79                            "v128:32:128-v64:32:64-n32-S32") :
     80                Subtarget.isAAPCS_ABI() ?
     81                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     82                            "v128:64:128-v64:64:64-n32-S64") :
     83                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     84                            "v128:64:128-v64:64:64-n32-S32")),
     85     TLInfo(*this),
     86     TSInfo(*this),
     87     FrameLowering(Subtarget) {
     88   if (!Subtarget.hasARMOps())
     89     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
     90                        "support ARM mode execution!");
     91 }
     92 
     93 void ThumbTargetMachine::anchor() { }
     94 
     95 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
     96                                        StringRef CPU, StringRef FS,
     97                                        const TargetOptions &Options,
     98                                        Reloc::Model RM, CodeModel::Model CM,
     99                                        CodeGenOpt::Level OL)
    100   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
    101     InstrInfo(Subtarget.hasThumb2()
    102               ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
    103               : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
    104     DL(Subtarget.isAPCS_ABI() ?
    105                std::string("e-p:32:32-f64:32:64-i64:32:64-"
    106                            "i16:16:32-i8:8:32-i1:8:32-"
    107                            "v128:32:128-v64:32:64-a:0:32-n32-S32") :
    108                Subtarget.isAAPCS_ABI() ?
    109                std::string("e-p:32:32-f64:64:64-i64:64:64-"
    110                            "i16:16:32-i8:8:32-i1:8:32-"
    111                            "v128:64:128-v64:64:64-a:0:32-n32-S64") :
    112                std::string("e-p:32:32-f64:64:64-i64:64:64-"
    113                            "i16:16:32-i8:8:32-i1:8:32-"
    114                            "v128:64:128-v64:64:64-a:0:32-n32-S32")),
    115     TLInfo(*this),
    116     TSInfo(*this),
    117     FrameLowering(Subtarget.hasThumb2()
    118               ? new ARMFrameLowering(Subtarget)
    119               : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
    120 }
    121 
    122 namespace {
    123 /// ARM Code Generator Pass Configuration Options.
    124 class ARMPassConfig : public TargetPassConfig {
    125 public:
    126   ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
    127     : TargetPassConfig(TM, PM) {}
    128 
    129   ARMBaseTargetMachine &getARMTargetMachine() const {
    130     return getTM<ARMBaseTargetMachine>();
    131   }
    132 
    133   const ARMSubtarget &getARMSubtarget() const {
    134     return *getARMTargetMachine().getSubtargetImpl();
    135   }
    136 
    137   virtual bool addPreISel();
    138   virtual bool addInstSelector();
    139   virtual bool addPreRegAlloc();
    140   virtual bool addPreSched2();
    141   virtual bool addPreEmitPass();
    142 };
    143 } // namespace
    144 
    145 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
    146   return new ARMPassConfig(this, PM);
    147 }
    148 
    149 bool ARMPassConfig::addPreISel() {
    150   if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
    151     addPass(createGlobalMergePass(TM->getTargetLowering()));
    152 
    153   return false;
    154 }
    155 
    156 bool ARMPassConfig::addInstSelector() {
    157   addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
    158 
    159   const ARMSubtarget *Subtarget = &getARMSubtarget();
    160   if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
    161       TM->Options.EnableFastISel)
    162     addPass(createARMGlobalBaseRegPass());
    163   return false;
    164 }
    165 
    166 bool ARMPassConfig::addPreRegAlloc() {
    167   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    168   if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
    169     addPass(createARMLoadStoreOptimizationPass(true));
    170   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isLikeA9())
    171     addPass(createMLxExpansionPass());
    172   // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
    173   // enabled when NEON is available.
    174   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() &&
    175     getARMSubtarget().hasNEON() && !DisableA15SDOptimization) {
    176     addPass(createA15SDOptimizerPass());
    177   }
    178   return true;
    179 }
    180 
    181 bool ARMPassConfig::addPreSched2() {
    182   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    183   if (getOptLevel() != CodeGenOpt::None) {
    184     if (!getARMSubtarget().isThumb1Only()) {
    185       addPass(createARMLoadStoreOptimizationPass());
    186       printAndVerify("After ARM load / store optimizer");
    187     }
    188     if ((DisableA15SDOptimization || !getARMSubtarget().isCortexA15()) &&
    189       getARMSubtarget().hasNEON())
    190       addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
    191   }
    192 
    193   // Expand some pseudo instructions into multiple instructions to allow
    194   // proper scheduling.
    195   addPass(createARMExpandPseudoPass());
    196 
    197   if (getOptLevel() != CodeGenOpt::None) {
    198     if (!getARMSubtarget().isThumb1Only())
    199       addPass(&IfConverterID);
    200   }
    201   if (getARMSubtarget().isThumb2())
    202     addPass(createThumb2ITBlockPass());
    203 
    204   return true;
    205 }
    206 
    207 bool ARMPassConfig::addPreEmitPass() {
    208   if (getARMSubtarget().isThumb2()) {
    209     if (!getARMSubtarget().prefers32BitThumb())
    210       addPass(createThumb2SizeReductionPass());
    211 
    212     // Constant island pass work on unbundled instructions.
    213     addPass(&UnpackMachineBundlesID);
    214   }
    215 
    216   addPass(createARMConstantIslandPass());
    217 
    218   return true;
    219 }
    220 
    221 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
    222                                           JITCodeEmitter &JCE) {
    223   // Machine code emitter pass for ARM.
    224   PM.add(createARMJITCodeEmitterPass(*this, JCE));
    225   return false;
    226 }
    227