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 /// TargetMachine ctor - Create an ARM architecture model.
     38 ///
     39 ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, StringRef TT,
     40                                            StringRef CPU, StringRef FS,
     41                                            Reloc::Model RM, CodeModel::Model CM)
     42   : LLVMTargetMachine(T, TT, CPU, FS, RM, CM),
     43     Subtarget(TT, CPU, FS),
     44     JITInfo(),
     45     InstrItins(Subtarget.getInstrItineraryData()) {
     46   // Default to soft float ABI
     47   if (FloatABIType == FloatABI::Default)
     48     FloatABIType = FloatABI::Soft;
     49 }
     50 
     51 ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
     52                                    StringRef CPU, StringRef FS,
     53                                    Reloc::Model RM, CodeModel::Model CM)
     54   : ARMBaseTargetMachine(T, TT, CPU, FS, RM, CM), InstrInfo(Subtarget),
     55     DataLayout(Subtarget.isAPCS_ABI() ?
     56                std::string("e-p:32:32-f64:32:64-i64:32:64-"
     57                            "v128:32:128-v64:32:64-n32-S32") :
     58                Subtarget.isAAPCS_ABI() ?
     59                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     60                            "v128:64:128-v64:64:64-n32-S64") :
     61                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     62                            "v128:64:128-v64:64:64-n32-S32")),
     63     ELFWriterInfo(*this),
     64     TLInfo(*this),
     65     TSInfo(*this),
     66     FrameLowering(Subtarget) {
     67   if (!Subtarget.hasARMOps())
     68     report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not "
     69                        "support ARM mode execution!");
     70 }
     71 
     72 ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
     73                                        StringRef CPU, StringRef FS,
     74                                        Reloc::Model RM, CodeModel::Model CM)
     75   : ARMBaseTargetMachine(T, TT, CPU, FS, RM, CM),
     76     InstrInfo(Subtarget.hasThumb2()
     77               ? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
     78               : ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
     79     DataLayout(Subtarget.isAPCS_ABI() ?
     80                std::string("e-p:32:32-f64:32:64-i64:32:64-"
     81                            "i16:16:32-i8:8:32-i1:8:32-"
     82                            "v128:32:128-v64:32:64-a:0:32-n32-S32") :
     83                Subtarget.isAAPCS_ABI() ?
     84                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     85                            "i16:16:32-i8:8:32-i1:8:32-"
     86                            "v128:64:128-v64:64:64-a:0:32-n32-S64") :
     87                std::string("e-p:32:32-f64:64:64-i64:64:64-"
     88                            "i16:16:32-i8:8:32-i1:8:32-"
     89                            "v128:64:128-v64:64:64-a:0:32-n32-S32")),
     90     ELFWriterInfo(*this),
     91     TLInfo(*this),
     92     TSInfo(*this),
     93     FrameLowering(Subtarget.hasThumb2()
     94               ? new ARMFrameLowering(Subtarget)
     95               : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) {
     96 }
     97 
     98 bool ARMBaseTargetMachine::addPreISel(PassManagerBase &PM,
     99                                       CodeGenOpt::Level OptLevel) {
    100   if (OptLevel != CodeGenOpt::None && EnableGlobalMerge)
    101     PM.add(createGlobalMergePass(getTargetLowering()));
    102 
    103   return false;
    104 }
    105 
    106 bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
    107                                            CodeGenOpt::Level OptLevel) {
    108   PM.add(createARMISelDag(*this, OptLevel));
    109   return false;
    110 }
    111 
    112 bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
    113                                           CodeGenOpt::Level OptLevel) {
    114   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    115   if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
    116     PM.add(createARMLoadStoreOptimizationPass(true));
    117   if (OptLevel != CodeGenOpt::None && Subtarget.isCortexA9())
    118     PM.add(createMLxExpansionPass());
    119   return true;
    120 }
    121 
    122 bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM,
    123                                         CodeGenOpt::Level OptLevel) {
    124   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
    125   if (OptLevel != CodeGenOpt::None) {
    126     if (!Subtarget.isThumb1Only())
    127       PM.add(createARMLoadStoreOptimizationPass());
    128     if (Subtarget.hasNEON())
    129       PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass));
    130   }
    131 
    132   // Expand some pseudo instructions into multiple instructions to allow
    133   // proper scheduling.
    134   PM.add(createARMExpandPseudoPass());
    135 
    136   if (OptLevel != CodeGenOpt::None) {
    137     if (!Subtarget.isThumb1Only())
    138       PM.add(createIfConverterPass());
    139   }
    140   if (Subtarget.isThumb2())
    141     PM.add(createThumb2ITBlockPass());
    142 
    143   return true;
    144 }
    145 
    146 bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
    147                                           CodeGenOpt::Level OptLevel) {
    148   if (Subtarget.isThumb2() && !Subtarget.prefers32BitThumb())
    149     PM.add(createThumb2SizeReductionPass());
    150 
    151   PM.add(createARMConstantIslandPass());
    152   return true;
    153 }
    154 
    155 bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
    156                                           CodeGenOpt::Level OptLevel,
    157                                           JITCodeEmitter &JCE) {
    158   // Machine code emitter pass for ARM.
    159   PM.add(createARMJITCodeEmitterPass(*this, JCE));
    160   return false;
    161 }
    162