Use vectors instead of hash_maps for issueGaps and conflictLists.

These hash lookups were a major sink of time because they happen so often!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4136 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve
2002-10-13 00:37:46 +00:00
parent 516b26fd86
commit 5aefcad35b
2 changed files with 38 additions and 31 deletions

View File

@@ -242,21 +242,20 @@ public:
inline int getLongestIssueConflict () const { inline int getLongestIssueConflict () const {
return longestIssueConflict; return longestIssueConflict;
} }
inline int getMinIssueGap (MachineOpCode fromOp, inline int getMinIssueGap (MachineOpCode fromOp,
MachineOpCode toOp) const { MachineOpCode toOp) const {
hash_map<OpCodePair,int>::const_iterator assert(fromOp < (int) issueGaps.size());
I = issueGaps.find(OpCodePair(fromOp, toOp)); const std::vector<int>& toGaps = issueGaps[fromOp];
return (I == issueGaps.end())? 0 : (*I).second; return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
} }
inline const std::vector<MachineOpCode>* inline const std::vector<MachineOpCode>&
getConflictList(MachineOpCode opCode) const { getConflictList(MachineOpCode opCode) const {
hash_map<MachineOpCode, std::vector<MachineOpCode> >::const_iterator assert(opCode < (int) conflictLists.size());
I = conflictLists.find(opCode); return conflictLists[opCode];
return (I == conflictLists.end())? NULL : & (*I).second;
} }
inline bool isSingleIssue (MachineOpCode opCode) const { inline bool isSingleIssue (MachineOpCode opCode) const {
return getInstrRUsage(opCode).isSingleIssue; return getInstrRUsage(opCode).isSingleIssue;
} }
@@ -276,6 +275,13 @@ private:
void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses); void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses); void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
std::vector<int>& toGaps = issueGaps[fromOp];
if (toOp >= (int) toGaps.size())
toGaps.resize(toOp+1);
toGaps[toOp] = gap;
}
protected: protected:
int numSchedClasses; int numSchedClasses;
const MachineInstrInfo* mii; const MachineInstrInfo* mii;
@@ -285,10 +291,10 @@ protected:
unsigned numUsageDeltas; unsigned numUsageDeltas;
unsigned numIssueDeltas; unsigned numIssueDeltas;
std::vector<InstrRUsage> instrRUsages; // indexed by opcode std::vector<InstrRUsage> instrRUsages; // indexed by opcode
hash_map<OpCodePair,int> issueGaps; // indexed by opcode pair std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
hash_map<MachineOpCode, std::vector<MachineOpCode> > std::vector<std::vector<MachineOpCode> >
conflictLists; // indexed by opcode conflictLists; // indexed by [opcode]
}; };
#endif #endif

View File

@@ -151,11 +151,12 @@ MachineSchedInfo::computeIssueGaps(const std::vector<InstrRUsage>&
instrRUForClasses) instrRUForClasses)
{ {
int numOpCodes = mii->getNumRealOpCodes(); int numOpCodes = mii->getNumRealOpCodes();
instrRUsages.resize(numOpCodes); issueGaps.resize(numOpCodes);
conflictLists.resize(numOpCodes);
assert(numOpCodes < (1 << MAX_OPCODE_SIZE) - 1 assert(numOpCodes < (1 << MAX_OPCODE_SIZE) - 1
&& "numOpCodes invalid for implementation of class OpCodePair!"); && "numOpCodes invalid for implementation of class OpCodePair!");
// First, compute issue gaps between pairs of classes based on common // First, compute issue gaps between pairs of classes based on common
// resources usages for each class, because most instruction pairs will // resources usages for each class, because most instruction pairs will
// usually behave the same as their class. // usually behave the same as their class.
@@ -168,27 +169,27 @@ MachineSchedInfo::computeIssueGaps(const std::vector<InstrRUsage>&
instrRUForClasses[toSC]); instrRUForClasses[toSC]);
classPairGaps[fromSC][toSC] = classPairGap; classPairGaps[fromSC][toSC] = classPairGap;
} }
// Now, for each pair of instructions, use the class pair gap if both // Now, for each pair of instructions, use the class pair gap if both
// instructions have identical resource usage as their respective classes. // instructions have identical resource usage as their respective classes.
// If not, recompute the gap for the pair from scratch. // If not, recompute the gap for the pair from scratch.
longestIssueConflict = 0; longestIssueConflict = 0;
for (MachineOpCode fromOp=0; fromOp < numOpCodes; fromOp++) for (MachineOpCode fromOp=0; fromOp < numOpCodes; fromOp++)
for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++) for (MachineOpCode toOp=0; toOp < numOpCodes; toOp++)
{ {
int instrPairGap = int instrPairGap =
(instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass) (instrRUsages[fromOp].sameAsClass && instrRUsages[toOp].sameAsClass)
? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)] ? classPairGaps[getSchedClass(fromOp)][getSchedClass(toOp)]
: ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]); : ComputeMinGap(instrRUsages[fromOp], instrRUsages[toOp]);
if (instrPairGap > 0) if (instrPairGap > 0)
{ {
issueGaps[OpCodePair(fromOp,toOp)] = instrPairGap; this->setGap(instrPairGap, fromOp, toOp);
conflictLists[fromOp].push_back(toOp); conflictLists[fromOp].push_back(toOp);
longestIssueConflict = std::max(longestIssueConflict, instrPairGap); longestIssueConflict=std::max(longestIssueConflict, instrPairGap);
} }
} }
} }