aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2010-04-07 18:19:32 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2010-04-07 18:19:32 +0000
commit9cc241abf0f6d769c2b3c23424279bd6f53de181 (patch)
tree11f979db3890993a7fbe28524bba4ff6870449b2
parent60fb802a477298b4ed4a1b8a38bdd729b3bd1de8 (diff)
downloadexternal_llvm-9cc241abf0f6d769c2b3c23424279bd6f53de181.zip
external_llvm-9cc241abf0f6d769c2b3c23424279bd6f53de181.tar.gz
external_llvm-9cc241abf0f6d769c2b3c23424279bd6f53de181.tar.bz2
Initial support for different kinds of FU reservation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100645 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetInstrItineraries.h20
-rw-r--r--include/llvm/Target/TargetSchedule.td11
-rw-r--r--lib/CodeGen/ExactHazardRecognizer.cpp53
-rw-r--r--lib/CodeGen/ExactHazardRecognizer.h3
-rw-r--r--utils/TableGen/SubtargetEmitter.cpp9
5 files changed, 79 insertions, 17 deletions
diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h
index 420fa94..3dfa8bc 100644
--- a/include/llvm/Target/TargetInstrItineraries.h
+++ b/include/llvm/Target/TargetInstrItineraries.h
@@ -47,10 +47,24 @@ namespace llvm {
/// 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
+ 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 {
@@ -62,6 +76,10 @@ struct InstrStage {
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 {
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index dcc0992..bbf43de 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -22,6 +22,13 @@
//
class FuncUnit;
+class ReservationKind<bits<1> val> {
+ bits<1> Value = val;
+}
+
+def Required : ReservationKind<0>;
+def Reserved : ReservationKind<1>;
+
//===----------------------------------------------------------------------===//
// Instruction stage - These values represent a non-pipelined step in
// the execution of an instruction. Cycles represents the number of
@@ -36,10 +43,12 @@ class FuncUnit;
// InstrStage<1, [FU_x, FU_y]> - TimeInc defaults to Cycles
// InstrStage<1, [FU_x, FU_y], 0> - TimeInc explicit
//
-class InstrStage<int cycles, list<FuncUnit> units, int timeinc = -1> {
+class InstrStage<int cycles, list<FuncUnit> units,
+ int timeinc = -1, ReservationKind kind = Required> {
int Cycles = cycles; // length of stage in machine cycles
list<FuncUnit> Units = units; // choice of functional units
int TimeInc = timeinc; // cycles till start of next stage
+ int Kind = kind.Value; // kind of FU reservation
}
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/ExactHazardRecognizer.cpp b/lib/CodeGen/ExactHazardRecognizer.cpp
index 52908ed..af5f289 100644
--- a/lib/CodeGen/ExactHazardRecognizer.cpp
+++ b/lib/CodeGen/ExactHazardRecognizer.cpp
@@ -45,14 +45,16 @@ ExactHazardRecognizer(const InstrItineraryData &LItinData) :
}
}
- Scoreboard.reset(ScoreboardDepth);
+ ReservedScoreboard.reset(ScoreboardDepth);
+ RequiredScoreboard.reset(ScoreboardDepth);
DEBUG(dbgs() << "Using exact hazard recognizer: ScoreboardDepth = "
<< ScoreboardDepth << '\n');
}
void ExactHazardRecognizer::Reset() {
- Scoreboard.reset();
+ RequiredScoreboard.reset();
+ ReservedScoreboard.reset();
}
void ExactHazardRecognizer::ScoreBoard::dump() const {
@@ -86,10 +88,23 @@ ExactHazardRecognizer::HazardType ExactHazardRecognizer::getHazardType(SUnit *SU
// stage is occupied. FIXME it would be more accurate to find the
// same unit free in all the cycles.
for (unsigned int i = 0; i < IS->getCycles(); ++i) {
- assert(((cycle + i) < Scoreboard.getDepth()) &&
+ assert(((cycle + i) < RequiredScoreboard.getDepth()) &&
"Scoreboard depth exceeded!");
- unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
+ unsigned freeUnits = IS->getUnits();
+ switch (IS->getReservationKind()) {
+ default:
+ assert(0 && "Invalid FU reservation");
+ case InstrStage::Required:
+ // Required FUs conflict with both reserved and required ones
+ freeUnits &= ~ReservedScoreboard[cycle + i];
+ // FALLTHROUGH
+ case InstrStage::Reserved:
+ // Reserved FUs can conflict only with required ones.
+ freeUnits &= ~RequiredScoreboard[cycle + i];
+ break;
+ }
+
if (!freeUnits) {
DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", ");
DEBUG(dbgs() << "SU(" << SU->NodeNum << "): ");
@@ -114,16 +129,28 @@ void ExactHazardRecognizer::EmitInstruction(SUnit *SU) {
// Use the itinerary for the underlying instruction to reserve FU's
// in the scoreboard at the appropriate future cycles.
unsigned idx = SU->getInstr()->getDesc().getSchedClass();
- for (const InstrStage *IS = ItinData.beginStage(idx),
+ for (const InstrStage *IS = ItinData.beginStage(idx),
*E = ItinData.endStage(idx); IS != E; ++IS) {
// We must reserve one of the stage's units for every cycle the
// stage is occupied. FIXME it would be more accurate to reserve
// the same unit free in all the cycles.
for (unsigned int i = 0; i < IS->getCycles(); ++i) {
- assert(((cycle + i) < Scoreboard.getDepth()) &&
+ assert(((cycle + i) < RequiredScoreboard.getDepth()) &&
"Scoreboard depth exceeded!");
- unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
+ unsigned freeUnits = IS->getUnits();
+ switch (IS->getReservationKind()) {
+ default:
+ assert(0 && "Invalid FU reservation");
+ case InstrStage::Required:
+ // Required FUs conflict with both reserved and required ones
+ freeUnits &= ~ReservedScoreboard[cycle + i];
+ // FALLTHROUGH
+ case InstrStage::Reserved:
+ // Reserved FUs can conflict only with required ones.
+ freeUnits &= ~RequiredScoreboard[cycle + i];
+ break;
+ }
// reduce to a single unit
unsigned freeUnit = 0;
@@ -133,17 +160,21 @@ void ExactHazardRecognizer::EmitInstruction(SUnit *SU) {
} while (freeUnits);
assert(freeUnit && "No function unit available!");
- Scoreboard[cycle + i] |= freeUnit;
+ if (IS->getReservationKind() == InstrStage::Required)
+ RequiredScoreboard[cycle + i] |= freeUnit;
+ else
+ ReservedScoreboard[cycle + i] |= freeUnit;
}
// Advance the cycle to the next stage.
cycle += IS->getNextCycles();
}
- DEBUG(Scoreboard.dump());
+ DEBUG(ReservedScoreboard.dump());
+ DEBUG(RequiredScoreboard.dump());
}
void ExactHazardRecognizer::AdvanceCycle() {
- Scoreboard[0] = 0;
- Scoreboard.advance();
+ ReservedScoreboard[0] = 0; ReservedScoreboard.advance();
+ RequiredScoreboard[0] = 0; RequiredScoreboard.advance();
}
diff --git a/lib/CodeGen/ExactHazardRecognizer.h b/lib/CodeGen/ExactHazardRecognizer.h
index 50fe024..91c81a9 100644
--- a/lib/CodeGen/ExactHazardRecognizer.h
+++ b/lib/CodeGen/ExactHazardRecognizer.h
@@ -70,7 +70,8 @@ namespace llvm {
// Itinerary data for the target.
const InstrItineraryData &ItinData;
- ScoreBoard Scoreboard;
+ ScoreBoard ReservedScoreboard;
+ ScoreBoard RequiredScoreboard;
public:
ExactHazardRecognizer(const InstrItineraryData &ItinData);
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
index 9ac652f..fb86a70 100644
--- a/utils/TableGen/SubtargetEmitter.cpp
+++ b/utils/TableGen/SubtargetEmitter.cpp
@@ -216,7 +216,7 @@ void SubtargetEmitter::FormItineraryStageString(Record *ItinData,
// Next stage
const Record *Stage = StageList[i];
- // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc }
+ // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
int Cycles = Stage->getValueAsInt("Cycles");
ItinString += " { " + itostr(Cycles) + ", ";
@@ -233,6 +233,9 @@ void SubtargetEmitter::FormItineraryStageString(Record *ItinData,
int TimeInc = Stage->getValueAsInt("TimeInc");
ItinString += ", " + itostr(TimeInc);
+ int Kind = Stage->getValueAsInt("Kind");
+ ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
+
// Close off stage
ItinString += " }";
if (++i < N) ItinString += ", ";
@@ -278,7 +281,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
// Begin stages table
std::string StageTable = "static const llvm::InstrStage Stages[] = {\n";
- StageTable += " { 0, 0, 0 }, // No itinerary\n";
+ StageTable += " { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
// Begin operand cycle table
std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
@@ -367,7 +370,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
}
// Closing stage
- StageTable += " { 0, 0, 0 } // End itinerary\n";
+ StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
StageTable += "};\n";
// Closing operand cycles