summaryrefslogtreecommitdiff
path: root/tools/llvm-mca/Instruction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-mca/Instruction.cpp')
-rw-r--r--tools/llvm-mca/Instruction.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/tools/llvm-mca/Instruction.cpp b/tools/llvm-mca/Instruction.cpp
index 53f0d67bf77..0c847670557 100644
--- a/tools/llvm-mca/Instruction.cpp
+++ b/tools/llvm-mca/Instruction.cpp
@@ -132,7 +132,22 @@ void Instruction::execute() {
void Instruction::update() {
assert(isDispatched() && "Unexpected instruction stage found!");
- if (llvm::all_of(Uses, [](const UniqueUse &Use) { return Use->isReady(); }))
+
+ if (!llvm::all_of(Uses, [](const UniqueUse &Use) { return Use->isReady(); }))
+ return;
+
+ // A partial register write cannot complete before a dependent write.
+ auto IsDefReady = [&](const UniqueDef &Def) {
+ if (const WriteState *Write = Def->getDependentWrite()) {
+ int WriteLatency = Write->getCyclesLeft();
+ if (WriteLatency == UNKNOWN_CYCLES)
+ return false;
+ return static_cast<unsigned>(WriteLatency) < Desc.MaxLatency;
+ }
+ return true;
+ };
+
+ if (llvm::all_of(Defs, IsDefReady))
Stage = IS_READY;
}
@@ -141,14 +156,10 @@ void Instruction::cycleEvent() {
return;
if (isDispatched()) {
- bool IsReady = true;
- for (UniqueUse &Use : Uses) {
+ for (UniqueUse &Use : Uses)
Use->cycleEvent();
- IsReady &= Use->isReady();
- }
- if (IsReady)
- Stage = IS_READY;
+ update();
return;
}