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 "ARMFrameLowering.h"
     15 #include "ARM.h"
     16 #include "llvm/PassManager.h"
     17 #include "llvm/CodeGen/Passes.h"
     18 #include "llvm/MC/MCAsmInfo.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 extern "C" void LLVMInitializeARMTarget() {
     32   // Register the target.
     33   RegisterTargetMachine<ARMTargetMachine> X(TheARMTarget);
     34   RegisterTargetMachine<ThumbTargetMachine> Y(TheThumbTarget);
     35 }
     36 
     37 
     38 /// TargetMachine ctor - Create an ARM architecture model.
     39 ///
     40 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
     41                                            StringRef CPU, StringRef FS,
     42                                            const TargetOptions &Options,
     43                                            Reloc::Model RM, CodeModel::Model CM,
     44                                            CodeGenOpt::Level OL)
     45   : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
     46     Subtarget(TT, CPU, FS),
     47     JITInfo(),
     48     InstrItins(Subtarget.getInstrItineraryData()) {
     49   // Default to soft float ABI
     50   if (Options.FloatABIType == FloatABI::Default)
     51     this->Options.FloatABIType = FloatABI::Soft;
     52 }
     53 
     54 void ARMTargetMachine::anchor() { }
     55 
     56 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
     57                                    StringRef CPU, StringRef FS,
     58                                    const TargetOptions &Options,
     59                                    Reloc::Model RM, CodeModel::Model CM,
     60                                    CodeGenOpt::Level OL)
     61   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
     62     InstrInfo(Subtarget),
     63     DataLayout(Subtarget.isAPCS_ABI() ?
     64                std::string("e-p:32:32-f64:32:64-i64:32:64-"
     65                            "v128:32:128-v64:32:64-n32-S32") :
     66                Subtarget.isAAPCS_ABI() ?
     67                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     68                            "v128:64:128-v64:64:64-n32-S64") :
     69                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     70                            "v128:64:128-v64:64:64-n32-S32")),
     71     ELFWriterInfo(*this),
     72     TLInfo(*this),
     73     TSInfo(*this),
     74     FrameLowering(Subtarget) {
     75   if (!Subtarget.hasARMOps())
     76     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
     77                        "support ARM mode execution!");
     78 }
     79 
     80 void ThumbTargetMachine::anchor() { }
     81 
     82 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
     83                                        StringRef CPU, StringRef FS,
     84                                        const TargetOptions &Options,
     85                                        Reloc::Model RM, CodeModel::Model CM,
     86                                        CodeGenOpt::Level OL)
     87   : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
     88     InstrInfo(Subtarget.hasThumb2()
     89               ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
     90               : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
     91     DataLayout(Subtarget.isAPCS_ABI() ?
     92                std::string("e-p:32:32-f64:32:64-i64:32:64-"
     93                            "i16:16:32-i8:8:32-i1:8:32-"
     94                            "v128:32:128-v64:32:64-a:0:32-n32-S32") :
     95                Subtarget.isAAPCS_ABI() ?
     96                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     97                            "i16:16:32-i8:8:32-i1:8:32-"
     98                            "v128:64:128-v64:64:64-a:0:32-n32-S64") :
     99                std::string("e-p:32:32-f64:64:64-i64:64:64-"
    100                            "i16:16:32-i8:8:32-i1:8:32-"
    101                            "v128:64:128-v64:64:64-a:0:32-n32-S32")),
    102     ELFWriterInfo(*this),
    103     TLInfo(*this),
    104     TSInfo(*this),
    105     FrameLowering(Subtarget.hasThumb2()
    106               ? new ARMFrameLowering(Subtarget)
    107               : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
    108 }
    109 
    110 namespace {
    111 /// ARM Code Generator Pass Configuration Options.
    112 class ARMPassConfig : public TargetPassConfig {
    113 public:
    114   ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM)
    115     : TargetPassConfig(TM, PM) {}
    116 
    117   ARMBaseTargetMachine &getARMTargetMachine() const {
    118     return getTM<ARMBaseTargetMachine>();
    119   }
    120 
    121   const ARMSubtarget &getARMSubtarget() const {
    122     return *getARMTargetMachine().getSubtargetImpl();
    123   }
    124 
    125   virtual bool addPreISel();
    126   virtual bool addInstSelector();
    127   virtual bool addPreRegAlloc();
    128   virtual bool addPreSched2();
    129   virtual bool addPreEmitPass();
    130 };
    131 } // namespace
    132 
    133 TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
    134   return new ARMPassConfig(this, PM);
    135 }
    136 
    137 bool ARMPassConfig::addPreISel() {
    138   if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge)
    139     PM.add(createGlobalMergePass(TM->getTargetLowering()));
    140 
    141   return false;
    142 }
    143 
    144 bool ARMPassConfig::addInstSelector() {
    145   PM.add(createARMISelDag(getARMTargetMachine(), getOptLevel()));
    146   return false;
    147 }
    148 
    149 bool ARMPassConfig::addPreRegAlloc() {
    150   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    151   if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only())
    152     PM.add(createARMLoadStoreOptimizationPass(true));
    153   if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9())
    154     PM.add(createMLxExpansionPass());
    155   return true;
    156 }
    157 
    158 bool ARMPassConfig::addPreSched2() {
    159   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    160   if (getOptLevel() != CodeGenOpt::None) {
    161     if (!getARMSubtarget().isThumb1Only()) {
    162       PM.add(createARMLoadStoreOptimizationPass());
    163       printAndVerify("After ARM load / store optimizer");
    164     }
    165     if (getARMSubtarget().hasNEON())
    166       PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass));
    167   }
    168 
    169   // Expand some pseudo instructions into multiple instructions to allow
    170   // proper scheduling.
    171   PM.add(createARMExpandPseudoPass());
    172 
    173   if (getOptLevel() != CodeGenOpt::None) {
    174     if (!getARMSubtarget().isThumb1Only())
    175       addPass(IfConverterID);
    176   }
    177   if (getARMSubtarget().isThumb2())
    178     PM.add(createThumb2ITBlockPass());
    179 
    180   return true;
    181 }
    182 
    183 bool ARMPassConfig::addPreEmitPass() {
    184   if (getARMSubtarget().isThumb2()) {
    185     if (!getARMSubtarget().prefers32BitThumb())
    186       PM.add(createThumb2SizeReductionPass());
    187 
    188     // Constant island pass work on unbundled instructions.
    189     addPass(UnpackMachineBundlesID);
    190   }
    191 
    192   PM.add(createARMConstantIslandPass());
    193 
    194   return true;
    195 }
    196 
    197 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
    198                                           JITCodeEmitter &JCE) {
    199   // Machine code emitter pass for ARM.
    200   PM.add(createARMJITCodeEmitterPass(*this, JCE));
    201   return false;
    202 }
    203