1 //===-- PPCTargetMachine.cpp - Define TargetMachine for PowerPC -----------===// 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 // Top-level implementation for the PowerPC target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "PPCTargetMachine.h" 15 #include "PPC.h" 16 #include "llvm/CodeGen/Passes.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/MC/MCStreamer.h" 19 #include "llvm/PassManager.h" 20 #include "llvm/Support/CommandLine.h" 21 #include "llvm/Support/FormattedStream.h" 22 #include "llvm/Support/TargetRegistry.h" 23 #include "llvm/Target/TargetOptions.h" 24 using namespace llvm; 25 26 static cl:: 27 opt<bool> DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden, 28 cl::desc("Disable CTR loops for PPC")); 29 30 static cl::opt<bool> 31 VSXFMAMutateEarly("schedule-ppc-vsx-fma-mutation-early", 32 cl::Hidden, cl::desc("Schedule VSX FMA instruction mutation early")); 33 34 extern "C" void LLVMInitializePowerPCTarget() { 35 // Register the targets 36 RegisterTargetMachine<PPC32TargetMachine> A(ThePPC32Target); 37 RegisterTargetMachine<PPC64TargetMachine> B(ThePPC64Target); 38 RegisterTargetMachine<PPC64TargetMachine> C(ThePPC64LETarget); 39 } 40 41 static std::string computeFSAdditions(StringRef FS, CodeGenOpt::Level OL, StringRef TT) { 42 std::string FullFS = FS; 43 Triple TargetTriple(TT); 44 45 // Make sure 64-bit features are available when CPUname is generic 46 if (TargetTriple.getArch() == Triple::ppc64 || 47 TargetTriple.getArch() == Triple::ppc64le) { 48 if (!FullFS.empty()) 49 FullFS = "+64bit," + FullFS; 50 else 51 FullFS = "+64bit"; 52 } 53 54 if (OL >= CodeGenOpt::Default) { 55 if (!FullFS.empty()) 56 FullFS = "+crbits," + FullFS; 57 else 58 FullFS = "+crbits"; 59 } 60 return FullFS; 61 } 62 63 // The FeatureString here is a little subtle. We are modifying the feature string 64 // with what are (currently) non-function specific overrides as it goes into the 65 // LLVMTargetMachine constructor and then using the stored value in the 66 // Subtarget constructor below it. 67 PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, StringRef CPU, 68 StringRef FS, const TargetOptions &Options, 69 Reloc::Model RM, CodeModel::Model CM, 70 CodeGenOpt::Level OL) 71 : LLVMTargetMachine(T, TT, CPU, computeFSAdditions(FS, OL, TT), Options, RM, 72 CM, OL), 73 Subtarget(TT, CPU, TargetFS, *this) { 74 initAsmInfo(); 75 } 76 77 void PPC32TargetMachine::anchor() { } 78 79 PPC32TargetMachine::PPC32TargetMachine(const Target &T, StringRef TT, 80 StringRef CPU, StringRef FS, 81 const TargetOptions &Options, 82 Reloc::Model RM, CodeModel::Model CM, 83 CodeGenOpt::Level OL) 84 : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) { 85 } 86 87 void PPC64TargetMachine::anchor() { } 88 89 PPC64TargetMachine::PPC64TargetMachine(const Target &T, StringRef TT, 90 StringRef CPU, StringRef FS, 91 const TargetOptions &Options, 92 Reloc::Model RM, CodeModel::Model CM, 93 CodeGenOpt::Level OL) 94 : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) { 95 } 96 97 const PPCSubtarget * 98 PPCTargetMachine::getSubtargetImpl(const Function &F) const { 99 AttributeSet FnAttrs = F.getAttributes(); 100 Attribute CPUAttr = 101 FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-cpu"); 102 Attribute FSAttr = 103 FnAttrs.getAttribute(AttributeSet::FunctionIndex, "target-features"); 104 105 std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 106 ? CPUAttr.getValueAsString().str() 107 : TargetCPU; 108 std::string FS = !FSAttr.hasAttribute(Attribute::None) 109 ? FSAttr.getValueAsString().str() 110 : TargetFS; 111 112 auto &I = SubtargetMap[CPU + FS]; 113 if (!I) { 114 // This needs to be done before we create a new subtarget since any 115 // creation will depend on the TM and the code generation flags on the 116 // function that reside in TargetOptions. 117 resetTargetOptions(F); 118 I = llvm::make_unique<PPCSubtarget>(TargetTriple, CPU, FS, *this); 119 } 120 return I.get(); 121 } 122 123 //===----------------------------------------------------------------------===// 124 // Pass Pipeline Configuration 125 //===----------------------------------------------------------------------===// 126 127 namespace { 128 /// PPC Code Generator Pass Configuration Options. 129 class PPCPassConfig : public TargetPassConfig { 130 public: 131 PPCPassConfig(PPCTargetMachine *TM, PassManagerBase &PM) 132 : TargetPassConfig(TM, PM) {} 133 134 PPCTargetMachine &getPPCTargetMachine() const { 135 return getTM<PPCTargetMachine>(); 136 } 137 138 const PPCSubtarget &getPPCSubtarget() const { 139 return *getPPCTargetMachine().getSubtargetImpl(); 140 } 141 142 void addIRPasses() override; 143 bool addPreISel() override; 144 bool addILPOpts() override; 145 bool addInstSelector() override; 146 bool addPreRegAlloc() override; 147 bool addPreSched2() override; 148 bool addPreEmitPass() override; 149 }; 150 } // namespace 151 152 TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) { 153 return new PPCPassConfig(this, PM); 154 } 155 156 void PPCPassConfig::addIRPasses() { 157 addPass(createAtomicExpandPass(&getPPCTargetMachine())); 158 TargetPassConfig::addIRPasses(); 159 } 160 161 bool PPCPassConfig::addPreISel() { 162 if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None) 163 addPass(createPPCCTRLoops(getPPCTargetMachine())); 164 165 return false; 166 } 167 168 bool PPCPassConfig::addILPOpts() { 169 addPass(&EarlyIfConverterID); 170 return true; 171 } 172 173 bool PPCPassConfig::addInstSelector() { 174 // Install an instruction selector. 175 addPass(createPPCISelDag(getPPCTargetMachine())); 176 177 #ifndef NDEBUG 178 if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None) 179 addPass(createPPCCTRLoopsVerify()); 180 #endif 181 182 addPass(createPPCVSXCopyPass()); 183 return false; 184 } 185 186 bool PPCPassConfig::addPreRegAlloc() { 187 initializePPCVSXFMAMutatePass(*PassRegistry::getPassRegistry()); 188 insertPass(VSXFMAMutateEarly ? &RegisterCoalescerID : &MachineSchedulerID, 189 &PPCVSXFMAMutateID); 190 return false; 191 } 192 193 bool PPCPassConfig::addPreSched2() { 194 addPass(createPPCVSXCopyCleanupPass()); 195 196 if (getOptLevel() != CodeGenOpt::None) 197 addPass(&IfConverterID); 198 199 return true; 200 } 201 202 bool PPCPassConfig::addPreEmitPass() { 203 if (getOptLevel() != CodeGenOpt::None) 204 addPass(createPPCEarlyReturnPass()); 205 // Must run branch selection immediately preceding the asm printer. 206 addPass(createPPCBranchSelectionPass()); 207 return false; 208 } 209 210 void PPCTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 211 // Add first the target-independent BasicTTI pass, then our PPC pass. This 212 // allows the PPC pass to delegate to the target independent layer when 213 // appropriate. 214 PM.add(createBasicTargetTransformInfoPass(this)); 215 PM.add(createPPCTargetTransformInfoPass(this)); 216 } 217 218