forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Post RA scheduler changes. Introduce a hazard recognizer that uses th…
…e target schedule information to accurately model the pipeline. Update the scheduler to correctly handle multi-issue targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78563 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
David Goodwin
committed
Aug 10, 2009
1 parent
65f2e78
commit d94a4e5
Showing
8 changed files
with
342 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
//===----- ExactHazardRecognizer.cpp - hazard recognizer -------- ---------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This implements a a hazard recognizer using the instructions itineraries | ||
// defined for the current target. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#define DEBUG_TYPE "exact-hazards" | ||
#include "ExactHazardRecognizer.h" | ||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h" | ||
#include "llvm/Support/Debug.h" | ||
#include "llvm/Support/ErrorHandling.h" | ||
#include "llvm/Target/TargetInstrItineraries.h" | ||
|
||
namespace llvm { | ||
|
||
ExactHazardRecognizer::ExactHazardRecognizer(const InstrItineraryData &LItinData) : | ||
ScheduleHazardRecognizer(), ItinData(LItinData) | ||
{ | ||
// Determine the maximum depth of any itinerary. This determines the | ||
// depth of the scoreboard. We always make the scoreboard at least 1 | ||
// cycle deep to avoid dealing with the boundary condition. | ||
ScoreboardDepth = 1; | ||
if (!ItinData.isEmpty()) { | ||
for (unsigned idx = 0; ; ++idx) { | ||
// If the begin stage of an itinerary has 0 cycles and units, | ||
// then we have reached the end of the itineraries. | ||
const InstrStage *IS = ItinData.begin(idx), *E = ItinData.end(idx); | ||
if ((IS->Cycles == 0) && (IS->Units == 0)) | ||
break; | ||
|
||
unsigned ItinDepth = 0; | ||
for (; IS != E; ++IS) | ||
ItinDepth += IS->Cycles; | ||
|
||
ScoreboardDepth = std::max(ScoreboardDepth, ItinDepth); | ||
} | ||
} | ||
|
||
Scoreboard = new unsigned[ScoreboardDepth]; | ||
ScoreboardHead = 0; | ||
|
||
DOUT << "Using exact hazard recognizer: ScoreboardDepth = " | ||
<< ScoreboardDepth << '\n'; | ||
} | ||
|
||
ExactHazardRecognizer::~ExactHazardRecognizer() { | ||
delete Scoreboard; | ||
} | ||
|
||
void ExactHazardRecognizer::Reset() { | ||
memset(Scoreboard, 0, ScoreboardDepth * sizeof(unsigned)); | ||
ScoreboardHead = 0; | ||
} | ||
|
||
unsigned ExactHazardRecognizer::getFutureIndex(unsigned offset) { | ||
return (ScoreboardHead + offset) % ScoreboardDepth; | ||
} | ||
|
||
void ExactHazardRecognizer::dumpScoreboard() { | ||
DOUT << "Scoreboard:\n"; | ||
|
||
unsigned last = ScoreboardDepth - 1; | ||
while ((last > 0) && (Scoreboard[getFutureIndex(last)] == 0)) | ||
last--; | ||
|
||
for (unsigned i = 0; i <= last; i++) { | ||
unsigned FUs = Scoreboard[getFutureIndex(i)]; | ||
DOUT << "\t"; | ||
for (int j = 31; j >= 0; j--) | ||
DOUT << ((FUs & (1 << j)) ? '1' : '0'); | ||
DOUT << '\n'; | ||
} | ||
} | ||
|
||
ExactHazardRecognizer::HazardType ExactHazardRecognizer::getHazardType(SUnit *SU) { | ||
unsigned cycle = 0; | ||
|
||
// Use the itinerary for the underlying instruction to check for | ||
// free FU's in the scoreboard at the appropriate future cycles. | ||
unsigned idx = SU->getInstr()->getDesc().getSchedClass(); | ||
for (const InstrStage *IS = ItinData.begin(idx), *E = ItinData.end(idx); | ||
IS != E; ++IS) { | ||
// We must find one of the stage's units free for every cycle the | ||
// stage is occupied. | ||
for (unsigned int i = 0; i < IS->Cycles; ++i) { | ||
assert((cycle < ScoreboardDepth) && "Scoreboard depth exceeded!"); | ||
|
||
unsigned index = getFutureIndex(cycle); | ||
unsigned freeUnits = IS->Units & ~Scoreboard[index]; | ||
if (!freeUnits) { | ||
DOUT << "*** Hazard in cycle " << cycle << ", "; | ||
DOUT << "SU(" << SU->NodeNum << "): "; | ||
DEBUG(SU->getInstr()->dump()); | ||
return Hazard; | ||
} | ||
|
||
++cycle; | ||
} | ||
} | ||
|
||
return NoHazard; | ||
} | ||
|
||
void ExactHazardRecognizer::EmitInstruction(SUnit *SU) { | ||
unsigned cycle = 0; | ||
|
||
// 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.begin(idx), *E = ItinData.end(idx); | ||
IS != E; ++IS) { | ||
// We must reserve one of the stage's units for every cycle the | ||
// stage is occupied. | ||
for (unsigned int i = 0; i < IS->Cycles; ++i) { | ||
assert((cycle < ScoreboardDepth) && "Scoreboard depth exceeded!"); | ||
|
||
unsigned index = getFutureIndex(cycle); | ||
unsigned freeUnits = IS->Units & ~Scoreboard[index]; | ||
|
||
// reduce to a single unit | ||
unsigned freeUnit = 0; | ||
do { | ||
freeUnit = freeUnits; | ||
freeUnits = freeUnit & (freeUnit - 1); | ||
} while (freeUnits); | ||
|
||
assert(freeUnit && "No function unit available!"); | ||
Scoreboard[index] |= freeUnit; | ||
++cycle; | ||
} | ||
} | ||
|
||
DEBUG(dumpScoreboard()); | ||
} | ||
|
||
void ExactHazardRecognizer::AdvanceCycle() { | ||
Scoreboard[ScoreboardHead] = 0; | ||
ScoreboardHead = getFutureIndex(1); | ||
} | ||
|
||
} /* namespace llvm */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
//=- llvm/CodeGen/ExactHazardRecognizer.h - Scheduling Support -*- C++ -*-=// | ||
// | ||
// 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 ExactHazardRecognizer class, which | ||
// implements hazard-avoidance heuristics for scheduling, based on the | ||
// scheduling itineraries specified for the target. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H | ||
#define LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H | ||
|
||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h" | ||
#include "llvm/CodeGen/ScheduleDAG.h" | ||
#include "llvm/Target/TargetInstrItineraries.h" | ||
|
||
namespace llvm { | ||
class ExactHazardRecognizer : public ScheduleHazardRecognizer { | ||
// Itinerary data for the target. | ||
const InstrItineraryData &ItinData; | ||
|
||
// Scoreboard to track function unit usage. Scoreboard[0] is a | ||
// mask of the FUs in use in the cycle currently being | ||
// schedule. Scoreboard[1] is a mask for the next cycle. The | ||
// Scoreboard is used as a circular buffer with the current cycle | ||
// indicated by ScoreboardHead. | ||
unsigned *Scoreboard; | ||
|
||
// The maximum number of cycles monitored by the Scoreboard. This | ||
// value is determined based on the target itineraries to ensure | ||
// that all hazards can be tracked. | ||
unsigned ScoreboardDepth; | ||
|
||
// Indices into the Scoreboard that represent the current cycle. | ||
unsigned ScoreboardHead; | ||
|
||
// Return the scoreboard index to use for 'offset' cycles in the | ||
// future. 'offset' of 0 returns ScoreboardHead. | ||
unsigned getFutureIndex(unsigned offset); | ||
|
||
// Print the scoreboard. | ||
void dumpScoreboard(); | ||
|
||
public: | ||
ExactHazardRecognizer(const InstrItineraryData &ItinData); | ||
~ExactHazardRecognizer(); | ||
|
||
virtual HazardType getHazardType(SUnit *SU); | ||
virtual void Reset(); | ||
virtual void EmitInstruction(SUnit *SU); | ||
virtual void AdvanceCycle(); | ||
}; | ||
} | ||
|
||
#endif |
Oops, something went wrong.