diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h --- a/llvm/lib/Target/PowerPC/PPCSubtarget.h +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h @@ -116,7 +116,8 @@ /// This constructor initializes the data members to match that /// of the specified triple. /// - PPCSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, + PPCSubtarget(const Triple &TT, const std::string &CPU, + const std::string &TuneCPU, const std::string &FS, const PPCTargetMachine &TM); /// ParseSubtargetFeatures - Parses features string setting specified @@ -153,13 +154,16 @@ } const PPCTargetMachine &getTargetMachine() const { return TM; } - /// initializeSubtargetDependencies - Initializes using a CPU and feature string - /// so that we can use initializer lists for subtarget initialization. - PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); + /// initializeSubtargetDependencies - Initializes using a CPU, a TuneCPU, and + /// feature string so that we can use initializer lists for subtarget + /// initialization. + PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, + StringRef TuneCPU, + StringRef FS); private: void initializeEnvironment(); - void initSubtargetFeatures(StringRef CPU, StringRef FS); + void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); public: /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp --- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -48,18 +48,20 @@ cl::init(false), cl::Hidden); PPCSubtarget &PPCSubtarget::initializeSubtargetDependencies(StringRef CPU, + StringRef TuneCPU, StringRef FS) { initializeEnvironment(); - initSubtargetFeatures(CPU, FS); + initSubtargetFeatures(CPU, TuneCPU, FS); return *this; } PPCSubtarget::PPCSubtarget(const Triple &TT, const std::string &CPU, - const std::string &FS, const PPCTargetMachine &TM) - : PPCGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TargetTriple(TT), + const std::string &TuneCPU, const std::string &FS, + const PPCTargetMachine &TM) + : PPCGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT), IsPPC64(TargetTriple.getArch() == Triple::ppc64 || TargetTriple.getArch() == Triple::ppc64le), - TM(TM), FrameLowering(initializeSubtargetDependencies(CPU, FS)), + TM(TM), FrameLowering(initializeSubtargetDependencies(CPU, TuneCPU, FS)), InstrInfo(*this), TLInfo(TM, *this) { CallLoweringInfo.reset(new PPCCallLowering(*getTargetLowering())); Legalizer.reset(new PPCLegalizerInfo(*this)); @@ -76,7 +78,8 @@ HasPOPCNTD = POPCNTD_Unavailable; } -void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { +void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, + StringRef FS) { // Determine default and user specified characteristics std::string CPUName = std::string(CPU); if (CPUName.empty() || CPU == "generic") { @@ -89,11 +92,14 @@ CPUName = "generic"; } + // Determine the CPU to schedule for. + if (TuneCPU.empty()) TuneCPU = CPUName; + // Initialize scheduling itinerary for the specified CPU. InstrItins = getInstrItineraryForCPU(CPUName); // Parse features string. - ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS); + ParseSubtargetFeatures(CPUName, TuneCPU, FS); // If the user requested use of 64-bit regs, but the cpu selected doesn't // support it, ignore. diff --git a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp --- a/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -341,10 +341,13 @@ const PPCSubtarget * PPCTargetMachine::getSubtargetImpl(const Function &F) const { Attribute CPUAttr = F.getFnAttribute("target-cpu"); + Attribute TuneAttr = F.getFnAttribute("tune-cpu"); Attribute FSAttr = F.getFnAttribute("target-features"); std::string CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; + std::string TuneCPU = + TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; std::string FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; @@ -359,14 +362,14 @@ if (SoftFloat) FS += FS.empty() ? "-hard-float" : ",-hard-float"; - auto &I = SubtargetMap[CPU + FS]; + auto &I = SubtargetMap[CPU + TuneCPU + FS]; if (!I) { // This needs to be done before we create a new subtarget since any // creation will depend on the TM and the code generation flags on the // function that reside in TargetOptions. resetTargetOptions(F); I = std::make_unique( - TargetTriple, CPU, + TargetTriple, CPU, TuneCPU, // FIXME: It would be good to have the subtarget additions here // not necessary. Anything that turns them on/off (overrides) ends // up being put at the end of the feature string, but the defaults