opt<bool> DisableCTRLoops("disable-ppc-ctrloops", cl::Hidden,
cl::desc("Disable CTR loops for PPC"));
+static cl::opt<bool>
+VSXFMAMutateEarly("schedule-ppc-vsx-fma-mutation-early",
+ cl::Hidden, cl::desc("Schedule VSX FMA instruction mutation early"));
+
extern "C" void LLVMInitializePowerPCTarget() {
// Register the targets
RegisterTargetMachine<PPC32TargetMachine> A(ThePPC32Target);
RegisterTargetMachine<PPC64TargetMachine> C(ThePPC64LETarget);
}
-/// Return the datalayout string of a subtarget.
-static std::string getDataLayoutString(const PPCSubtarget &ST) {
- const Triple &T = ST.getTargetTriple();
-
- // PPC is big endian
- std::string Ret = "E";
-
- // PPC64 has 64 bit pointers, PPC32 has 32 bit pointers.
- if (ST.isPPC64())
- Ret += "-p:64:64";
- else
- Ret += "-p:32:32";
-
- // Note, the alignment values for f64 and i64 on ppc64 in Darwin
- // documentation are wrong; these are correct (i.e. "what gcc does").
- Ret += "-f64:64:64-i64:64:64";
-
- // Set support for 128 floats depending on the ABI.
- if (ST.isPPC64() && ST.isSVR4ABI()) {
- if (T.getOS() != llvm::Triple::FreeBSD)
- Ret += "-f128:128:128";
- } else {
- Ret += "-f128:64:128";
+static std::string computeFSAdditions(StringRef FS, CodeGenOpt::Level OL, StringRef TT) {
+ std::string FullFS = FS;
+ Triple TargetTriple(TT);
+
+ // Make sure 64-bit features are available when CPUname is generic
+ if (TargetTriple.getArch() == Triple::ppc64 ||
+ TargetTriple.getArch() == Triple::ppc64le) {
+ if (!FullFS.empty())
+ FullFS = "+64bit," + FullFS;
+ else
+ FullFS = "+64bit";
}
- // Some ABIs support 128 bit vectors.
- if (ST.isPPC64() && ST.isSVR4ABI())
- Ret += "-v128:128:128";
-
- // PPC64 has 32 and 64 bit register, PPC32 has only 32 bit ones.
- if (ST.isPPC64())
- Ret += "-n32:64";
- else
- Ret += "-n32";
-
- return Ret;
+ if (OL >= CodeGenOpt::Default) {
+ if (!FullFS.empty())
+ FullFS = "+crbits," + FullFS;
+ else
+ FullFS = "+crbits";
+ }
+ return FullFS;
}
-PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT,
- StringRef CPU, StringRef FS,
- const TargetOptions &Options,
+// The FeatureString here is a little subtle. We are modifying the feature string
+// with what are (currently) non-function specific overrides as it goes into the
+// LLVMTargetMachine constructor and then using the stored value in the
+// Subtarget constructor below it.
+PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, StringRef CPU,
+ StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL,
- bool is64Bit)
- : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
- Subtarget(TT, CPU, FS, is64Bit),
- DL(getDataLayoutString(Subtarget)), InstrInfo(*this),
- FrameLowering(Subtarget), JITInfo(*this, is64Bit),
- TLInfo(*this), TSInfo(*this),
- InstrItins(Subtarget.getInstrItineraryData()) {
-
- // The binutils for the BG/P are too old for CFI.
- if (Subtarget.isBGP())
- setMCUseCFI(false);
+ CodeGenOpt::Level OL)
+ : LLVMTargetMachine(T, TT, CPU, computeFSAdditions(FS, OL, TT), Options, RM,
+ CM, OL),
+ Subtarget(TT, CPU, TargetFS, *this, OL) {
initAsmInfo();
}
const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
- : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {
+ : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {
}
void PPC64TargetMachine::anchor() { }
const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
- : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {
+ : PPCTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {
}
return *getPPCTargetMachine().getSubtargetImpl();
}
- virtual bool addPreISel();
- virtual bool addILPOpts();
- virtual bool addInstSelector();
- virtual bool addPreSched2();
- virtual bool addPreEmitPass();
+ void addIRPasses() override;
+ bool addPreISel() override;
+ bool addILPOpts() override;
+ bool addInstSelector() override;
+ bool addPreRegAlloc() override;
+ bool addPreSched2() override;
+ bool addPreEmitPass() override;
};
} // namespace
return new PPCPassConfig(this, PM);
}
+void PPCPassConfig::addIRPasses() {
+ addPass(createAtomicExpandPass(&getPPCTargetMachine()));
+ TargetPassConfig::addIRPasses();
+}
+
bool PPCPassConfig::addPreISel() {
if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None)
addPass(createPPCCTRLoops(getPPCTargetMachine()));
}
bool PPCPassConfig::addILPOpts() {
- if (getPPCSubtarget().hasISEL()) {
- addPass(&EarlyIfConverterID);
- return true;
- }
-
- return false;
+ addPass(&EarlyIfConverterID);
+ return true;
}
bool PPCPassConfig::addInstSelector() {
addPass(createPPCCTRLoopsVerify());
#endif
+ addPass(createPPCVSXCopyPass());
+ return false;
+}
+
+bool PPCPassConfig::addPreRegAlloc() {
+ initializePPCVSXFMAMutatePass(*PassRegistry::getPassRegistry());
+ insertPass(VSXFMAMutateEarly ? &RegisterCoalescerID : &MachineSchedulerID,
+ &PPCVSXFMAMutateID);
return false;
}
bool PPCPassConfig::addPreSched2() {
+ addPass(createPPCVSXCopyCleanupPass());
+
if (getOptLevel() != CodeGenOpt::None)
addPass(&IfConverterID);
return false;
}
-bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM,
- JITCodeEmitter &JCE) {
- // Inform the subtarget that we are in JIT mode. FIXME: does this break macho
- // writing?
- Subtarget.SetJITMode();
-
- // Machine code emitter pass for PowerPC.
- PM.add(createPPCJITCodeEmitterPass(*this, JCE));
-
- return false;
-}
-
void PPCTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
// Add first the target-independent BasicTTI pass, then our PPC pass. This
// allows the PPC pass to delegate to the target independent layer when