[llvm] [Exegesis] Implemented strategy for load operation (PR #113458)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 28 03:56:35 PDT 2024
https://github.com/AnastasiyaChernikova updated https://github.com/llvm/llvm-project/pull/113458
>From 52cad46579cfa7ce79d7c1b1ef6050a99983a60c Mon Sep 17 00:00:00 2001
From: Anastasiya Chernikova <anastasiya.chernikova at syntacore.com>
Date: Wed, 23 Oct 2024 16:14:28 +0300
Subject: [PATCH] [Exegesis] Implemented strategy for load operation
This fix helps to map operand memory to destination registers.
If instruction is load, we can self-alias it in case when instruction
overrides whole address register. For that we use provided scratch memory.
---
llvm/tools/llvm-exegesis/lib/CodeTemplate.h | 3 ++
.../lib/SerialSnippetGenerator.cpp | 46 ++++++++++++++++++-
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/llvm/tools/llvm-exegesis/lib/CodeTemplate.h b/llvm/tools/llvm-exegesis/lib/CodeTemplate.h
index 7aca224302a1ff..8c32c8d26fc548 100644
--- a/llvm/tools/llvm-exegesis/lib/CodeTemplate.h
+++ b/llvm/tools/llvm-exegesis/lib/CodeTemplate.h
@@ -132,6 +132,9 @@ struct CodeTemplate {
// If the template uses the provided scratch memory, the register in which
// the pointer to this memory is passed in to the function.
unsigned ScratchSpacePointerInReg = 0;
+ // Require to pre-store value of a given register (fisrt)
+ // to scratch memory with given offset (second)
+ SmallVector<std::pair<unsigned, unsigned>, 2> PreinitScratchMemory;
#if defined(__GNUC__) && (defined(__clang__) || LLVM_GNUC_PREREQ(8, 0, 0))
// FIXME: GCC7 bug workaround. Drop #if after GCC7 no longer supported.
diff --git a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
index 7100b51bbb7298..ac4881f298618d 100644
--- a/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp
@@ -113,7 +113,51 @@ static void appendCodeTemplates(const LLVMState &State,
}
case ExecutionMode::SERIAL_VIA_MEMORY_INSTR: {
// Select back-to-back memory instruction.
- // TODO: Implement me.
+
+ auto &I = Variant.getInstr();
+ if (I.Description.mayLoad()) {
+ // If instruction is load, we can self-alias it in case when instruction
+ // overrides whole address register. For that we use provided scratch
+ // memory.
+
+ // TODO: now it is not checked if load writes the whole register.
+
+ auto DefOpIt = find_if(I.Operands, [](Operand const &op) {
+ return op.isDef() && op.isReg();
+ });
+
+ if (DefOpIt == I.Operands.end())
+ return;
+
+ const Operand &DefOp = *DefOpIt;
+ auto &ET = State.getExegesisTarget();
+ auto ScratchMemoryRegister = ET.getScratchMemoryRegister(
+ State.getTargetMachine().getTargetTriple());
+ auto &RegClass =
+ State.getTargetMachine().getMCRegisterInfo()->getRegClass(
+ DefOp.getExplicitOperandInfo().RegClass);
+
+ // Register classes of def operand and memory operand must be the same
+ // to perform aliasing.
+ if (!RegClass.contains(ScratchMemoryRegister))
+ return;
+
+ ET.fillMemoryOperands(Variant, ScratchMemoryRegister, 0);
+ Variant.getValueFor(DefOp) = MCOperand::createReg(ScratchMemoryRegister);
+
+ CodeTemplate CT;
+ CT.Execution = ExecutionModeBit;
+ if (CT.ScratchSpacePointerInReg == 0)
+ CT.ScratchSpacePointerInReg = ScratchMemoryRegister;
+
+ CT.Info = std::string(ExecutionClassDescription);
+ CT.Instructions.push_back(std::move(Variant));
+ CT.PreinitScratchMemory.emplace_back(ScratchMemoryRegister,
+ /* Offset */ 0);
+ CodeTemplates.push_back(std::move(CT));
+ }
+
+ // TODO: implement more cases
return;
}
case ExecutionMode::SERIAL_VIA_EXPLICIT_REGS: {
More information about the llvm-commits
mailing list