1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[llvm-mca] LSUnit: use a SmallSet to model load/store queues. NFCI

Also, try to minimize the number of queries to the memory queues to speedup the
analysis.

On average, this change gives a small 2% speedup. For memcpy-like kernels, the
speedup is up to 5.5%.

llvm-svn: 347469
This commit is contained in:
Andrea Di Biagio 2018-11-22 15:47:44 +00:00
parent 68ff6bfb10
commit ab66dcd995
2 changed files with 32 additions and 25 deletions

View File

@ -17,7 +17,7 @@
#define LLVM_TOOLS_LLVM_MCA_LSUNIT_H
#include "HardwareUnits/HardwareUnit.h"
#include <set>
#include "llvm/ADT/SmallSet.h"
namespace llvm {
namespace mca {
@ -99,8 +99,8 @@ class LSUnit : public HardwareUnit {
// If true, loads will never alias with stores. This is the default.
bool NoAlias;
std::set<unsigned> LoadQueue;
std::set<unsigned> StoreQueue;
SmallSet<unsigned, 16> LoadQueue;
SmallSet<unsigned, 16> StoreQueue;
void assignLQSlot(unsigned Index);
void assignSQSlot(unsigned Index);
@ -109,12 +109,12 @@ class LSUnit : public HardwareUnit {
// An instruction that both 'mayStore' and 'HasUnmodeledSideEffects' is
// conservatively treated as a store barrier. It forces older store to be
// executed before newer stores are issued.
std::set<unsigned> StoreBarriers;
SmallSet<unsigned, 8> StoreBarriers;
// An instruction that both 'MayLoad' and 'HasUnmodeledSideEffects' is
// conservatively treated as a load barrier. It forces older loads to execute
// before newer loads are issued.
std::set<unsigned> LoadBarriers;
SmallSet<unsigned, 8> LoadBarriers;
bool isSQEmpty() const { return StoreQueue.empty(); }
bool isLQEmpty() const { return LoadQueue.empty(); }

View File

@ -136,31 +136,38 @@ bool LSUnit::isReady(const InstRef &IR) const {
}
void LSUnit::onInstructionExecuted(const InstRef &IR) {
const InstrDesc &Desc = IR.getInstruction()->getDesc();
const unsigned Index = IR.getSourceIndex();
std::set<unsigned>::iterator it = LoadQueue.find(Index);
if (it != LoadQueue.end()) {
LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the load queue.\n");
LoadQueue.erase(it);
bool IsALoad = Desc.MayLoad;
bool IsAStore = Desc.MayStore;
if (IsALoad) {
if (LoadQueue.erase(Index)) {
LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the load queue.\n");
}
if (!LoadBarriers.empty() && Index == *LoadBarriers.begin()) {
LLVM_DEBUG(
dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the set of load barriers.\n");
LoadBarriers.erase(Index);
}
}
it = StoreQueue.find(Index);
if (it != StoreQueue.end()) {
LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the store queue.\n");
StoreQueue.erase(it);
}
if (IsAStore) {
if (StoreQueue.erase(Index)) {
LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the store queue.\n");
}
if (!StoreBarriers.empty() && Index == *StoreBarriers.begin()) {
LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the set of store barriers.\n");
StoreBarriers.erase(StoreBarriers.begin());
}
if (!LoadBarriers.empty() && Index == *LoadBarriers.begin()) {
LLVM_DEBUG(dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the set of load barriers.\n");
LoadBarriers.erase(LoadBarriers.begin());
if (!StoreBarriers.empty() && Index == *StoreBarriers.begin()) {
LLVM_DEBUG(
dbgs() << "[LSUnit]: Instruction idx=" << Index
<< " has been removed from the set of store barriers.\n");
StoreBarriers.erase(Index);
}
}
}
} // namespace mca
} // namespace llvm