Sink SubtargetFeature and TargetInstrItineraries (renamed MCInstrItineraries) into MC.
authorEvan Cheng <evan.cheng@apple.com>
Wed, 29 Jun 2011 01:14:12 +0000 (01:14 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 29 Jun 2011 01:14:12 +0000 (01:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134049 91177308-0d34-0410-b5e6-96231b3b80d8

26 files changed:
include/llvm/MC/MCInstrItineraries.h [new file with mode: 0644]
include/llvm/MC/SubtargetFeature.h [new file with mode: 0644]
include/llvm/Target/SubtargetFeature.h [deleted file]
include/llvm/Target/TargetInstrItineraries.h [deleted file]
include/llvm/Target/TargetMachine.h
lib/CodeGen/IfConversion.cpp
lib/CodeGen/MachineLICM.cpp
lib/CodeGen/ScheduleDAGInstrs.cpp
lib/CodeGen/ScoreboardHazardRecognizer.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
lib/ExecutionEngine/TargetSelect.cpp
lib/MC/SubtargetFeature.cpp [new file with mode: 0644]
lib/Target/ARM/ARMSubtarget.h
lib/Target/Alpha/AlphaSubtarget.h
lib/Target/CellSPU/SPUSubtarget.h
lib/Target/MBlaze/MBlazeSubtarget.h
lib/Target/Mips/MipsSubtarget.h
lib/Target/PowerPC/PPCSubtarget.h
lib/Target/SubtargetFeature.cpp [deleted file]
lib/Target/TargetInstrInfo.cpp
tools/llc/llc.cpp
tools/llvm-mc/llvm-mc.cpp
tools/lto/LTOCodeGenerator.cpp
tools/lto/LTOModule.cpp
utils/TableGen/SubtargetEmitter.cpp
utils/TableGen/SubtargetEmitter.h

diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h
new file mode 100644 (file)
index 0000000..e942892
--- /dev/null
@@ -0,0 +1,253 @@
+//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- 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 structures used for instruction
+// itineraries, stages, and operand reads/writes.  This is used by
+// schedulers to determine instruction stages and latencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRITINERARIES_H
+#define LLVM_MC_MCINSTRITINERARIES_H
+
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// Instruction stage - These values represent a non-pipelined step in
+/// the execution of an instruction.  Cycles represents the number of
+/// discrete time slots needed to complete the stage.  Units represent
+/// the choice of functional units that can be used to complete the
+/// stage.  Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+/// cycles should elapse from the start of this stage to the start of
+/// the next stage in the itinerary. A value of -1 indicates that the
+/// next stage should start immediately after the current one.
+/// For example:
+///
+///   { 1, x, -1 }
+///      indicates that the stage occupies FU x for 1 cycle and that
+///      the next stage starts immediately after this one.
+///
+///   { 2, x|y, 1 }
+///      indicates that the stage occupies either FU x or FU y for 2
+///      consecuative cycles and that the next stage starts one cycle
+///      after this stage starts. That is, the stage requirements
+///      overlap in time.
+///
+///   { 1, x, 0 }
+///      indicates that the stage occupies FU x for 1 cycle and that
+///      the next stage starts in this same cycle. This can be used to
+///      indicate that the instruction requires multiple stages at the
+///      same time.
+///
+/// FU reservation can be of two different kinds:
+///  - FUs which instruction actually requires
+///  - FUs which instruction just reserves. Reserved unit is not available for
+///    execution of other instruction. However, several instructions can reserve
+///    the same unit several times.
+/// Such two types of units reservation is used to model instruction domain
+/// change stalls, FUs using the same resource (e.g. same register file), etc.
+
+struct InstrStage {
+  enum ReservationKinds {
+    Required = 0,
+    Reserved = 1
+  };
+
+  unsigned Cycles_;  ///< Length of stage in machine cycles
+  unsigned Units_;   ///< Choice of functional units
+  int NextCycles_;   ///< Number of machine cycles to next stage
+  ReservationKinds Kind_; ///< Kind of the FU reservation
+
+  /// getCycles - returns the number of cycles the stage is occupied
+  unsigned getCycles() const {
+    return Cycles_;
+  }
+
+  /// getUnits - returns the choice of FUs
+  unsigned getUnits() const {
+    return Units_;
+  }
+
+  ReservationKinds getReservationKind() const {
+    return Kind_;
+  }
+
+  /// getNextCycles - returns the number of cycles from the start of
+  /// this stage to the start of the next stage in the itinerary
+  unsigned getNextCycles() const {
+    return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary - An itinerary represents the scheduling
+/// information for an instruction. This includes a set of stages
+/// occupies by the instruction, and the pipeline cycle in which
+/// operands are read and written.
+///
+struct InstrItinerary {
+  unsigned NumMicroOps;        ///< # of micro-ops, 0 means it's variable
+  unsigned FirstStage;         ///< Index of first stage in itinerary
+  unsigned LastStage;          ///< Index of last + 1 stage in itinerary
+  unsigned FirstOperandCycle;  ///< Index of first operand rd/wr
+  unsigned LastOperandCycle;   ///< Index of last + 1 operand rd/wr
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
+/// used by a target.
+///
+class InstrItineraryData {
+public:
+  const InstrStage     *Stages;         ///< Array of stages selected
+  const unsigned       *OperandCycles;  ///< Array of operand cycles selected
+  const unsigned       *Forwardings;    ///< Array of pipeline forwarding pathes
+  const InstrItinerary *Itineraries;    ///< Array of itineraries selected
+  unsigned              IssueWidth;     ///< Max issue per cycle. 0=Unknown.
+
+  /// Ctors.
+  ///
+  InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
+                         Itineraries(0), IssueWidth(0) {}
+
+  InstrItineraryData(const InstrStage *S, const unsigned *OS,
+                     const unsigned *F, const InstrItinerary *I)
+    : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
+      IssueWidth(0) {}
+
+  /// isEmpty - Returns true if there are no itineraries.
+  ///
+  bool isEmpty() const { return Itineraries == 0; }
+
+  /// isEndMarker - Returns true if the index is for the end marker
+  /// itinerary.
+  ///
+  bool isEndMarker(unsigned ItinClassIndx) const {
+    return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
+            (Itineraries[ItinClassIndx].LastStage == ~0U));
+  }
+
+  /// beginStage - Return the first stage of the itinerary.
+  ///
+  const InstrStage *beginStage(unsigned ItinClassIndx) const {
+    unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
+    return Stages + StageIdx;
+  }
+
+  /// endStage - Return the last+1 stage of the itinerary.
+  ///
+  const InstrStage *endStage(unsigned ItinClassIndx) const {
+    unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
+    return Stages + StageIdx;
+  }
+
+  /// getStageLatency - Return the total stage latency of the given
+  /// class.  The latency is the maximum completion time for any stage
+  /// in the itinerary.
+  ///
+  unsigned getStageLatency(unsigned ItinClassIndx) const {
+    // If the target doesn't provide itinerary information, use a simple
+    // non-zero default value for all instructions.  Some target's provide a
+    // dummy (Generic) itinerary which should be handled as if it's itinerary is
+    // empty. We identify this by looking for a reference to stage zero (invalid
+    // stage). This is different from beginStage == endState != 0, which could
+    // be used for zero-latency pseudo ops.
+    if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
+      return 1;
+
+    // Calculate the maximum completion time for any stage.
+    unsigned Latency = 0, StartCycle = 0;
+    for (const InstrStage *IS = beginStage(ItinClassIndx),
+           *E = endStage(ItinClassIndx); IS != E; ++IS) {
+      Latency = std::max(Latency, StartCycle + IS->getCycles());
+      StartCycle += IS->getNextCycles();
+    }
+
+    return Latency;
+  }
+
+  /// getOperandCycle - Return the cycle for the given class and
+  /// operand. Return -1 if no cycle is specified for the operand.
+  ///
+  int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
+    if (isEmpty())
+      return -1;
+
+    unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
+    unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
+    if ((FirstIdx + OperandIdx) >= LastIdx)
+      return -1;
+
+    return (int)OperandCycles[FirstIdx + OperandIdx];
+  }
+
+  /// hasPipelineForwarding - Return true if there is a pipeline forwarding
+  /// between instructions of itinerary classes DefClass and UseClasses so that
+  /// value produced by an instruction of itinerary class DefClass, operand
+  /// index DefIdx can be bypassed when it's read by an instruction of
+  /// itinerary class UseClass, operand index UseIdx.
+  bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
+                             unsigned UseClass, unsigned UseIdx) const {
+    unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
+    unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
+    if ((FirstDefIdx + DefIdx) >= LastDefIdx)
+      return false;
+    if (Forwardings[FirstDefIdx + DefIdx] == 0)
+      return false;
+
+    unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
+    unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
+    if ((FirstUseIdx + UseIdx) >= LastUseIdx)
+      return false;
+
+    return Forwardings[FirstDefIdx + DefIdx] ==
+      Forwardings[FirstUseIdx + UseIdx];
+  }
+
+  /// getOperandLatency - Compute and return the use operand latency of a given
+  /// itinerary class and operand index if the value is produced by an
+  /// instruction of the specified itinerary class and def operand index.
+  int getOperandLatency(unsigned DefClass, unsigned DefIdx,
+                        unsigned UseClass, unsigned UseIdx) const {
+    if (isEmpty())
+      return -1;
+
+    int DefCycle = getOperandCycle(DefClass, DefIdx);
+    if (DefCycle == -1)
+      return -1;
+
+    int UseCycle = getOperandCycle(UseClass, UseIdx);
+    if (UseCycle == -1)
+      return -1;
+
+    UseCycle = DefCycle - UseCycle + 1;
+    if (UseCycle > 0 &&
+        hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
+      // FIXME: This assumes one cycle benefit for every pipeline forwarding.
+      --UseCycle;
+    return UseCycle;
+  }
+
+  /// isMicroCoded - Return true if the instructions in the given class decode
+  /// to more than one micro-ops.
+  bool isMicroCoded(unsigned ItinClassIndx) const {
+    if (isEmpty())
+      return false;
+    return Itineraries[ItinClassIndx].NumMicroOps != 1;
+  }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
new file mode 100644 (file)
index 0000000..cc56576
--- /dev/null
@@ -0,0 +1,118 @@
+//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines and manages user or tool specified CPU characteristics.
+// The intent is to be able to package specific features that should or should
+// not be used on a specific target processor.  A tool, such as llc, could, as
+// as example, gather chip info from the command line, a long with features
+// that should be used on that chip.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SUBTARGETFEATURE_H
+#define LLVM_MC_SUBTARGETFEATURE_H
+
+#include <string>
+#include <vector>
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  class raw_ostream;
+  
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatureKV - Used to provide key value pairs for feature and
+/// CPU bit flags.
+//
+struct SubtargetFeatureKV {
+  const char *Key;                      // K-V key string
+  const char *Desc;                     // Help descriptor
+  uint64_t Value;                       // K-V integer value
+  uint64_t Implies;                     // K-V bit mask
+  
+  // Compare routine for std binary search
+  bool operator<(const SubtargetFeatureKV &S) const {
+    return strcmp(Key, S.Key) < 0;
+  }
+};
+  
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
+/// pointers.
+//
+struct SubtargetInfoKV {
+  const char *Key;                      // K-V key string
+  void *Value;                          // K-V pointer value
+  
+  // Compare routine for std binary search
+  bool operator<(const SubtargetInfoKV &S) const {
+    return strcmp(Key, S.Key) < 0;
+  }
+};
+  
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatures - Manages the enabling and disabling of subtarget 
+/// specific features.  Features are encoded as a string of the form
+///   "cpu,+attr1,+attr2,-attr3,...,+attrN"
+/// A comma separates each feature from the next (all lowercase.)
+/// The first feature is always the CPU subtype (eg. pentiumm).  If the CPU
+/// value is "generic" then the CPU subtype should be generic for the target.
+/// Each of the remaining features is prefixed with + or - indicating whether
+/// that feature should be enabled or disabled contrary to the cpu
+/// specification.
+///
+
+class SubtargetFeatures {
+  std::vector<std::string> Features;    // Subtarget features as a vector
+public:
+  explicit SubtargetFeatures(const std::string &Initial = std::string());
+
+  /// Features string accessors.
+  std::string getString() const;
+  void setString(const std::string &Initial);
+
+  /// Set the CPU string.  Replaces previous setting.  Setting to "" clears CPU.
+  void setCPU(const std::string &String);
+
+  /// Setting CPU string only if no string is set.
+  void setCPUIfNone(const std::string &String);
+
+  /// Returns current CPU string.
+  const std::string & getCPU() const;
+
+  /// Adding Features.
+  void AddFeature(const std::string &String, bool IsEnabled = true);
+           
+  /// Get feature bits.
+  uint64_t getBits(const SubtargetFeatureKV *CPUTable,
+                         size_t CPUTableSize,
+                   const SubtargetFeatureKV *FeatureTable,
+                         size_t FeatureTableSize);
+                         
+  /// Get info pointer
+  void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
+  
+  /// Print feature string.
+  void print(raw_ostream &OS) const;
+  
+  // Dump feature info.
+  void dump() const;
+
+  /// Retrieve a formatted string of the default features for the specified
+  /// target triple.
+  void getDefaultSubtargetFeatures(const std::string &CPU,
+                                   const Triple& Triple);
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h
deleted file mode 100644 (file)
index cbd2c3b..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines and manages user or tool specified CPU characteristics.
-// The intent is to be able to package specific features that should or should
-// not be used on a specific target processor.  A tool, such as llc, could, as
-// as example, gather chip info from the command line, a long with features
-// that should be used on that chip.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_SUBTARGETFEATURE_H
-#define LLVM_TARGET_SUBTARGETFEATURE_H
-
-#include <string>
-#include <vector>
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
-  class raw_ostream;
-  
-//===----------------------------------------------------------------------===//
-///
-/// SubtargetFeatureKV - Used to provide key value pairs for feature and
-/// CPU bit flags.
-//
-struct SubtargetFeatureKV {
-  const char *Key;                      // K-V key string
-  const char *Desc;                     // Help descriptor
-  uint64_t Value;                       // K-V integer value
-  uint64_t Implies;                     // K-V bit mask
-  
-  // Compare routine for std binary search
-  bool operator<(const SubtargetFeatureKV &S) const {
-    return strcmp(Key, S.Key) < 0;
-  }
-};
-  
-//===----------------------------------------------------------------------===//
-///
-/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
-/// pointers.
-//
-struct SubtargetInfoKV {
-  const char *Key;                      // K-V key string
-  void *Value;                          // K-V pointer value
-  
-  // Compare routine for std binary search
-  bool operator<(const SubtargetInfoKV &S) const {
-    return strcmp(Key, S.Key) < 0;
-  }
-};
-  
-//===----------------------------------------------------------------------===//
-///
-/// SubtargetFeatures - Manages the enabling and disabling of subtarget 
-/// specific features.  Features are encoded as a string of the form
-///   "cpu,+attr1,+attr2,-attr3,...,+attrN"
-/// A comma separates each feature from the next (all lowercase.)
-/// The first feature is always the CPU subtype (eg. pentiumm).  If the CPU
-/// value is "generic" then the CPU subtype should be generic for the target.
-/// Each of the remaining features is prefixed with + or - indicating whether
-/// that feature should be enabled or disabled contrary to the cpu
-/// specification.
-///
-
-class SubtargetFeatures {
-  std::vector<std::string> Features;    // Subtarget features as a vector
-public:
-  explicit SubtargetFeatures(const std::string &Initial = std::string());
-
-  /// Features string accessors.
-  std::string getString() const;
-  void setString(const std::string &Initial);
-
-  /// Set the CPU string.  Replaces previous setting.  Setting to "" clears CPU.
-  void setCPU(const std::string &String);
-
-  /// Setting CPU string only if no string is set.
-  void setCPUIfNone(const std::string &String);
-
-  /// Returns current CPU string.
-  const std::string & getCPU() const;
-
-  /// Adding Features.
-  void AddFeature(const std::string &String, bool IsEnabled = true);
-           
-  /// Get feature bits.
-  uint64_t getBits(const SubtargetFeatureKV *CPUTable,
-                         size_t CPUTableSize,
-                   const SubtargetFeatureKV *FeatureTable,
-                         size_t FeatureTableSize);
-                         
-  /// Get info pointer
-  void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
-  
-  /// Print feature string.
-  void print(raw_ostream &OS) const;
-  
-  // Dump feature info.
-  void dump() const;
-
-  /// Retrieve a formatted string of the default features for the specified
-  /// target triple.
-  void getDefaultSubtargetFeatures(const std::string &CPU,
-                                   const Triple& Triple);
-};
-
-} // End namespace llvm
-
-#endif
diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h
deleted file mode 100644 (file)
index 6011402..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- 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 structures used for instruction
-// itineraries, stages, and operand reads/writes.  This is used by
-// schedulers to determine instruction stages and latencies.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H
-#define LLVM_TARGET_TARGETINSTRITINERARIES_H
-
-#include <algorithm>
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-/// Instruction stage - These values represent a non-pipelined step in
-/// the execution of an instruction.  Cycles represents the number of
-/// discrete time slots needed to complete the stage.  Units represent
-/// the choice of functional units that can be used to complete the
-/// stage.  Eg. IntUnit1, IntUnit2. NextCycles indicates how many
-/// cycles should elapse from the start of this stage to the start of
-/// the next stage in the itinerary. A value of -1 indicates that the
-/// next stage should start immediately after the current one.
-/// For example:
-///
-///   { 1, x, -1 }
-///      indicates that the stage occupies FU x for 1 cycle and that
-///      the next stage starts immediately after this one.
-///
-///   { 2, x|y, 1 }
-///      indicates that the stage occupies either FU x or FU y for 2
-///      consecuative cycles and that the next stage starts one cycle
-///      after this stage starts. That is, the stage requirements
-///      overlap in time.
-///
-///   { 1, x, 0 }
-///      indicates that the stage occupies FU x for 1 cycle and that
-///      the next stage starts in this same cycle. This can be used to
-///      indicate that the instruction requires multiple stages at the
-///      same time.
-///
-/// FU reservation can be of two different kinds:
-///  - FUs which instruction actually requires
-///  - FUs which instruction just reserves. Reserved unit is not available for
-///    execution of other instruction. However, several instructions can reserve
-///    the same unit several times.
-/// Such two types of units reservation is used to model instruction domain
-/// change stalls, FUs using the same resource (e.g. same register file), etc.
-
-struct InstrStage {
-  enum ReservationKinds {
-    Required = 0,
-    Reserved = 1
-  };
-
-  unsigned Cycles_;  ///< Length of stage in machine cycles
-  unsigned Units_;   ///< Choice of functional units
-  int NextCycles_;   ///< Number of machine cycles to next stage
-  ReservationKinds Kind_; ///< Kind of the FU reservation
-
-  /// getCycles - returns the number of cycles the stage is occupied
-  unsigned getCycles() const {
-    return Cycles_;
-  }
-
-  /// getUnits - returns the choice of FUs
-  unsigned getUnits() const {
-    return Units_;
-  }
-
-  ReservationKinds getReservationKind() const {
-    return Kind_;
-  }
-
-  /// getNextCycles - returns the number of cycles from the start of
-  /// this stage to the start of the next stage in the itinerary
-  unsigned getNextCycles() const {
-    return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
-  }
-};
-
-
-//===----------------------------------------------------------------------===//
-/// Instruction itinerary - An itinerary represents the scheduling
-/// information for an instruction. This includes a set of stages
-/// occupies by the instruction, and the pipeline cycle in which
-/// operands are read and written.
-///
-struct InstrItinerary {
-  unsigned NumMicroOps;        ///< # of micro-ops, 0 means it's variable
-  unsigned FirstStage;         ///< Index of first stage in itinerary
-  unsigned LastStage;          ///< Index of last + 1 stage in itinerary
-  unsigned FirstOperandCycle;  ///< Index of first operand rd/wr
-  unsigned LastOperandCycle;   ///< Index of last + 1 operand rd/wr
-};
-
-
-//===----------------------------------------------------------------------===//
-/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
-/// used by a target.
-///
-class InstrItineraryData {
-public:
-  const InstrStage     *Stages;         ///< Array of stages selected
-  const unsigned       *OperandCycles;  ///< Array of operand cycles selected
-  const unsigned       *Forwardings;    ///< Array of pipeline forwarding pathes
-  const InstrItinerary *Itineraries;    ///< Array of itineraries selected
-  unsigned              IssueWidth;     ///< Max issue per cycle. 0=Unknown.
-
-  /// Ctors.
-  ///
-  InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
-                         Itineraries(0), IssueWidth(0) {}
-
-  InstrItineraryData(const InstrStage *S, const unsigned *OS,
-                     const unsigned *F, const InstrItinerary *I)
-    : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
-      IssueWidth(0) {}
-
-  /// isEmpty - Returns true if there are no itineraries.
-  ///
-  bool isEmpty() const { return Itineraries == 0; }
-
-  /// isEndMarker - Returns true if the index is for the end marker
-  /// itinerary.
-  ///
-  bool isEndMarker(unsigned ItinClassIndx) const {
-    return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
-            (Itineraries[ItinClassIndx].LastStage == ~0U));
-  }
-
-  /// beginStage - Return the first stage of the itinerary.
-  ///
-  const InstrStage *beginStage(unsigned ItinClassIndx) const {
-    unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
-    return Stages + StageIdx;
-  }
-
-  /// endStage - Return the last+1 stage of the itinerary.
-  ///
-  const InstrStage *endStage(unsigned ItinClassIndx) const {
-    unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
-    return Stages + StageIdx;
-  }
-
-  /// getStageLatency - Return the total stage latency of the given
-  /// class.  The latency is the maximum completion time for any stage
-  /// in the itinerary.
-  ///
-  unsigned getStageLatency(unsigned ItinClassIndx) const {
-    // If the target doesn't provide itinerary information, use a simple
-    // non-zero default value for all instructions.  Some target's provide a
-    // dummy (Generic) itinerary which should be handled as if it's itinerary is
-    // empty. We identify this by looking for a reference to stage zero (invalid
-    // stage). This is different from beginStage == endState != 0, which could
-    // be used for zero-latency pseudo ops.
-    if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
-      return 1;
-
-    // Calculate the maximum completion time for any stage.
-    unsigned Latency = 0, StartCycle = 0;
-    for (const InstrStage *IS = beginStage(ItinClassIndx),
-           *E = endStage(ItinClassIndx); IS != E; ++IS) {
-      Latency = std::max(Latency, StartCycle + IS->getCycles());
-      StartCycle += IS->getNextCycles();
-    }
-
-    return Latency;
-  }
-
-  /// getOperandCycle - Return the cycle for the given class and
-  /// operand. Return -1 if no cycle is specified for the operand.
-  ///
-  int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
-    if (isEmpty())
-      return -1;
-
-    unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
-    unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
-    if ((FirstIdx + OperandIdx) >= LastIdx)
-      return -1;
-
-    return (int)OperandCycles[FirstIdx + OperandIdx];
-  }
-
-  /// hasPipelineForwarding - Return true if there is a pipeline forwarding
-  /// between instructions of itinerary classes DefClass and UseClasses so that
-  /// value produced by an instruction of itinerary class DefClass, operand
-  /// index DefIdx can be bypassed when it's read by an instruction of
-  /// itinerary class UseClass, operand index UseIdx.
-  bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
-                             unsigned UseClass, unsigned UseIdx) const {
-    unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
-    unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
-    if ((FirstDefIdx + DefIdx) >= LastDefIdx)
-      return false;
-    if (Forwardings[FirstDefIdx + DefIdx] == 0)
-      return false;
-
-    unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
-    unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
-    if ((FirstUseIdx + UseIdx) >= LastUseIdx)
-      return false;
-
-    return Forwardings[FirstDefIdx + DefIdx] ==
-      Forwardings[FirstUseIdx + UseIdx];
-  }
-
-  /// getOperandLatency - Compute and return the use operand latency of a given
-  /// itinerary class and operand index if the value is produced by an
-  /// instruction of the specified itinerary class and def operand index.
-  int getOperandLatency(unsigned DefClass, unsigned DefIdx,
-                        unsigned UseClass, unsigned UseIdx) const {
-    if (isEmpty())
-      return -1;
-
-    int DefCycle = getOperandCycle(DefClass, DefIdx);
-    if (DefCycle == -1)
-      return -1;
-
-    int UseCycle = getOperandCycle(UseClass, UseIdx);
-    if (UseCycle == -1)
-      return -1;
-
-    UseCycle = DefCycle - UseCycle + 1;
-    if (UseCycle > 0 &&
-        hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
-      // FIXME: This assumes one cycle benefit for every pipeline forwarding.
-      --UseCycle;
-    return UseCycle;
-  }
-
-  /// isMicroCoded - Return true if the instructions in the given class decode
-  /// to more than one micro-ops.
-  bool isMicroCoded(unsigned ItinClassIndx) const {
-    if (isEmpty())
-      return false;
-    return Itineraries[ItinClassIndx].NumMicroOps != 1;
-  }
-};
-
-
-} // End llvm namespace
-
-#endif
index 78f770cc41c3e62b37bbd26866c9be9198f43094..6544ce25f86307a6093413aae160b87d2267c12d 100644 (file)
 #ifndef LLVM_TARGET_TARGETMACHINE_H
 #define LLVM_TARGET_TARGETMACHINE_H
 
-#include "llvm/Target/TargetInstrItineraries.h"
 #include <cassert>
 #include <string>
 
 namespace llvm {
 
-class Target;
+class InstrItineraryData;
+class JITCodeEmitter;
 class MCAsmInfo;
+class MCContext;
+class Pass;
+class PassManager;
+class PassManagerBase;
+class Target;
 class TargetData;
-class TargetSubtarget;
+class TargetELFWriterInfo;
+class TargetFrameLowering;
 class TargetInstrInfo;
 class TargetIntrinsicInfo;
 class TargetJITInfo;
 class TargetLowering;
-class TargetSelectionDAGInfo;
-class TargetFrameLowering;
-class JITCodeEmitter;
-class MCContext;
 class TargetRegisterInfo;
-class PassManagerBase;
-class PassManager;
-class Pass;
-class TargetELFWriterInfo;
+class TargetSelectionDAGInfo;
+class TargetSubtarget;
 class formatted_raw_ostream;
 class raw_ostream;
 
index d8355ab86cfab02ca422e9f93670adec3babcb7c..c918bf631209d31149745562054e71ce077136b4 100644 (file)
@@ -18,8 +18,8 @@
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetInstrItineraries.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetRegisterInfo.h"
index 28a81e188194563e438ee09fd3aeec0d295c857a..722ceb202439dbf1d6cbc8c070e1086e2b1c2a4b 100644 (file)
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetInstrItineraries.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/ADT/DenseMap.h"
index 94941ecf23b624f8557fb2476893547b034f6195..9cceb4e8d745b29b45954f56437855855e1c0789 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
index 35e48cd8a133faa067827e444a25130c42472f90..0e005d35189db0a08918ed7eb4d4c5c7545e6959 100644 (file)
 #define DEBUG_TYPE ::llvm::ScoreboardHazardRecognizer::DebugType
 #include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
 #include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetInstrItineraries.h"
 
 using namespace llvm;
 
index ca70adafc08b4f6580f0608836fb7e667eac9b6d..63ca326417135e6f965216aa201fb0a7b1b68193 100644 (file)
@@ -17,6 +17,7 @@
 #include "ScheduleDAGSDNodes.h"
 #include "InstrEmitter.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetLowering.h"
index a8822e58d40f27e0372b4ec090938f2f26dc25b2..83b1f0542c326af34c07be76b18e45edba0a65c1 100644 (file)
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
 #include "llvm/Module.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Host.h"
-#include "llvm/Target/SubtargetFeature.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetRegistry.h"
 using namespace llvm;
diff --git a/lib/MC/SubtargetFeature.cpp b/lib/MC/SubtargetFeature.cpp
new file mode 100644 (file)
index 0000000..3ed122a
--- /dev/null
@@ -0,0 +1,384 @@
+//===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SubtargetFeature interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/StringExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cstdlib>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//                          Static Helper Functions
+//===----------------------------------------------------------------------===//
+
+/// hasFlag - Determine if a feature has a flag; '+' or '-'
+///
+static inline bool hasFlag(const std::string &Feature) {
+  assert(!Feature.empty() && "Empty string");
+  // Get first character
+  char Ch = Feature[0];
+  // Check if first character is '+' or '-' flag
+  return Ch == '+' || Ch =='-';
+}
+
+/// StripFlag - Return string stripped of flag.
+///
+static inline std::string StripFlag(const std::string &Feature) {
+  return hasFlag(Feature) ? Feature.substr(1) : Feature;
+}
+
+/// isEnabled - Return true if enable flag; '+'.
+///
+static inline bool isEnabled(const std::string &Feature) {
+  assert(!Feature.empty() && "Empty string");
+  // Get first character
+  char Ch = Feature[0];
+  // Check if first character is '+' for enabled
+  return Ch == '+';
+}
+
+/// PrependFlag - Return a string with a prepended flag; '+' or '-'.
+///
+static inline std::string PrependFlag(const std::string &Feature,
+                                      bool IsEnabled) {
+  assert(!Feature.empty() && "Empty string");
+  if (hasFlag(Feature)) return Feature;
+  return std::string(IsEnabled ? "+" : "-") + Feature;
+}
+
+/// Split - Splits a string of comma separated items in to a vector of strings.
+///
+static void Split(std::vector<std::string> &V, const std::string &S) {
+  // Start at beginning of string.
+  size_t Pos = 0;
+  while (true) {
+    // Find the next comma
+    size_t Comma = S.find(',', Pos);
+    // If no comma found then the rest of the string is used
+    if (Comma == std::string::npos) {
+      // Add string to vector
+      V.push_back(S.substr(Pos));
+      break;
+    }
+    // Otherwise add substring to vector
+    V.push_back(S.substr(Pos, Comma - Pos));
+    // Advance to next item
+    Pos = Comma + 1;
+  }
+}
+
+/// Join a vector of strings to a string with a comma separating each element.
+///
+static std::string Join(const std::vector<std::string> &V) {
+  // Start with empty string.
+  std::string Result;
+  // If the vector is not empty 
+  if (!V.empty()) {
+    // Start with the CPU feature
+    Result = V[0];
+    // For each successive feature
+    for (size_t i = 1; i < V.size(); i++) {
+      // Add a comma
+      Result += ",";
+      // Add the feature
+      Result += V[i];
+    }
+  }
+  // Return the features string 
+  return Result;
+}
+
+/// Adding features.
+void SubtargetFeatures::AddFeature(const std::string &String,
+                                   bool IsEnabled) {
+  // Don't add empty features
+  if (!String.empty()) {
+    // Convert to lowercase, prepend flag and add to vector
+    Features.push_back(PrependFlag(LowercaseString(String), IsEnabled));
+  }
+}
+
+/// Find KV in array using binary search.
+template<typename T> const T *Find(const std::string &S, const T *A, size_t L) {
+  // Make the lower bound element we're looking for
+  T KV;
+  KV.Key = S.c_str();
+  // Determine the end of the array
+  const T *Hi = A + L;
+  // Binary search the array
+  const T *F = std::lower_bound(A, Hi, KV);
+  // If not found then return NULL
+  if (F == Hi || std::string(F->Key) != S) return NULL;
+  // Return the found array item
+  return F;
+}
+
+/// getLongestEntryLength - Return the length of the longest entry in the table.
+///
+static size_t getLongestEntryLength(const SubtargetFeatureKV *Table,
+                                    size_t Size) {
+  size_t MaxLen = 0;
+  for (size_t i = 0; i < Size; i++)
+    MaxLen = std::max(MaxLen, std::strlen(Table[i].Key));
+  return MaxLen;
+}
+
+/// Display help for feature choices.
+///
+static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize,
+                 const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) {
+  // Determine the length of the longest CPU and Feature entries.
+  unsigned MaxCPULen  = getLongestEntryLength(CPUTable, CPUTableSize);
+  unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize);
+
+  // Print the CPU table.
+  errs() << "Available CPUs for this target:\n\n";
+  for (size_t i = 0; i != CPUTableSize; i++)
+    errs() << "  " << CPUTable[i].Key
+         << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ')
+         << " - " << CPUTable[i].Desc << ".\n";
+  errs() << "\n";
+  
+  // Print the Feature table.
+  errs() << "Available features for this target:\n\n";
+  for (size_t i = 0; i != FeatTableSize; i++)
+    errs() << "  " << FeatTable[i].Key
+         << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ')
+         << " - " << FeatTable[i].Desc << ".\n";
+  errs() << "\n";
+  
+  errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
+       << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
+  std::exit(1);
+}
+
+//===----------------------------------------------------------------------===//
+//                    SubtargetFeatures Implementation
+//===----------------------------------------------------------------------===//
+
+SubtargetFeatures::SubtargetFeatures(const std::string &Initial) {
+  // Break up string into separate features
+  Split(Features, Initial);
+}
+
+
+std::string SubtargetFeatures::getString() const {
+  return Join(Features);
+}
+void SubtargetFeatures::setString(const std::string &Initial) {
+  // Throw out old features
+  Features.clear();
+  // Break up string into separate features
+  Split(Features, LowercaseString(Initial));
+}
+
+
+/// setCPU - Set the CPU string.  Replaces previous setting.  Setting to ""
+/// clears CPU.
+void SubtargetFeatures::setCPU(const std::string &String) {
+  Features[0] = LowercaseString(String);
+}
+
+
+/// setCPUIfNone - Setting CPU string only if no string is set.
+///
+void SubtargetFeatures::setCPUIfNone(const std::string &String) {
+  if (Features[0].empty()) setCPU(String);
+}
+
+/// getCPU - Returns current CPU.
+///
+const std::string & SubtargetFeatures::getCPU() const {
+  return Features[0];
+}
+
+
+/// SetImpliedBits - For each feature that is (transitively) implied by this
+/// feature, set it.
+///
+static
+void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
+                    const SubtargetFeatureKV *FeatureTable,
+                    size_t FeatureTableSize) {
+  for (size_t i = 0; i < FeatureTableSize; ++i) {
+    const SubtargetFeatureKV &FE = FeatureTable[i];
+
+    if (FeatureEntry->Value == FE.Value) continue;
+
+    if (FeatureEntry->Implies & FE.Value) {
+      Bits |= FE.Value;
+      SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+    }
+  }
+}
+
+/// ClearImpliedBits - For each feature that (transitively) implies this
+/// feature, clear it.
+/// 
+static
+void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
+                      const SubtargetFeatureKV *FeatureTable,
+                      size_t FeatureTableSize) {
+  for (size_t i = 0; i < FeatureTableSize; ++i) {
+    const SubtargetFeatureKV &FE = FeatureTable[i];
+
+    if (FeatureEntry->Value == FE.Value) continue;
+
+    if (FE.Implies & FeatureEntry->Value) {
+      Bits &= ~FE.Value;
+      ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+    }
+  }
+}
+
+/// getBits - Get feature bits.
+///
+uint64_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable,
+                                          size_t CPUTableSize,
+                                    const SubtargetFeatureKV *FeatureTable,
+                                          size_t FeatureTableSize) {
+  assert(CPUTable && "missing CPU table");
+  assert(FeatureTable && "missing features table");
+#ifndef NDEBUG
+  for (size_t i = 1; i < CPUTableSize; i++) {
+    assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 &&
+           "CPU table is not sorted");
+  }
+  for (size_t i = 1; i < FeatureTableSize; i++) {
+    assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 &&
+          "CPU features table is not sorted");
+  }
+#endif
+  uint64_t Bits = 0;                    // Resulting bits
+
+  // Check if help is needed
+  if (Features[0] == "help")
+    Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
+  
+  // Find CPU entry
+  const SubtargetFeatureKV *CPUEntry =
+                            Find(Features[0], CPUTable, CPUTableSize);
+  // If there is a match
+  if (CPUEntry) {
+    // Set base feature bits
+    Bits = CPUEntry->Value;
+
+    // Set the feature implied by this CPU feature, if any.
+    for (size_t i = 0; i < FeatureTableSize; ++i) {
+      const SubtargetFeatureKV &FE = FeatureTable[i];
+      if (CPUEntry->Value & FE.Value)
+        SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
+    }
+  } else {
+    errs() << "'" << Features[0]
+           << "' is not a recognized processor for this target"
+           << " (ignoring processor)\n";
+  }
+  // Iterate through each feature
+  for (size_t i = 1; i < Features.size(); i++) {
+    const std::string &Feature = Features[i];
+    
+    // Check for help
+    if (Feature == "+help")
+      Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
+    
+    // Find feature in table.
+    const SubtargetFeatureKV *FeatureEntry =
+                       Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
+    // If there is a match
+    if (FeatureEntry) {
+      // Enable/disable feature in bits
+      if (isEnabled(Feature)) {
+        Bits |=  FeatureEntry->Value;
+
+        // For each feature that this implies, set it.
+        SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+      } else {
+        Bits &= ~FeatureEntry->Value;
+
+        // For each feature that implies this, clear it.
+        ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
+      }
+    } else {
+      errs() << "'" << Feature
+             << "' is not a recognized feature for this target"
+             << " (ignoring feature)\n";
+    }
+  }
+
+  return Bits;
+}
+
+/// Get info pointer
+void *SubtargetFeatures::getInfo(const SubtargetInfoKV *Table,
+                                       size_t TableSize) {
+  assert(Table && "missing table");
+#ifndef NDEBUG
+  for (size_t i = 1; i < TableSize; i++) {
+    assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted");
+  }
+#endif
+
+  // Find entry
+  const SubtargetInfoKV *Entry = Find(Features[0], Table, TableSize);
+  
+  if (Entry) {
+    return Entry->Value;
+  } else {
+    errs() << "'" << Features[0]
+           << "' is not a recognized processor for this target"
+           << " (ignoring processor)\n";
+    return NULL;
+  }
+}
+
+/// print - Print feature string.
+///
+void SubtargetFeatures::print(raw_ostream &OS) const {
+  for (size_t i = 0, e = Features.size(); i != e; ++i)
+    OS << Features[i] << "  ";
+  OS << "\n";
+}
+
+/// dump - Dump feature info.
+///
+void SubtargetFeatures::dump() const {
+  print(dbgs());
+}
+
+/// getDefaultSubtargetFeatures - Return a string listing the features
+/// associated with the target triple.
+///
+/// FIXME: This is an inelegant way of specifying the features of a
+/// subtarget. It would be better if we could encode this information
+/// into the IR. See <rdar://5972456>.
+///
+void SubtargetFeatures::getDefaultSubtargetFeatures(const std::string &CPU,
+                                                    const Triple& Triple) {
+  setCPU(CPU);
+
+  if (Triple.getVendor() == Triple::Apple) {
+    if (Triple.getArch() == Triple::ppc) {
+      // powerpc-apple-*
+      AddFeature("altivec");
+    } else if (Triple.getArch() == Triple::ppc64) {
+      // powerpc64-apple-*
+      AddFeature("64bit");
+      AddFeature("altivec");
+    }
+  }
+}
index 0271c873f191a92942c00925f408e9230d3b8689..e4bcf3e364158086342baa14257e84e42705a9c1 100644 (file)
@@ -14,9 +14,8 @@
 #ifndef ARMSUBTARGET_H
 #define ARMSUBTARGET_H
 
