Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

Commit cad1311

Browse files
authored
Kostin Artem. Lab #3. Var 1. (#119)
An optimization pass that replaces multiplication and addition operation with muladd instruction.
1 parent 0a861b8 commit cad1311

File tree

3 files changed

+787
-0
lines changed

3 files changed

+787
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
set(PluginName X86KostinPass)
2+
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h)
3+
add_llvm_pass_plugin(${PluginName}
4+
${ALL_SOURCE_FILES}
5+
DEPENDS
6+
intrinsics_gen
7+
X86
8+
BUILDTREE_ONLY)
9+
10+
target_include_directories(${PluginName} PUBLIC ${PATH_TO_X86})
11+
12+
set(LLVM_TEST_DEPENDS ${PluginName} ${LLVM_TEST_DEPENDS} PARENT_SCOPE)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include "X86.h"
2+
#include "X86InstrInfo.h"
3+
#include "X86Subtarget.h"
4+
#include "llvm/CodeGen/MachineFunctionPass.h"
5+
#include "llvm/CodeGen/MachineInstrBuilder.h"
6+
#include <utility>
7+
#include <vector>
8+
9+
using namespace llvm;
10+
11+
namespace {
12+
class X86KostinPass : public MachineFunctionPass {
13+
public:
14+
static char ID;
15+
X86KostinPass() : MachineFunctionPass(ID) {}
16+
bool runOnMachineFunction(MachineFunction &MF) override;
17+
};
18+
19+
char X86KostinPass::ID = 0;
20+
21+
bool X86KostinPass::runOnMachineFunction(MachineFunction &pFunction) {
22+
const TargetInstrInfo *instrInfo = pFunction.getSubtarget().getInstrInfo();
23+
bool isModified = false;
24+
bool isOp = false;
25+
std::vector<std::pair<MachineInstr *, MachineInstr *>> toDelete;
26+
27+
for (auto &basicBlock : pFunction) {
28+
MachineInstr *mulInstruction = nullptr;
29+
MachineInstr *addInstruction = nullptr;
30+
isOp = false;
31+
32+
for (auto &instr : basicBlock) {
33+
if (instr.getOpcode() == X86::MULPDrr) {
34+
mulInstruction = &instr;
35+
36+
for (auto next = std::next(instr.getIterator());
37+
next != basicBlock.end(); ++next) {
38+
if (next->getOpcode() == X86::ADDPDrr) {
39+
addInstruction = &*next;
40+
if (mulInstruction->getOperand(0).getReg() ==
41+
addInstruction->getOperand(2).getReg() ||
42+
mulInstruction->getOperand(0).getReg() ==
43+
addInstruction->getOperand(1).getReg()) {
44+
toDelete.emplace_back(mulInstruction, addInstruction);
45+
isModified = true;
46+
if (mulInstruction->getOperand(0).getReg() ==
47+
addInstruction->getOperand(2).getReg()) {
48+
isOp = true;
49+
} else {
50+
isOp = false;
51+
}
52+
break;
53+
}
54+
} else if (next->definesRegister(
55+
mulInstruction->getOperand(0).getReg())) {
56+
break;
57+
}
58+
}
59+
}
60+
}
61+
}
62+
63+
for (const auto &[mulInstr, addInstr] : toDelete) {
64+
MachineInstrBuilder builder =
65+
BuildMI(*mulInstr->getParent(), *mulInstr, mulInstr->getDebugLoc(),
66+
instrInfo->get(X86::VFMADD213PDZ128r));
67+
builder.addReg(addInstr->getOperand(0).getReg(), RegState::Define);
68+
builder.addReg(mulInstr->getOperand(1).getReg());
69+
builder.addReg(mulInstr->getOperand(2).getReg());
70+
if (isOp) {
71+
builder.addReg(addInstr->getOperand(1).getReg());
72+
} else {
73+
builder.addReg(addInstr->getOperand(2).getReg());
74+
}
75+
mulInstr->eraseFromParent();
76+
addInstr->eraseFromParent();
77+
}
78+
79+
return isModified;
80+
}
81+
} // namespace
82+
83+
static RegisterPass<X86KostinPass> X("x86-kostin-pass", "X86 Kostin Pass",
84+
false, false);

0 commit comments

Comments
 (0)