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