-#include "llvm/Target/TargetInstrItineraries.h"
-#include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetSubtarget.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/ADT/Triple.h"
 #include <string>
 
index f0eb93c6cba2e62b63210af95941901b4d4b3f92..ab7d1e0562042b49c264ba7c0ecbc797f1e3a045 100644 (file)
@@ -14,9 +14,8 @@
 #ifndef ALPHASUBTARGET_H
 #define ALPHASUBTARGET_H
 
-#include "llvm/Target/TargetInstrItineraries.h"
 #include "llvm/Target/TargetSubtarget.h"
-
+#include "llvm/MC/MCInstrItineraries.h"
 #include <string>
 
 namespace llvm {
index d7929302f0806b5bc60c1ed2a2f366af749ab69e..39b2d86196cce1e028e9dbf238f8cf422fe22a8b 100644 (file)
@@ -14,9 +14,8 @@
 #ifndef CELLSUBTARGET_H
 #define CELLSUBTARGET_H
 
-#include "llvm/Target/TargetInstrItineraries.h"
 #include "llvm/Target/TargetSubtarget.h"
-
+#include "llvm/MC/MCInstrItineraries.h"
 #include <string>
 
 namespace llvm {
index 2255b2809be2a6dc517f38c30d09967ab458982b..342b2fb65d721090e821a18dd606f886a90cdff0 100644 (file)
@@ -15,8 +15,7 @@
 #define MBLAZESUBTARGET_H
 
 #include "llvm/Target/TargetSubtarget.h"
-#include "llvm/Target/TargetMachine.h"
-
+#include "llvm/MC/MCInstrItineraries.h"
 #include <string>
 
 namespace llvm {
index 096bbed7b047c857426de529e483953ab2c5baca..f09df6b9a114884abe630ce4201df5e9afb12f83 100644 (file)
@@ -15,8 +15,7 @@
 #define MIPSSUBTARGET_H
 
 #include "llvm/Target/TargetSubtarget.h"
-#include "llvm/Target/TargetMachine.h"
-
+#include "llvm/MC/MCInstrItineraries.h"
 #include <string>
 
 namespace llvm {
index 8fd1a447692d762c1e0244427e8931ce4ea7a5c5..799bb3dd81fab99545630973a37979332b9c6608 100644 (file)
 #ifndef POWERPCSUBTARGET_H
 #define POWERPCSUBTARGET_H
 
-#include "llvm/ADT/Triple.h"
-#include "llvm/Target/TargetInstrItineraries.h"
 #include "llvm/Target/TargetSubtarget.h"
-
+#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/ADT/Triple.h"
 #include <string>
 
 // GCC #defines PPC on Linux but we use it as our namespace name
diff --git a/lib/Target/SubtargetFeature.cpp b/lib/Target/SubtargetFeature.cpp
deleted file mode 100644 (file)
index e0a9de8..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-//===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the SubtargetFeature interface.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Target/SubtargetFeature.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/StringExtras.h"
-#include <algorithm>
-#include <cassert>
-#include <cctype>
-#include <cstdlib>
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-//                          Static Helper Functions
-//===----------------------------------------------------------------------===//
-
-/// hasFlag - Determine if a feature has a flag; '+' or '-'
-///
-static inline bool hasFlag(const std::string &Feature) {
-  assert(!Feature.empty() && "Empty string");
-  // Get first character
-  char Ch = Feature[0];
-  // Check if first character is '+' or '-' flag
-  return Ch == '+' || Ch =='-';
-}
-
-/// StripFlag - Return string stripped of flag.
-///
-static inline std::string StripFlag(const std::string &Feature) {
-  return hasFlag(Feature) ? Feature.substr(1) : Feature;
-}
-
-/// isEnabled - Return true if enable flag; '+'.
-///
-static inline bool isEnabled(const std::string &Feature) {
-  assert(!Feature.empty() && "Empty string");
-  // Get first character
-  char Ch = Feature[0];
-  // Check if first character is '+' for enabled
-  return Ch == '+';
-}
-
-/// PrependFlag - Return a string with a prepended flag; '+' or '-'.
-///
-static inline std::string PrependFlag(const std::string &Feature,
-                                      bool IsEnabled) {
-  assert(!Feature.empty() && "Empty string");
-  if (hasFlag(Feature)) return Feature;
-  return std::string(IsEnabled ? "+" : "-") + Feature;
-}
-
-/// Split - Splits a string of comma separated items in to a vector of strings.
-///
-static void Split(std::vector<std::string> &V, const std::string &S) {
-  // Start at beginning of string.
-  size_t Pos = 0;
-  while (true) {
-    // Find the next comma
-    size_t Comma = S.find(',', Pos);
-    // If no comma found then the rest of the string is used
-    if (Comma == std::string::npos) {
-      // Add string to vector
-      V.push_back(S.substr(Pos));
-      break;
-    }
-    // Otherwise add substring to vector
-    V.push_back(S.substr(Pos, Comma - Pos));
-    // Advance to next item
-    Pos = Comma + 1;
-  }
-}
-
-/// Join a vector of strings to a string with a comma separating each element.
-///
-static std::string Join(const std::vector<std::string> &V) {
-  // Start with empty string.
-  std::string Result;
-  // If the vector is not empty 
-  if (!V.empty()) {
-    // Start with the CPU feature
-    Result = V[0];
-    // For each successive feature
-    for (size_t i = 1; i < V.size(); i++) {
-      // Add a comma
-      Result += ",";
-      // Add the feature
-      Result += V[i];
-    }
-  }
-  // Return the features string 
-  return Result;
-}
-
-/// Adding features.
-void SubtargetFeatures::AddFeature(const std::string &String,
-                                   bool IsEnabled) {
-  // Don't add empty features
-  if (!String.empty()) {
-    // Convert to lowercase, prepend flag and add to vector
-    Features.push_back(PrependFlag(LowercaseString(String), IsEnabled));
-  }
-}
-
-/// Find KV in array using binary search.
-template<typename T> const T *Find(const std::string &S, const T *A, size_t L) {
-  // Make the lower bound element we're looking for
-  T KV;
-  KV.Key = S.c_str();
-  // Determine the end of the array
-  const T *Hi = A + L;
-  // Binary search the array
-  const T *F = std::lower_bound(A, Hi, KV);
-  // If not found then return NULL
-  if (F == Hi || std::string(F->Key) != S) return NULL;
-  // Return the found array item
-  return F;
-}
-
-/// getLongestEntryLength - Return the length of the longest entry in the table.
-///
-static size_t getLongestEntryLength(const SubtargetFeatureKV *Table,
-                                    size_t Size) {
-  size_t MaxLen = 0;
-  for (size_t i = 0; i < Size; i++)
-    MaxLen = std::max(MaxLen, std::strlen(Table[i].Key));
-  return MaxLen;
-}
-
-/// Display help for feature choices.
-///
-static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize,
-                 const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) {
-  // Determine the length of the longest CPU and Feature entries.
-  unsigned MaxCPULen  = getLongestEntryLength(CPUTable, CPUTableSize);
-  unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize);
-
-  // Print the CPU table.
-  errs() << "Available CPUs for this target:\n\n";
-  for (size_t i = 0; i != CPUTableSize; i++)
-    errs() << "  " << CPUTable[i].Key
-         << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ')
-         << " - " << CPUTable[i].Desc << ".\n";
-  errs() << "\n";
-  
-  // Print the Feature table.
-  errs() << "Available features for this target:\n\n";
-  for (size_t i = 0; i != FeatTableSize; i++)
-    errs() << "  " << FeatTable[i].Key
-         << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ')
-         << " - " << FeatTable[i].Desc << ".\n";
-  errs() << "\n";
-  
-  errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
-       << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
-  std::exit(1);
-}
-
-//===----------------------------------------------------------------------===//
-//                    SubtargetFeatures Implementation
-//===----------------------------------------------------------------------===//
-
-SubtargetFeatures::SubtargetFeatures(const std::string &Initial) {
-  // Break up string into separate features
-  Split(Features, Initial);
-}
-
-
-std::string SubtargetFeatures::getString() const {
-  return Join(Features);
-}
-void SubtargetFeatures::setString(const std::string &Initial) {
-  // Throw out old features
-  Features.clear();
-  // Break up string into separate features
-  Split(Features, LowercaseString(Initial));
-}
-
-
-/// setCPU - Set the CPU string.  Replaces previous setting.  Setting to ""
-/// clears CPU.
-void SubtargetFeatures::setCPU(const std::string &String) {
-  Features[0] = LowercaseString(String);
-}
-
-
-/// setCPUIfNone - Setting CPU string only if no string is set.
-///
-void SubtargetFeatures::setCPUIfNone(const std::string &String) {
-  if (Features[0].empty()) setCPU(String);
-}
-
-/// getCPU - Returns current CPU.
-///
-const std::string & SubtargetFeatures::getCPU() const {
-  return Features[0];
-}
-
-
-/// SetImpliedBits - For each feature that is (transitively) implied by this
-/// feature, set it.
-///
-static
-void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
-                    const SubtargetFeatureKV *FeatureTable,
-                    size_t FeatureTableSize) {
-  for (size_t i = 0; i < FeatureTableSize; ++i) {
-    const SubtargetFeatureKV &FE = FeatureTable[i];
-
-    if (FeatureEntry->Value == FE.Value) continue;
-
-    if (FeatureEntry->Implies & FE.Value) {
-      Bits |= FE.Value;
-      SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
-    }
-  }
-}
-
-/// ClearImpliedBits - For each feature that (transitively) implies this
-/// feature, clear it.
-/// 
-static
-void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
-                      const SubtargetFeatureKV *FeatureTable,
-                      size_t FeatureTableSize) {
-  for (size_t i = 0; i < FeatureTableSize; ++i) {
-    const SubtargetFeatureKV &FE = FeatureTable[i];
-
-    if (FeatureEntry->Value == FE.Value) continue;
-
-    if (FE.Implies & FeatureEntry->Value) {
-      Bits &= ~FE.Value;
-      ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
-    }
-  }
-}
-
-/// getBits - Get feature bits.
-///
-uint64_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable,
-                                          size_t CPUTableSize,
-                                    const SubtargetFeatureKV *FeatureTable,
-                                          size_t FeatureTableSize) {
-  assert(CPUTable && "missing CPU table");
-  assert(FeatureTable && "missing features table");
-#ifndef NDEBUG
-  for (size_t i = 1; i < CPUTableSize; i++) {
-    assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 &&
-           "CPU table is not sorted");
-  }
-  for (size_t i = 1; i < FeatureTableSize; i++) {
-    assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 &&
-          "CPU features table is not sorted");
-  }
-#endif
-  uint64_t Bits = 0;                    // Resulting bits
-
-  // Check if help is needed
-  if (Features[0] == "help")
-    Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
-  
-  // Find CPU entry
-  const SubtargetFeatureKV *CPUEntry =
-                            Find(Features[0], CPUTable, CPUTableSize);
-  // If there is a match
-  if (CPUEntry) {
-    // Set base feature bits
-    Bits = CPUEntry->Value;
-
-    // Set the feature implied by this CPU feature, if any.
-    for (size_t i = 0; i < FeatureTableSize; ++i) {
-      const SubtargetFeatureKV &FE = FeatureTable[i];
-      if (CPUEntry->Value & FE.Value)
-        SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
-    }
-  } else {
-    errs() << "'" << Features[0]
-           << "' is not a recognized processor for this target"
-           << " (ignoring processor)\n";
-  }
-  // Iterate through each feature
-  for (size_t i = 1; i < Features.size(); i++) {
-    const std::string &Feature = Features[i];
-    
-    // Check for help
-    if (Feature == "+help")
-      Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
-    
-    // Find feature in table.
-    const SubtargetFeatureKV *FeatureEntry =
-                       Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
-    // If there is a match
-    if (FeatureEntry) {
-      // Enable/disable feature in bits
-      if (isEnabled(Feature)) {
-        Bits |=  FeatureEntry->Value;
-
-        // For each feature that this implies, set it.
-        SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
-      } else {
-        Bits &= ~FeatureEntry->Value;
-
-        // For each feature that implies this, clear it.
-        ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
-      }
-    } else {
-      errs() << "'" << Feature
-             << "' is not a recognized feature for this target"
-             << " (ignoring feature)\n";
-    }
-  }
-
-  return Bits;
-}
-
-/// Get info pointer
-void *SubtargetFeatures::getInfo(const SubtargetInfoKV *Table,
-                                       size_t TableSize) {
-  assert(Table && "missing table");
-#ifndef NDEBUG
-  for (size_t i = 1; i < TableSize; i++) {
-    assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted");
-  }
-#endif
-
-  // Find entry
-  const SubtargetInfoKV *Entry = Find(Features[0], Table, TableSize);
-  
-  if (Entry) {
-    return Entry->Value;
-  } else {
-    errs() << "'" << Features[0]
-           << "' is not a recognized processor for this target"
-           << " (ignoring processor)\n";
-    return NULL;
-  }
-}
-
-/// print - Print feature string.
-///
-void SubtargetFeatures::print(raw_ostream &OS) const {
-  for (size_t i = 0, e = Features.size(); i != e; ++i)
-    OS << Features[i] << "  ";
-  OS << "\n";
-}
-
-/// dump - Dump feature info.
-///
-void SubtargetFeatures::dump() const {
-  print(dbgs());
-}
-
-/// getDefaultSubtargetFeatures - Return a string listing the features
-/// associated with the target triple.
-///
-/// FIXME: This is an inelegant way of specifying the features of a
-/// subtarget. It would be better if we could encode this information
-/// into the IR. See <rdar://5972456>.
-///
-void SubtargetFeatures::getDefaultSubtargetFeatures(const std::string &CPU,
-                                                    const Triple& Triple) {
-  setCPU(CPU);
-
-  if (Triple.getVendor() == Triple::Apple) {
-    if (Triple.getArch() == Triple::ppc) {
-      // powerpc-apple-*
-      AddFeature("altivec");
-    } else if (Triple.getArch() == Triple::ppc64) {
-      // powerpc64-apple-*
-      AddFeature("64bit");
-      AddFeature("altivec");
-    }
-  }
-}
index d30bb6c379c69cfa3a9dc7babb1179679ae0c562..2931416febb076415451f4d83debbf848030d9f9 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetInstrItineraries.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <cctype>
 using namespace llvm;
