--- /dev/null
+//===-- 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
--- /dev/null
+//===-- 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
+++ /dev/null
-//===-- 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
+++ /dev/null
-//===-- 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
#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;
#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"
#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"
#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"
#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;
#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"
#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;
--- /dev/null
+//===- 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");
+ }
+ }
+}
#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>
#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 {
#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 {
#define MBLAZESUBTARGET_H
#include "llvm/Target/TargetSubtarget.h"
-#include "llvm/Target/TargetMachine.h"
-
+#include "llvm/MC/MCInstrItineraries.h"
#include <string>
namespace llvm {
#define MIPSSUBTARGET_H
#include "llvm/Target/TargetSubtarget.h"
-#include "llvm/Target/TargetMachine.h"
-
+#include "llvm/MC/MCInstrItineraries.h"
#include <string>
namespace llvm {
#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
+++ /dev/null
-//===- 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");
- }
- }
-}
//===----------------------------------------------------------------------===//
#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;
#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"
#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"
#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.
#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"
#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"
#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"
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";
#define SUBTARGET_EMITTER_H
#include "TableGenBackend.h"
-#include "llvm/Target/TargetInstrItineraries.h"
+#include "llvm/MC/MCInstrItineraries.h"
#include <vector>
#include <map>
#include <string>