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 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, Options),
     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(this));
     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   initAsmInfo();
     89   if (!Subtarget.hasARMOps())
     90     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
     91                        "support ARM mode execution!");
     92 }
     93 
     94 void ThumbTargetMachine::anchor() { }
     95 
     96 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
     97                                        StringRef CPU, StringRef FS,
     98                                        const TargetOptions &Options,
     99                                        Reloc::Model RM, CodeModel::Model CM,
    100                                        CodeGenOpt::Level OL)
    101   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
    102     InstrInfo(Subtarget.hasThumb2()
    103               ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
    104               : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
    105     DL(Subtarget.isAPCS_ABI() ?
    106                std::string("e-p:32:32-f64:32:64-i64:32:64-"
    107                            "i16:16:32-i8:8:32-i1:8:32-"
    108                            "v128:32:128-v64:32:64-a:0:32-n32-S32") :
    109                Subtarget.isAAPCS_ABI() ?
    110                std::string("e-p:32:32-f64:64:64-i64:64:64-"
    111                            "i16:16:32-i8:8:32-i1:8:32-"
    112                            "v128:64:128-v64:64:64-a:0:32-n32-S64") :
    113                std::string("e-p:32:32-f64:64:64-i64:64:64-"
    114                            "i16:16:32-i8:8:32-i1:8:32-"
    115                            "v128:64:128-v64:64:64-a:0:32-n32-S32")),
    116     TLInfo(*this),
    117     TSInfo(*this),
    118     FrameLowering(Subtarget.hasThumb2()
    119               ? new ARMFrameLowering(Subtarget)
    120               : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
    121   initAsmInfo();
    122 }
    123 
    124 namespace {
    125 /// ARM Code Generator Pass Configuration Options.
    126 class ARMPassConfig : public TargetPassConfig {
    127 public:
    128   ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
    129     : TargetPassConfig(TM, PM) {}
    130 
    131   ARMBaseTargetMachine &getARMTargetMachine() const {
    132     return getTM<ARMBaseTargetMachine>();
    133   }
    134 
    135   const ARMSubtarget &getARMSubtarget() const {
    136     return *getARMTargetMachine().getSubtargetImpl();
    137   }
    138 
    139   virtual bool addPreISel();
    140   virtual bool addInstSelector();
    141   virtual bool addPreRegAlloc();
    142   virtual bool addPreSched2();
    143   virtual bool addPreEmitPass();
    144 };
    145 } // namespace
    146 
    147 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
    148   return new ARMPassConfig(this, PM);
    149 }
    150 
    151 bool ARMPassConfig::addPreISel() {
    152   if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
    153     addPass(createGlobalMergePass(TM));
    154 
    155   return false;
    156 }
    157 
    158 bool ARMPassConfig::addInstSelector() {
    159   addPass(createARMISelDag(getARMTargetMachine(), getOptLevel()));
    160 
    161   const ARMSubtarget *Subtarget = &getARMSubtarget();
    162   if (Subtarget->isTargetELF() && !Subtarget->isThumb1Only() &&
    163       TM->Options.EnableFastISel)
    164     addPass(createARMGlobalBaseRegPass());
    165   return false;
    166 }
    167 
    168 bool ARMPassConfig::addPreRegAlloc() {
    169   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    170   if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
    171     addPass(createARMLoadStoreOptimizationPass(true));
    172   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
    173     addPass(createMLxExpansionPass());
    174   // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
    175   // enabled when NEON is available.
    176   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA15() &&
    177     getARMSubtarget().hasNEON() && !DisableA15SDOptimization) {
    178     addPass(createA15SDOptimizerPass());
    179   }
    180   return true;
    181 }
    182 
    183 bool ARMPassConfig::addPreSched2() {
    184   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    185   if (getOptLevel() != CodeGenOpt::None) {
    186     if (!getARMSubtarget().isThumb1Only()) {
    187       addPass(createARMLoadStoreOptimizationPass());
    188       printAndVerify("After ARM load / store optimizer");
    189     }
    190     if (getARMSubtarget().hasNEON())
    191       addPass(createExecutionDependencyFixPass(&ARM::DPRRegClass));
    192   }
    193 
    194   // Expand some pseudo instructions into multiple instructions to allow
    195   // proper scheduling.
    196   addPass(createARMExpandPseudoPass());
    197 
    198   if (getOptLevel() != CodeGenOpt::None) {
    199     if (!getARMSubtarget().isThumb1Only())
    200       addPass(&IfConverterID);
    201   }
    202   if (getARMSubtarget().isThumb2())
    203     addPass(createThumb2ITBlockPass());
    204 
    205   return true;
    206 }
    207 
    208 bool ARMPassConfig::addPreEmitPass() {
    209   if (getARMSubtarget().isThumb2()) {
    210     if (!getARMSubtarget().prefers32BitThumb())
    211       addPass(createThumb2SizeReductionPass());
    212 
    213     // Constant island pass work on unbundled instructions.
    214     addPass(&UnpackMachineBundlesID);
    215   }
    216 
    217   addPass(createARMConstantIslandPass());
    218 
    219   return true;
    220 }
    221 
    222 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
    223                                           JITCodeEmitter &JCE) {
    224   // Machine code emitter pass for ARM.
    225   PM.add(createARMJITCodeEmitterPass(*this, JCE));
    226   return false;
    227 }
    228