index 162d6c8ad9ca6ffda26582dd761123fd5cd34e1f..e89b4d8318b3a1d6856c91b1dfa1455de66ff056 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
 #include "llvm/Config/config.h"
+#include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FormattedStream.h"
@@ -31,7 +32,6 @@
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Signals.h"
-#include "llvm/Target/SubtargetFeature.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetRegistry.h"
index 077f0e6700ba0c126d022f101db59e305bca9b85..e2244597af990bc02755f41de494148464935f2f 100644 (file)
 #include "llvm/MC/MCInstPrinter.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Target/TargetAsmBackend.h"
 #include "llvm/Target/TargetAsmParser.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/SubtargetFeature.h" // FIXME.
 #include "llvm/Target/TargetAsmInfo.h"  // FIXME.
 #include "llvm/Target/TargetLowering.h"  // FIXME.
 #include "llvm/Target/TargetLoweringObjectFile.h"  // FIXME.
index 3abd6413657335328c94390ae467cd0535d6e777..f175255c515933197aed699820c128c3f80cd36b 100644 (file)
@@ -26,8 +26,8 @@
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
+#include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Target/Mangler.h"
-#include "llvm/Target/SubtargetFeature.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
index 4e754f6dce90a23fbebc396b39c4289e54a54418..814d80bda077652e7c726395ca88f53edc1d2e6e 100644 (file)
@@ -29,7 +29,6 @@
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/system_error.h"
 #include "llvm/Target/Mangler.h"
-#include "llvm/Target/SubtargetFeature.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
@@ -37,6 +36,7 @@
 #include "llvm/MC/MCParser/MCAsmParser.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Target/TargetAsmParser.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetRegistry.h"
index 928fa4bee9009851a784637b648e9ce819e7c59f..6899cb194a426b7acf23301ef6bbef5f1e64aaf9 100644 (file)
@@ -654,8 +654,8 @@ void SubtargetEmitter::run(raw_ostream &OS) {
 
   OS << "#include \"llvm/Support/Debug.h\"\n";
   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
-  OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
-  OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
+  OS << "#include \"llvm/MC/SubtargetFeature.h\"\n";
+  OS << "#include \"llvm/MC/MCInstrItineraries.h\"\n\n";
 
 //  Enumeration(OS, "FuncUnit", true);
 //  OS<<"\n";
index 93055b7fec12655888b48cdf3bec8a5ab7c07d5d..cf793c880bc70437dbfd90fbb894e779008eb1c4 100644 (file)
@@ -15,7 +15,7 @@
 #define SUBTARGET_EMITTER_H
 
 #include "TableGenBackend.h"
-#include "llvm/Target/TargetInstrItineraries.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include <vector>
 #include <map>
 #include <string>