diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2011-07-01 20:45:01 +0000 | 
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2011-07-01 20:45:01 +0000 | 
| commit | 94214703d97d8d9dfca88174ffc7e94820a85e62 (patch) | |
| tree | 92edaa7cf8adfab8d915bdb21eb1d78267faee4e | |
| parent | eb03c3b22861e5fb6459aa055378e852df29b621 (diff) | |
| download | external_llvm-94214703d97d8d9dfca88174ffc7e94820a85e62.zip external_llvm-94214703d97d8d9dfca88174ffc7e94820a85e62.tar.gz external_llvm-94214703d97d8d9dfca88174ffc7e94820a85e62.tar.bz2  | |
- Added MCSubtargetInfo to capture subtarget features and scheduling
  itineraries.
- Refactor TargetSubtarget to be based on MCSubtargetInfo.
- Change tablegen generated subtarget info to initialize MCSubtargetInfo
  and hide more details from targets.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134257 91177308-0d34-0410-b5e6-96231b3b80d8
33 files changed, 402 insertions, 102 deletions
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h new file mode 100644 index 0000000..d991f42 --- /dev/null +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -0,0 +1,61 @@ +//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the subtarget options of a Target machine. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSUBTARGET_H +#define LLVM_MC_MCSUBTARGET_H + +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/MC/MCInstrItineraries.h" + +namespace llvm { + +class StringRef; + +//===----------------------------------------------------------------------===// +/// +/// MCSubtargetInfo - Generic base class for all target subtargets. +/// +class MCSubtargetInfo { +  const SubtargetFeatureKV *ProcFeatures;  // Processor feature list +  const SubtargetFeatureKV *ProcDesc;  // Processor descriptions +  const SubtargetInfoKV *ProcItins;    // Scheduling itineraries +  const InstrStage *Stages;            // Instruction stages +  const unsigned *OperandCycles;       // Operand cycles +  const unsigned *ForwardingPathes;    // Forwarding pathes +  unsigned NumFeatures;                // Number of processor features +  unsigned NumProcs;                   // Number of processors +     +public: +  void InitMCSubtargetInfo(const SubtargetFeatureKV *PF, +                           const SubtargetFeatureKV *PD, +                           const SubtargetInfoKV *PI, const InstrStage *IS, +                           const unsigned *OC, const unsigned *FP, +                           unsigned NF, unsigned NP) { +    ProcFeatures = PF; +    ProcDesc = PD; +    ProcItins = PI; +    Stages = IS; +    OperandCycles = OC; +    ForwardingPathes = FP; +    NumFeatures = NF; +    NumProcs = NP; +  } + +  /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. +  /// +  InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Target/TargetSubtarget.h b/include/llvm/Target/TargetSubtarget.h index 22b09ba..5127a62 100644 --- a/include/llvm/Target/TargetSubtarget.h +++ b/include/llvm/Target/TargetSubtarget.h @@ -14,6 +14,7 @@  #ifndef LLVM_TARGET_TARGETSUBTARGET_H  #define LLVM_TARGET_TARGETSUBTARGET_H +#include "llvm/MC/MCSubtargetInfo.h"  #include "llvm/Target/TargetMachine.h"  namespace llvm { @@ -29,7 +30,7 @@ template <typename T> class SmallVectorImpl;  /// Target-specific options that control code generation and printing should  /// be exposed through a TargetSubtarget-derived class.  /// -class TargetSubtarget { +class TargetSubtarget : public MCSubtargetInfo {    TargetSubtarget(const TargetSubtarget&);   // DO NOT IMPLEMENT    void operator=(const TargetSubtarget&);  // DO NOT IMPLEMENT  protected: // Can only create subclasses... diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt index 00e534f..22afa7e 100644 --- a/lib/MC/CMakeLists.txt +++ b/lib/MC/CMakeLists.txt @@ -28,6 +28,7 @@ add_llvm_library(LLVMMC    MCSectionELF.cpp    MCSectionMachO.cpp    MCStreamer.cpp +  MCSubtargetInfo.cpp    MCSymbol.cpp    MCValue.cpp    MCWin64EH.cpp diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp new file mode 100644 index 0000000..c401b7e --- /dev/null +++ b/lib/MC/MCSubtargetInfo.cpp @@ -0,0 +1,44 @@ +//===-- MCSubtargetInfo.cpp - Subtarget Information -----------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCInstrItineraries.h" +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> + +using namespace llvm; + +InstrItineraryData +MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const { +  assert(ProcItins && "Instruction itineraries information not available!"); + +#ifndef NDEBUG +  for (size_t i = 1; i < NumProcs; i++) { +    assert(strcmp(ProcItins[i - 1].Key, ProcItins[i].Key) < 0 && +           "Itineraries table is not sorted"); +  } +#endif + +  // Find entry +  SubtargetInfoKV KV; +  KV.Key = CPU.data(); +  const SubtargetInfoKV *Found = +    std::lower_bound(ProcItins, ProcItins+NumProcs, KV); +  if (Found == ProcItins+NumProcs || StringRef(Found->Key) != CPU) { +    errs() << "'" << CPU +           << "' is not a recognized processor for this target" +           << " (ignoring processor)\n"; +    return InstrItineraryData(); +  } + +  return InstrItineraryData(Stages, OperandCycles, ForwardingPathes, +                            (InstrItinerary *)Found->Value); +} diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 694b313..01acde0 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -12,11 +12,17 @@  //===----------------------------------------------------------------------===//  #include "ARMSubtarget.h" -#include "ARMGenSubtarget.inc"  #include "ARMBaseRegisterInfo.h"  #include "llvm/GlobalValue.h" +#include "llvm/Target/TargetSubtarget.h"  #include "llvm/Support/CommandLine.h"  #include "llvm/ADT/SmallVector.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "ARMGenSubtarget.inc" +  using namespace llvm;  static cl::opt<bool> @@ -32,7 +38,8 @@ StrictAlign("arm-strict-align", cl::Hidden,  ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,                             const std::string &FS, bool isT) -  : ARMArchVersion(V4) +  : ARMGenSubtargetInfo() +  , ARMArchVersion(V4)    , ARMProcFamily(Others)    , ARMFPUType(None)    , UseNEONForSinglePrecisionFP(false) @@ -130,6 +137,9 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,      FSWithArch = FSWithArch + "," + FS;    ParseSubtargetFeatures(FSWithArch, CPUString); +  // Initialize scheduling itinerary for the specified CPU. +  InstrItins = getInstrItineraryForCPU(CPUString); +    // After parsing Itineraries, set ItinData.IssueWidth.    computeIssueWidth(); diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 7c93173..fbe8322 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -19,10 +19,13 @@  #include "llvm/ADT/Triple.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "ARMGenSubtarget.inc" +  namespace llvm {  class GlobalValue; -class ARMSubtarget : public TargetSubtarget { +class ARMSubtarget : public ARMGenSubtargetInfo {  protected:    enum ARMArchEnum {      V4, V4T, V5T, V5TE, V6, V6M, V6T2, V7A, V7M diff --git a/lib/Target/Alpha/AlphaSubtarget.cpp b/lib/Target/Alpha/AlphaSubtarget.cpp index 7080327..5ed2d31 100644 --- a/lib/Target/Alpha/AlphaSubtarget.cpp +++ b/lib/Target/Alpha/AlphaSubtarget.cpp @@ -14,15 +14,24 @@  #include "AlphaSubtarget.h"  #include "Alpha.h"  #include "AlphaGenSubtarget.inc" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "AlphaGenSubtarget.inc" +  using namespace llvm;  AlphaSubtarget::AlphaSubtarget(const std::string &TT, const std::string &CPU,                                 const std::string &FS) -  : HasCT(false) { +  : AlphaGenSubtargetInfo(), HasCT(false) {    std::string CPUName = CPU;    if (CPUName.empty())      CPUName = "generic";    // Parse features string.    ParseSubtargetFeatures(FS, CPUName); + +  // Initialize scheduling itinerary for the specified CPU. +  InstrItins = getInstrItineraryForCPU(CPUName);  } diff --git a/lib/Target/Alpha/AlphaSubtarget.h b/lib/Target/Alpha/AlphaSubtarget.h index b1ccf26..0bd161c 100644 --- a/lib/Target/Alpha/AlphaSubtarget.h +++ b/lib/Target/Alpha/AlphaSubtarget.h @@ -18,9 +18,12 @@  #include "llvm/MC/MCInstrItineraries.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "AlphaGenSubtarget.inc" +  namespace llvm { -class AlphaSubtarget : public TargetSubtarget { +class AlphaSubtarget : public AlphaGenSubtargetInfo {  protected:    bool HasCT; diff --git a/lib/Target/Blackfin/BlackfinSubtarget.cpp b/lib/Target/Blackfin/BlackfinSubtarget.cpp index 5092026..f0328e0 100644 --- a/lib/Target/Blackfin/BlackfinSubtarget.cpp +++ b/lib/Target/Blackfin/BlackfinSubtarget.cpp @@ -12,6 +12,10 @@  //===----------------------------------------------------------------------===//  #include "BlackfinSubtarget.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC  #include "BlackfinGenSubtarget.inc"  using namespace llvm; @@ -19,7 +23,7 @@ using namespace llvm;  BlackfinSubtarget::BlackfinSubtarget(const std::string &TT,                                       const std::string &CPU,                                       const std::string &FS) -  : sdram(false), +  : BlackfinGenSubtargetInfo(), sdram(false),      icplb(false),      wa_mi_shift(false),      wa_csync(false), diff --git a/lib/Target/Blackfin/BlackfinSubtarget.h b/lib/Target/Blackfin/BlackfinSubtarget.h index a1a09ec..fecd035 100644 --- a/lib/Target/Blackfin/BlackfinSubtarget.h +++ b/lib/Target/Blackfin/BlackfinSubtarget.h @@ -17,9 +17,12 @@  #include "llvm/Target/TargetSubtarget.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "BlackfinGenSubtarget.inc" +  namespace llvm { -  class BlackfinSubtarget : public TargetSubtarget { +  class BlackfinSubtarget : public BlackfinGenSubtargetInfo {      bool sdram;      bool icplb;      bool wa_mi_shift; diff --git a/lib/Target/CellSPU/SPUSubtarget.cpp b/lib/Target/CellSPU/SPUSubtarget.cpp index a1a9f51..5128767 100644 --- a/lib/Target/CellSPU/SPUSubtarget.cpp +++ b/lib/Target/CellSPU/SPUSubtarget.cpp @@ -13,14 +13,19 @@  #include "SPUSubtarget.h"  #include "SPU.h" -#include "SPUGenSubtarget.inc"  #include "llvm/ADT/SmallVector.h"  #include "SPURegisterInfo.h" +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "SPUGenSubtarget.inc" +  using namespace llvm;  SPUSubtarget::SPUSubtarget(const std::string &TT, const std::string &CPU,                             const std::string &FS) : +  SPUGenSubtargetInfo(),    StackAlignment(16),    ProcDirective(SPU::DEFAULT_PROC),    UseLargeMem(false) @@ -31,6 +36,9 @@ SPUSubtarget::SPUSubtarget(const std::string &TT, const std::string &CPU,    // Parse features string.    ParseSubtargetFeatures(FS, default_cpu); + +  // Initialize scheduling itinerary for the specified CPU. +  InstrItins = getInstrItineraryForCPU(default_cpu);  }  /// SetJITMode - This is called to inform the subtarget info that we are diff --git a/lib/Target/CellSPU/SPUSubtarget.h b/lib/Target/CellSPU/SPUSubtarget.h index 69a60db..2e5934b 100644 --- a/lib/Target/CellSPU/SPUSubtarget.h +++ b/lib/Target/CellSPU/SPUSubtarget.h @@ -18,6 +18,9 @@  #include "llvm/MC/MCInstrItineraries.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "SPUGenSubtarget.inc" +  namespace llvm {    class GlobalValue; @@ -28,7 +31,7 @@ namespace llvm {      };    } -  class SPUSubtarget : public TargetSubtarget { +  class SPUSubtarget : public SPUGenSubtargetInfo {    protected:      /// stackAlignment - The minimum alignment known to hold of the stack frame      /// on entry to the function and which must be maintained by every function. diff --git a/lib/Target/MBlaze/MBlazeSubtarget.cpp b/lib/Target/MBlaze/MBlazeSubtarget.cpp index 034b5ce..0ba0bea 100644 --- a/lib/Target/MBlaze/MBlazeSubtarget.cpp +++ b/lib/Target/MBlaze/MBlazeSubtarget.cpp @@ -14,13 +14,19 @@  #include "MBlazeSubtarget.h"  #include "MBlaze.h"  #include "MBlazeRegisterInfo.h" -#include "MBlazeGenSubtarget.inc"  #include "llvm/Support/CommandLine.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "MBlazeGenSubtarget.inc" +  using namespace llvm;  MBlazeSubtarget::MBlazeSubtarget(const std::string &TT,                                   const std::string &CPU,                                   const std::string &FS): +  MBlazeGenSubtargetInfo(),    HasBarrel(false), HasDiv(false), HasMul(false), HasPatCmp(false),    HasFPU(false), HasMul64(false), HasSqrt(false)  { @@ -35,6 +41,9 @@ MBlazeSubtarget::MBlazeSubtarget(const std::string &TT,    HasItin = CPUName != "mblaze";    DEBUG(dbgs() << "CPU " << CPUName << "(" << HasItin << ")\n"); +  // Initialize scheduling itinerary for the specified CPU. +  InstrItins = getInstrItineraryForCPU(CPUName); +    // Compute the issue width of the MBlaze itineraries    computeIssueWidth();  } diff --git a/lib/Target/MBlaze/MBlazeSubtarget.h b/lib/Target/MBlaze/MBlazeSubtarget.h index f5e0b4c..63acee2 100644 --- a/lib/Target/MBlaze/MBlazeSubtarget.h +++ b/lib/Target/MBlaze/MBlazeSubtarget.h @@ -18,9 +18,12 @@  #include "llvm/MC/MCInstrItineraries.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "MBlazeGenSubtarget.inc" +  namespace llvm { -class MBlazeSubtarget : public TargetSubtarget { +class MBlazeSubtarget : public MBlazeGenSubtargetInfo {  protected:    bool HasBarrel; diff --git a/lib/Target/MSP430/MSP430Subtarget.cpp b/lib/Target/MSP430/MSP430Subtarget.cpp index a257abe..4198d20 100644 --- a/lib/Target/MSP430/MSP430Subtarget.cpp +++ b/lib/Target/MSP430/MSP430Subtarget.cpp @@ -13,6 +13,10 @@  #include "MSP430Subtarget.h"  #include "MSP430.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC  #include "MSP430GenSubtarget.inc"  using namespace llvm; diff --git a/lib/Target/MSP430/MSP430Subtarget.h b/lib/Target/MSP430/MSP430Subtarget.h index f36428a..0a508e0 100644 --- a/lib/Target/MSP430/MSP430Subtarget.h +++ b/lib/Target/MSP430/MSP430Subtarget.h @@ -16,11 +16,14 @@  #include "llvm/Target/TargetSubtarget.h" +#define GET_SUBTARGETINFO_HEADER +#include "MSP430GenSubtarget.inc" +  #include <string>  namespace llvm { -class MSP430Subtarget : public TargetSubtarget { +class MSP430Subtarget : public MSP430GenSubtargetInfo {    bool ExtendedInsts;  public:    /// This constructor initializes the data members to match that diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index 306ea11..9c69e04 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -13,11 +13,17 @@  #include "MipsSubtarget.h"  #include "Mips.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC  #include "MipsGenSubtarget.inc" +  using namespace llvm;  MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,                               const std::string &FS, bool little) : +  MipsGenSubtargetInfo(),    MipsArchVersion(Mips1), MipsABI(O32), IsLittle(little), IsSingleFloat(false),    IsFP64bit(false), IsGP64bit(false), HasVFPU(false), IsLinux(true),    HasSEInReg(false), HasCondMov(false), HasMulDivAdd(false), HasMinMax(false), @@ -31,6 +37,9 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,    // Parse features string.    ParseSubtargetFeatures(FS, CPUName); +  // Initialize scheduling itinerary for the specified CPU. +  InstrItins = getInstrItineraryForCPU(CPUName); +    // Is the target system Linux ?    if (TT.find("linux") == std::string::npos)      IsLinux = false; diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index 8acbf5b..2b7d98f 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -18,9 +18,12 @@  #include "llvm/MC/MCInstrItineraries.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "MipsGenSubtarget.inc" +  namespace llvm { -class MipsSubtarget : public TargetSubtarget { +class MipsSubtarget : public MipsGenSubtargetInfo {  public:    enum MipsABIEnum { diff --git a/lib/Target/PTX/PTXSubtarget.cpp b/lib/Target/PTX/PTXSubtarget.cpp index f8941b6..b3c8eb6 100644 --- a/lib/Target/PTX/PTXSubtarget.cpp +++ b/lib/Target/PTX/PTXSubtarget.cpp @@ -14,11 +14,17 @@  #include "PTXSubtarget.h"  #include "llvm/Support/ErrorHandling.h" +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "PTXGenSubtarget.inc" +  using namespace llvm;  PTXSubtarget::PTXSubtarget(const std::string &TT, const std::string &CPU,                             const std::string &FS, bool is64Bit) -  : PTXTarget(PTX_COMPUTE_1_0), +  : PTXGenSubtargetInfo(), +    PTXTarget(PTX_COMPUTE_1_0),      PTXVersion(PTX_VERSION_2_0),      SupportsDouble(false),      SupportsFMA(true), diff --git a/lib/Target/PTX/PTXSubtarget.h b/lib/Target/PTX/PTXSubtarget.h index 6d03377..b7b27d6 100644 --- a/lib/Target/PTX/PTXSubtarget.h +++ b/lib/Target/PTX/PTXSubtarget.h @@ -16,8 +16,11 @@  #include "llvm/Target/TargetSubtarget.h" +#define GET_SUBTARGETINFO_HEADER +#include "PTXGenSubtarget.inc" +  namespace llvm { -  class PTXSubtarget : public TargetSubtarget { +  class PTXSubtarget : public PTXGenSubtargetInfo {      public:        /** diff --git a/lib/Target/PowerPC/PPCSubtarget.cpp b/lib/Target/PowerPC/PPCSubtarget.cpp index bcc4c21..ef8386c 100644 --- a/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/lib/Target/PowerPC/PPCSubtarget.cpp @@ -15,8 +15,13 @@  #include "PPC.h"  #include "llvm/GlobalValue.h"  #include "llvm/Target/TargetMachine.h" -#include "PPCGenSubtarget.inc"  #include <cstdlib> + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "PPCGenSubtarget.inc" +  using namespace llvm;  #if defined(__APPLE__) @@ -59,7 +64,8 @@ static const char *GetCurrentPowerPCCPU() {  PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU,                             const std::string &FS, bool is64Bit) -  : StackAlignment(16) +  : PPCGenSubtargetInfo() +  , StackAlignment(16)    , DarwinDirective(PPC::DIR_NONE)    , IsGigaProcessor(false)    , Has64BitSupport(false) @@ -84,6 +90,9 @@ PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU,    // Parse features string.    ParseSubtargetFeatures(FS, CPUName); +  // Initialize scheduling itinerary for the specified CPU. +  InstrItins = getInstrItineraryForCPU(CPUName); +    // If we are generating code for ppc64, verify that options make sense.    if (is64Bit) {      Has64BitSupport = true; diff --git a/lib/Target/PowerPC/PPCSubtarget.h b/lib/Target/PowerPC/PPCSubtarget.h index 55c3fef..b4e5758 100644 --- a/lib/Target/PowerPC/PPCSubtarget.h +++ b/lib/Target/PowerPC/PPCSubtarget.h @@ -19,6 +19,9 @@  #include "llvm/ADT/Triple.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "PPCGenSubtarget.inc" +  // GCC #defines PPC on Linux but we use it as our namespace name  #undef PPC @@ -42,7 +45,7 @@ namespace PPC {  class GlobalValue;  class TargetMachine; -class PPCSubtarget : public TargetSubtarget { +class PPCSubtarget : public PPCGenSubtargetInfo {  protected:    /// stackAlignment - The minimum alignment known to hold of the stack frame on    /// entry to the function and which must be maintained by every function. diff --git a/lib/Target/Sparc/SparcSubtarget.cpp b/lib/Target/Sparc/SparcSubtarget.cpp index 06bfc64..3f7b23a 100644 --- a/lib/Target/Sparc/SparcSubtarget.cpp +++ b/lib/Target/Sparc/SparcSubtarget.cpp @@ -12,11 +12,17 @@  //===----------------------------------------------------------------------===//  #include "SparcSubtarget.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC  #include "SparcGenSubtarget.inc" +  using namespace llvm;  SparcSubtarget::SparcSubtarget(const std::string &TT, const std::string &CPU,                                 const std::string &FS,  bool is64Bit) : +  SparcGenSubtargetInfo(),    IsV9(false),    V8DeprecatedInsts(false),    IsVIS(false), diff --git a/lib/Target/Sparc/SparcSubtarget.h b/lib/Target/Sparc/SparcSubtarget.h index eabf390..af35e4c 100644 --- a/lib/Target/Sparc/SparcSubtarget.h +++ b/lib/Target/Sparc/SparcSubtarget.h @@ -17,9 +17,12 @@  #include "llvm/Target/TargetSubtarget.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "SparcGenSubtarget.inc" +  namespace llvm { -class SparcSubtarget : public TargetSubtarget { +class SparcSubtarget : public SparcGenSubtargetInfo {    bool IsV9;    bool V8DeprecatedInsts;    bool IsVIS; diff --git a/lib/Target/SystemZ/SystemZSubtarget.cpp b/lib/Target/SystemZ/SystemZSubtarget.cpp index 95521b2..33c9906 100644 --- a/lib/Target/SystemZ/SystemZSubtarget.cpp +++ b/lib/Target/SystemZ/SystemZSubtarget.cpp @@ -13,16 +13,20 @@  #include "SystemZSubtarget.h"  #include "SystemZ.h" -#include "SystemZGenSubtarget.inc"  #include "llvm/GlobalValue.h"  #include "llvm/Target/TargetMachine.h" +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "SystemZGenSubtarget.inc" +  using namespace llvm;  SystemZSubtarget::SystemZSubtarget(const std::string &TT,                                      const std::string &CPU,                                     const std::string &FS): -  HasZ10Insts(false) { +  SystemZGenSubtargetInfo(), HasZ10Insts(false) {    std::string CPUName = CPU;    if (CPUName.empty())      CPUName = "z9"; diff --git a/lib/Target/SystemZ/SystemZSubtarget.h b/lib/Target/SystemZ/SystemZSubtarget.h index 453471c..a08f2da 100644 --- a/lib/Target/SystemZ/SystemZSubtarget.h +++ b/lib/Target/SystemZ/SystemZSubtarget.h @@ -15,14 +15,16 @@  #define LLVM_TARGET_SystemZ_SUBTARGET_H  #include "llvm/Target/TargetSubtarget.h" -  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "SystemZGenSubtarget.inc" +  namespace llvm {  class GlobalValue;  class TargetMachine; -class SystemZSubtarget : public TargetSubtarget { +class SystemZSubtarget : public SystemZGenSubtargetInfo {    bool HasZ10Insts;  public:    /// This constructor initializes the data members to match that diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index d7f630c..5c653f6 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -14,13 +14,18 @@  #define DEBUG_TYPE "subtarget"  #include "X86Subtarget.h"  #include "X86InstrInfo.h" -#include "X86GenSubtarget.inc"  #include "llvm/GlobalValue.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Support/Host.h"  #include "llvm/Target/TargetMachine.h"  #include "llvm/ADT/SmallVector.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "X86GenSubtarget.inc" +  using namespace llvm;  #if defined(_MSC_VER) @@ -287,7 +292,8 @@ void X86Subtarget::AutoDetectSubtargetFeatures() {  X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU,                             const std::string &FS,                              bool is64Bit, unsigned StackAlignOverride) -  : PICStyle(PICStyles::None) +  : X86GenSubtargetInfo() +  , PICStyle(PICStyles::None)    , X86SSELevel(NoMMXSSE)    , X863DNowLevel(NoThreeDNow)    , HasCMov(false) diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 80a4103..cafc082 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -19,6 +19,9 @@  #include "llvm/CallingConv.h"  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "X86GenSubtarget.inc" +  namespace llvm {  class GlobalValue;  class TargetMachine; @@ -35,7 +38,7 @@ enum Style {  };  } -class X86Subtarget : public TargetSubtarget { +class X86Subtarget : public X86GenSubtargetInfo {  protected:    enum X86SSEEnum {      NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42 diff --git a/lib/Target/XCore/XCoreSubtarget.cpp b/lib/Target/XCore/XCoreSubtarget.cpp index 0447d2e..ef13520 100644 --- a/lib/Target/XCore/XCoreSubtarget.cpp +++ b/lib/Target/XCore/XCoreSubtarget.cpp @@ -13,9 +13,16 @@  #include "XCoreSubtarget.h"  #include "XCore.h" + +#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_MC_DESC +#define GET_SUBTARGETINFO_TARGET_DESC +#include "XCoreGenSubtarget.inc" +  using namespace llvm;  XCoreSubtarget::XCoreSubtarget(const std::string &TT,                                 const std::string &CPU, const std::string &FS) +  : XCoreGenSubtargetInfo()  {  } diff --git a/lib/Target/XCore/XCoreSubtarget.h b/lib/Target/XCore/XCoreSubtarget.h index ee40d36..182e5c4 100644 --- a/lib/Target/XCore/XCoreSubtarget.h +++ b/lib/Target/XCore/XCoreSubtarget.h @@ -16,12 +16,14 @@  #include "llvm/Target/TargetSubtarget.h"  #include "llvm/Target/TargetMachine.h" -  #include <string> +#define GET_SUBTARGETINFO_HEADER +#include "XCoreGenSubtarget.inc" +  namespace llvm { -class XCoreSubtarget : public TargetSubtarget { +class XCoreSubtarget : public XCoreGenSubtargetInfo {  public:    /// This constructor initializes the data members to match that diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 5e2fdf0..18d4db0 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -223,7 +223,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {    OS << "#undef GET_INSTRINFO_HEADER\n";    std::string ClassName = TargetName + "GenInstrInfo"; -  OS << "namespace llvm {\n\n"; +  OS << "namespace llvm {\n";    OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n"       << "  explicit " << ClassName << "(int SO = -1, int DO = -1);\n"       << "};\n"; @@ -234,7 +234,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {    OS << "\n#ifdef GET_INSTRINFO_CTOR\n";    OS << "#undef GET_INSTRINFO_CTOR\n"; -  OS << "namespace llvm {\n\n"; +  OS << "namespace llvm {\n";    OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"       << "  : TargetInstrInfoImpl(SO, DO) {\n"       << "  InitMCInstrInfo(" << TargetName << "Insts, " diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index c823cb1..a55836f 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -29,16 +29,20 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS,    std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);    std::sort(DefList.begin(), DefList.end(), LessRecord()); -  // Open enumeration -  OS << "enum {\n"; - -  // For each record    unsigned N = DefList.size(); +  if (N == 0) +    return;    if (N > 64) {      errs() << "Too many (> 64) subtarget features!\n";      exit(1);    } +  OS << "namespace " << Target << " {\n"; + +  // Open enumeration +  OS << "enum {\n"; + +  // For each record    for (unsigned i = 0; i < N;) {      // Next record      Record *Def = DefList[i]; @@ -57,23 +61,31 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS,    // Close enumeration    OS << "};\n"; + +  OS << "}\n";  }  //  // FeatureKeyValues - Emit data of all the subtarget features.  Used by the  // command line.  // -void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) { +unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {    // Gather and sort all the features    std::vector<Record*> FeatureList =                             Records.getAllDerivedDefinitions("SubtargetFeature"); + +  if (FeatureList.empty()) +    return 0; +    std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());    // Begin feature table    OS << "// Sorted (by key) array of values for CPU features.\n" -     << "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n"; +     << "static const llvm::SubtargetFeatureKV " +     << Target << "FeatureKV[] = {\n";    // For each feature +  unsigned NumFeatures = 0;    for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {      // Next feature      Record *Feature = FeatureList[i]; @@ -88,7 +100,7 @@ void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {      OS << "  { "         << "\"" << CommandLineName << "\", "         << "\"" << Desc << "\", " -       << Name << ", "; +       << Target << "::" << Name << ", ";      const std::vector<Record*> &ImpliesList =        Feature->getValueAsListOfDefs("Implies"); @@ -97,12 +109,13 @@ void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {        OS << "0ULL";      } else {        for (unsigned j = 0, M = ImpliesList.size(); j < M;) { -        OS << ImpliesList[j]->getName(); +        OS << Target << "::" << ImpliesList[j]->getName();          if (++j < M) OS << " | ";        }      }      OS << " }"; +    ++NumFeatures;      // Depending on 'if more in the list' emit comma      if ((i + 1) < N) OS << ","; @@ -113,17 +126,14 @@ void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {    // End feature table    OS << "};\n"; -  // Emit size of table -  OS<<"\nenum {\n"; -  OS<<"  FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n"; -  OS<<"};\n"; +  return NumFeatures;  }  //  // CPUKeyValues - Emit data of all the subtarget processors.  Used by command  // line.  // -void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) { +unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {    // Gather and sort processor information    std::vector<Record*> ProcessorList =                            Records.getAllDerivedDefinitions("Processor"); @@ -131,7 +141,8 @@ void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {    // Begin processor table    OS << "// Sorted (by key) array of values for CPU subtype.\n" -     << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n"; +     << "static const llvm::SubtargetFeatureKV " +     << Target << "SubTypeKV[] = {\n";    // For each processor    for (unsigned i = 0, N = ProcessorList.size(); i < N;) { @@ -151,7 +162,7 @@ void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {        OS << "0ULL";      } else {        for (unsigned j = 0, M = FeatureList.size(); j < M;) { -        OS << FeatureList[j]->getName(); +        OS << Target << "::" << FeatureList[j]->getName();          if (++j < M) OS << " | ";        }      } @@ -168,10 +179,7 @@ void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {    // End processor table    OS << "};\n"; -  // Emit size of table -  OS<<"\nenum {\n"; -  OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n"; -  OS<<"};\n"; +  return ProcessorList.size();  }  // @@ -192,11 +200,6 @@ CollectAllItinClasses(raw_ostream &OS,      ItinClassesMap[ItinClass->getName()] = i;    } -  // Emit size of table -  OS<<"\nenum {\n"; -  OS<<"  ItinClassesSize = " << N << "\n"; -  OS<<"};\n"; -    // Return itinerary class count    return N;  } @@ -336,15 +339,18 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,    }    // Begin stages table -  std::string StageTable = "\nstatic const llvm::InstrStage Stages[] = {\n"; +  std::string StageTable = "\nstatic const llvm::InstrStage " + Target + +    "Stages[] = {\n";    StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";    // Begin operand cycle table -  std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n"; +  std::string OperandCycleTable = "static const unsigned " + Target + +    "OperandCycles[] = {\n";    OperandCycleTable += "  0, // No itinerary\n";    // Begin pipeline bypass table -  std::string BypassTable = "static const unsigned ForwardingPathes[] = {\n"; +  std::string BypassTable = "static const unsigned " + Target + +    "ForwardingPathes[] = {\n";    BypassTable += "  0, // No itinerary\n";    unsigned StageCount = 1, OperandCycleCount = 1; @@ -457,12 +463,6 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,    OS << StageTable;    OS << OperandCycleTable;    OS << BypassTable; - -  // Emit size of tables -  OS<<"\nenum {\n"; -  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n"; -  OS<<"  OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n"; -  OS<<"};\n";  }  // @@ -533,7 +533,8 @@ void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {    // Begin processor table    OS << "\n";    OS << "// Sorted (by key) array of itineraries for CPU subtype.\n" -     << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n"; +     << "static const llvm::SubtargetInfoKV " +     << Target << "ProcItinKV[] = {\n";    // For each processor    for (unsigned i = 0, N = ProcessorList.size(); i < N;) { @@ -559,12 +560,6 @@ void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {    // End processor table    OS << "};\n"; - -  // Emit size of table -  OS<<"\nenum {\n"; -  OS<<"  ProcItinKVSize = sizeof(ProcItinKV)/" -                            "sizeof(llvm::SubtargetInfoKV)\n"; -  OS<<"};\n";  }  // @@ -599,7 +594,9 @@ void SubtargetEmitter::EmitData(raw_ostream &OS) {  // ParseFeaturesFunction - Produces a subtarget specific function for parsing  // the subtarget features string.  // -void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { +void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS, +                                             unsigned NumFeatures, +                                             unsigned NumProcs) {    std::vector<Record*> Features =                         Records.getAllDerivedDefinitions("SubtargetFeature");    std::sort(Features.begin(), Features.end(), LessRecord()); @@ -611,11 +608,18 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {    OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"       << "                                  const std::string &CPU) {\n"       << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n" -     << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n" -     << "  SubtargetFeatures Features(FS);\n" +     << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"; + +  if (Features.empty()) { +    OS << "}\n"; +    return; +  } + +  OS << "  SubtargetFeatures Features(FS);\n"       << "  uint64_t Bits =  Features.getFeatureBits(CPU, " -     << "SubTypeKV, SubTypeKVSize,\n" -     << "                                    FeatureKV, FeatureKVSize);\n"; +     << Target << "SubTypeKV, " << NumProcs << ",\n" +     << "                                    " << Target << "FeatureKV, " +     << NumFeatures << ");\n";    for (unsigned i = 0; i < Features.size(); i++) {      // Next record @@ -625,20 +629,12 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {      const std::string &Attribute = R->getValueAsString("Attribute");      if (Value=="true" || Value=="false") -      OS << "  if ((Bits & " << Instance << ") != 0) " +      OS << "  if ((Bits & " << Target << "::" << Instance << ") != 0) "           << Attribute << " = " << Value << ";\n";      else -      OS << "  if ((Bits & " << Instance << ") != 0 && " << Attribute << -            " < " << Value << ") " << Attribute << " = " << Value << ";\n"; -  } - -  if (HasItineraries) { -    OS << "\n" -       << "  InstrItinerary *Itinerary = (InstrItinerary *)" -       <<              "Features.getItinerary(CPU, " -       << "ProcItinKV, ProcItinKVSize);\n" -       << "  InstrItins = InstrItineraryData(Stages, OperandCycles, " -       << "ForwardingPathes, Itinerary);\n"; +      OS << "  if ((Bits & " << Target << "::" << Instance << ") != 0 && " +         << Attribute << " < " << Value << ") " +         << Attribute << " = " << Value << ";\n";    }    OS << "}\n"; @@ -652,22 +648,90 @@ void SubtargetEmitter::run(raw_ostream &OS) {    EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); -  OS << "#include \"llvm/Support/Debug.h\"\n"; -  OS << "#include \"llvm/Support/raw_ostream.h\"\n"; -  OS << "#include \"llvm/MC/SubtargetFeature.h\"\n"; -  OS << "#include \"llvm/MC/MCInstrItineraries.h\"\n\n"; +  OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; +  OS << "#undef GET_SUBTARGETINFO_MC_DESC\n"; -//  Enumeration(OS, "FuncUnit", true); -//  OS<<"\n"; -//  Enumeration(OS, "InstrItinClass", false); -//  OS<<"\n"; +  OS << "namespace llvm {\n";    Enumeration(OS, "SubtargetFeature", true);    OS<<"\n"; -  FeatureKeyValues(OS); +  unsigned NumFeatures = FeatureKeyValues(OS);    OS<<"\n"; -  CPUKeyValues(OS); +  unsigned NumProcs = CPUKeyValues(OS);    OS<<"\n";    EmitData(OS);    OS<<"\n"; -  ParseFeaturesFunction(OS); + +  // MCInstrInfo initialization routine. +  OS << "static inline void Init" << Target +     << "MCSubtargetInfo(MCSubtargetInfo *II) {\n"; +  OS << "  II->InitMCSubtargetInfo("; +  if (NumFeatures) +    OS << Target << "FeatureKV, "; +  else +    OS << "0, "; +  if (NumProcs) +    OS << Target << "SubTypeKV, "; +  else +    OS << "0, "; +  if (HasItineraries) { +    OS << Target << "ProcItinKV, " +       << Target << "Stages, " +       << Target << "OperandCycles, " +       << Target << "ForwardingPathes, "; +  } else +    OS << "0, 0, 0, 0, "; +  OS << NumFeatures << ", " << NumProcs << ");\n}\n\n"; + +  OS << "} // End llvm namespace \n"; + +  OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n"; + +  OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n"; +  OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n"; + +  OS << "#include \"llvm/Support/Debug.h\"\n"; +  OS << "#include \"llvm/Support/raw_ostream.h\"\n"; +  ParseFeaturesFunction(OS, NumFeatures, NumProcs); + +  OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n"; + +  // Create a TargetSubtarget subclass to hide the MC layer initialization. +  OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n"; +  OS << "#undef GET_SUBTARGETINFO_HEADER\n"; + +  std::string ClassName = Target + "GenSubtargetInfo"; +  OS << "namespace llvm {\n"; +  OS << "struct " << ClassName << " : public TargetSubtarget {\n" +     << "  explicit " << ClassName << "();\n" +     << "};\n"; +  OS << "} // End llvm namespace \n"; + +  OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; + +  OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n"; +  OS << "#undef GET_SUBTARGETINFO_CTOR\n"; + +  OS << "namespace llvm {\n"; +  OS << ClassName << "::" << ClassName << "()\n" +     << "  : TargetSubtarget() {\n" +     << "  InitMCSubtargetInfo("; +  if (NumFeatures) +    OS << Target << "FeatureKV, "; +  else +    OS << "0, "; +  if (NumProcs) +    OS << Target << "SubTypeKV, "; +  else +    OS << "0, "; +  if (HasItineraries) { +    OS << Target << "ProcItinKV, " +       << Target << "Stages, " +       << Target << "OperandCycles, " +       << Target << "ForwardingPathes, "; +  } else +    OS << "0, 0, 0, 0, "; +  OS << NumFeatures << ", " << NumProcs << ");\n}\n\n"; +  OS << "} // End llvm namespace \n"; + +  OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";  } diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h index cf793c8..b239f3d 100644 --- a/utils/TableGen/SubtargetEmitter.h +++ b/utils/TableGen/SubtargetEmitter.h @@ -30,8 +30,8 @@ class SubtargetEmitter : public TableGenBackend {    bool HasItineraries;    void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits); -  void FeatureKeyValues(raw_ostream &OS); -  void CPUKeyValues(raw_ostream &OS); +  unsigned FeatureKeyValues(raw_ostream &OS); +  unsigned CPUKeyValues(raw_ostream &OS);    unsigned CollectAllItinClasses(raw_ostream &OS,                                   std::map<std::string,unsigned> &ItinClassesMap,                                   std::vector<Record*> &ItinClassList); @@ -52,7 +52,8 @@ class SubtargetEmitter : public TableGenBackend {                           std::vector<std::vector<InstrItinerary> > &ProcList);    void EmitProcessorLookup(raw_ostream &OS);    void EmitData(raw_ostream &OS); -  void ParseFeaturesFunction(raw_ostream &OS); +  void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, +                             unsigned NumProcs);  public:    SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {}  | 
