aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MCA
diff options
context:
space:
mode:
authorMichael Maitland <michaeltmaitland@gmail.com>2024-03-06 07:59:29 -0500
committerGitHub <noreply@github.com>2024-03-06 07:59:29 -0500
commita6ee0adb724a3f1705fc54937e734ffc2a032096 (patch)
tree8b2cae9ba964bd8147ba16736064c884e20f0c43 /llvm/lib/MCA
parentdf267fe32759658bebd846f98fdf5db61312837d (diff)
downloadllvm-a6ee0adb724a3f1705fc54937e734ffc2a032096.zip
llvm-a6ee0adb724a3f1705fc54937e734ffc2a032096.tar.gz
llvm-a6ee0adb724a3f1705fc54937e734ffc2a032096.tar.bz2
[llvm-mca][AMDGPU] Retire instructions that have issue carry over correctly (#83881)
https://github.com/llvm/llvm-project/issues/83775 shows llvm-mca hits sanitizer error in cycleEnd. There was an instruction that takes multiple cycles to issue and is finished executing directly after issue. Prior to this patch, the instruction is retired on the first issue cycle, despite taking multiple cycles to issue. To fix this, if an instruction takes multiple cycles to issue and is done executing after issue, let updateCarriedOver retire the instruction when it is fully issued.
Diffstat (limited to 'llvm/lib/MCA')
-rw-r--r--llvm/lib/MCA/Stages/InOrderIssueStage.cpp36
1 files changed, 26 insertions, 10 deletions
diff --git a/llvm/lib/MCA/Stages/InOrderIssueStage.cpp b/llvm/lib/MCA/Stages/InOrderIssueStage.cpp
index 0f1737dc..8f720db 100644
--- a/llvm/lib/MCA/Stages/InOrderIssueStage.cpp
+++ b/llvm/lib/MCA/Stages/InOrderIssueStage.cpp
@@ -257,13 +257,13 @@ llvm::Error InOrderIssueStage::tryIssue(InstRef &IR) {
}
// If the instruction has a latency of 0, we need to handle
- // the execution and retirement now.
- if (IS.isExecuted()) {
+ // the execution and retirement now. If the instruction is issued in multiple
+ // cycles, we cannot handle the instruction being executed here so we make
+ // updateCarriedOver responsible.
+ if (IS.isExecuted() && !ShouldCarryOver) {
PRF.onInstructionExecuted(&IS);
LSU.onInstructionExecuted(IR);
- notifyEvent<HWInstructionEvent>(
- HWInstructionEvent(HWInstructionEvent::Executed, IR));
- LLVM_DEBUG(dbgs() << "[E] Instruction #" << IR << " is executed\n");
+ notifyInstructionExecuted(IR);
retireInstruction(IR);
return llvm::ErrorSuccess();
@@ -294,12 +294,18 @@ void InOrderIssueStage::updateIssuedInst() {
continue;
}
- PRF.onInstructionExecuted(&IS);
- LSU.onInstructionExecuted(IR);
- notifyInstructionExecuted(IR);
- ++NumExecuted;
+ // If the instruction takes multiple cycles to issue, defer these calls
+ // to updateCarriedOver. We still remove from IssuedInst even if there is
+ // carry over to avoid an extra call to cycleEvent in the next cycle.
+ if (!CarriedOver) {
+ PRF.onInstructionExecuted(&IS);
+ LSU.onInstructionExecuted(IR);
+ notifyInstructionExecuted(IR);
- retireInstruction(*I);
+ retireInstruction(*I);
+ }
+
+ ++NumExecuted;
std::iter_swap(I, E - NumExecuted);
}
@@ -329,6 +335,16 @@ void InOrderIssueStage::updateCarriedOver() {
else
Bandwidth -= CarryOver;
+ // updateIssuedInst defered these calls to updateCarriedOver when there was
+ // a carry over.
+ if (CarriedOver.getInstruction()->isExecuted()) {
+ PRF.onInstructionExecuted(CarriedOver.getInstruction());
+ LSU.onInstructionExecuted(CarriedOver);
+ notifyInstructionExecuted(CarriedOver);
+
+ retireInstruction(CarriedOver);
+ }
+
CarriedOver = InstRef();
CarryOver = 0;
}