This repository was archived by the owner on Jan 19, 2025. It is now read-only.
forked from NN-complr-tech/llvm
-
Notifications
You must be signed in to change notification settings - Fork 57
Mortina Anastasiya Lab3 Var1 #235
Merged
m-ly4
merged 2 commits into
NN-complr-tech:course-spring-2024
from
NastyaMortina:mortina_nastya_lab3
May 31, 2024
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
set(PluginName X86MortinaMulAddPass) | ||
|
||
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp) | ||
add_llvm_pass_plugin(${PluginName} | ||
${ALL_SOURCE_FILES} | ||
DEPENDS | ||
intrinsics_gen | ||
X86 | ||
BUILDTREE_ONLY) | ||
|
||
target_include_directories(${PluginName} PUBLIC ${PATH_TO_X86}) | ||
|
||
set(LLVM_TEST_DEPENDS ${PluginName} ${LLVM_TEST_DEPENDS} PARENT_SCOPE) |
102 changes: 102 additions & 0 deletions
102
llvm/lib/Target/X86/lab3/mortina_nastya/X86MortinaMulAdd.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#include "X86.h" | ||
#include "X86InstrInfo.h" | ||
#include "X86Subtarget.h" | ||
#include "llvm/CodeGen/MachineFunctionPass.h" | ||
#include "llvm/CodeGen/MachineInstrBuilder.h" | ||
#include "llvm/IR/Function.h" | ||
#include "llvm/IR/Instructions.h" | ||
#include "llvm/IR/IntrinsicsX86.h" | ||
#include "llvm/Pass.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace { | ||
class MortinaMulAddPass : public MachineFunctionPass { | ||
public: | ||
static char ID; | ||
MortinaMulAddPass() : MachineFunctionPass(ID) {} | ||
|
||
bool runOnMachineFunction(MachineFunction &MF) override { | ||
SmallVector<MachineInstr *> deletedInstrPtr; | ||
bool Changed = false; | ||
|
||
for (auto &MBB : MF) { | ||
for (auto MI = MBB.begin(); MI != MBB.end(); ++MI) { | ||
if (MI->getOpcode() == X86::MULPDrr) { | ||
Changed = processInstruction(MF, MBB, MI, deletedInstrPtr) || Changed; | ||
} | ||
} | ||
} | ||
|
||
for (auto it : deletedInstrPtr) | ||
it->eraseFromParent(); | ||
|
||
return Changed; | ||
} | ||
|
||
private: | ||
bool processInstruction(MachineFunction &MF, MachineBasicBlock &MBB, | ||
MachineBasicBlock::iterator MI, | ||
SmallVector<MachineInstr *> &deletedInstrPtr) { | ||
Register Reg = MI->getOperand(0).getReg(); | ||
|
||
for (auto NextMI = std::next(MI); NextMI != MBB.end(); ++NextMI) { | ||
if (NextMI->getOpcode() == X86::ADDPDrr && isRegInOperands(NextMI, Reg)) { | ||
if (!hasDependency(NextMI, Reg, MBB)) { | ||
buildNewInstruction(MF, MBB, MI, NextMI, Reg); | ||
deletedInstrPtr.push_back(&*MI); | ||
deletedInstrPtr.push_back(&*NextMI); | ||
return true; | ||
} | ||
break; | ||
} else if (isRegInOperands(NextMI, Reg)) { | ||
break; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool isRegInOperands(MachineBasicBlock::iterator MI, Register Reg) { | ||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { | ||
if (MI->getOperand(i).getReg() == Reg) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
bool hasDependency(MachineBasicBlock::iterator NextMI, Register Reg, | ||
MachineBasicBlock &MBB) { | ||
if (NextMI->getOperand(0).getReg() != Reg) { | ||
for (auto CheckMI = std::next(NextMI); CheckMI != MBB.end(); ++CheckMI) { | ||
if (isRegInOperands(CheckMI, Reg)) { | ||
return true; | ||
} | ||
} | ||
} | ||
if (NextMI->getOperand(1).getReg() == Reg && | ||
NextMI->getOperand(2).getReg() == Reg) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
void buildNewInstruction(MachineFunction &MF, MachineBasicBlock &MBB, | ||
MachineBasicBlock::iterator MI, | ||
MachineBasicBlock::iterator NextMI, Register Reg) { | ||
MachineInstrBuilder BuilderMI = | ||
BuildMI(MBB, MI, MI->getDebugLoc(), | ||
MF.getSubtarget().getInstrInfo()->get(X86::VFMADD213PDr)); | ||
BuilderMI.addReg(NextMI->getOperand(0).getReg(), RegState::Define); | ||
BuilderMI.addReg(MI->getOperand(1).getReg()); | ||
BuilderMI.addReg(MI->getOperand(2).getReg()); | ||
BuilderMI.addReg(NextMI->getOperand(2).getReg()); | ||
} | ||
}; | ||
|
||
char MortinaMulAddPass::ID = 0; | ||
static RegisterPass<MortinaMulAddPass> X("x86-mortina-muladd-pass", | ||
"x86 Mortina Intrinsics Pass"); | ||
} // namespace |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,277 @@ | ||
# RUN: llc -mtriple x86_64-unknown-linux-gnu --load=%llvmshlibdir/X86MortinaMulAddPass%shlibext -run-pass=x86-mortina-muladd-pass %s -o - | FileCheck %s | ||
|
||
# __m128d test1(__m128d x, __m128d y, __m128d z) { | ||
# __m128d res = x * y + z; | ||
# return res; | ||
# } | ||
|
||
# __m128d test2(__m128d x, __m128d y, __m128d z) { | ||
# __m128d tmp = x * z + y; | ||
# return tmp * z + y; | ||
# } | ||
|
||
# __m128d test3(__m128d x, __m128d y, __m128d z) { | ||
# __m128d tmp = x * z; | ||
# tmp = tmp / y; | ||
# return tmp + y; | ||
# } | ||
|
||
# __m128d test4(__m128d x, __m128d y, __m128d z) { | ||
# __m128d tmp = x * y; | ||
# __m128d tmp2 = y + x - z; | ||
# return tmp + z + tmp2; | ||
# } | ||
|
||
# __m128d test5(__m128d x, __m128d y, __m128d z) { | ||
# __m128d tmp = x * y; | ||
# __m128d tmp2 = tmp + z; | ||
# return tmp * z; | ||
# } | ||
|
||
# __m128d test6(__m128d x, __m128d y) { | ||
# __m128d tmp = x * y; | ||
# return tmp + tmp; | ||
# } | ||
|
||
|
||
--- | | ||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" | ||
target triple = "x86_64-unknown-linux-gnu" | ||
|
||
; Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) uwtable | ||
define dso_local noundef <2 x double> @_Z5test1Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #0 { | ||
entry: | ||
%0 = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %x, <2 x double> %y, <2 x double> %z) | ||
ret <2 x double> %0 | ||
} | ||
|
||
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) | ||
declare <2 x double> @llvm.fmuladd.v2f64(<2 x double>, <2 x double>, <2 x double>) #1 | ||
|
||
; Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) uwtable | ||
define dso_local noundef <2 x double> @_Z5test2Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #0 { | ||
entry: | ||
%0 = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %x, <2 x double> %z, <2 x double> %y) | ||
%1 = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %0, <2 x double> %z, <2 x double> %y) | ||
ret <2 x double> %1 | ||
} | ||
|
||
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable | ||
define dso_local noundef <2 x double> @_Z5test3Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #2 { | ||
entry: | ||
%mul = fmul <2 x double> %x, %z | ||
%div = fdiv <2 x double> %mul, %y | ||
%add = fadd <2 x double> %div, %y | ||
ret <2 x double> %add | ||
} | ||
|
||
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable | ||
define dso_local noundef <2 x double> @_Z5test4Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #2 { | ||
entry: | ||
%mul = fmul <2 x double> %x, %y | ||
%add = fadd <2 x double> %x, %y | ||
%sub = fsub <2 x double> %add, %z | ||
%add1 = fadd <2 x double> %mul, %z | ||
%add2 = fadd <2 x double> %add1, %sub | ||
ret <2 x double> %add2 | ||
} | ||
|
||
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable | ||
define dso_local noundef <2 x double> @_Z5test5Dv2_dS_S_(<2 x double> noundef %x, <2 x double> noundef %y, <2 x double> noundef %z) local_unnamed_addr #2 { | ||
entry: | ||
%mul = fmul <2 x double> %x, %y | ||
%mul1 = fmul <2 x double> %mul, %z | ||
ret <2 x double> %mul1 | ||
} | ||
|
||
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable | ||
define dso_local noundef <2 x double> @_Z5test6Dv2_dS_(<2 x double> noundef %x, <2 x double> noundef %y) local_unnamed_addr #2 { | ||
entry: | ||
%mul = fmul <2 x double> %x, %y | ||
%add = fadd <2 x double> %mul, %mul | ||
ret <2 x double> %add | ||
} | ||
|
||
attributes #0 = { mustprogress nofree nosync nounwind willreturn memory(none) uwtable "min-legal-vector-width"="128" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } | ||
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } | ||
attributes #2 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "min-legal-vector-width"="128" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } | ||
|
||
!llvm.module.flags = !{!0, !1, !2, !3} | ||
|
||
!0 = !{i32 1, !"wchar_size", i32 4} | ||
!1 = !{i32 8, !"PIC Level", i32 2} | ||
!2 = !{i32 7, !"PIE Level", i32 2} | ||
!3 = !{i32 7, !"uwtable", i32 2} | ||
|
||
... | ||
--- | ||
name: _Z5test1Dv2_dS_S_ | ||
alignment: 16 | ||
tracksRegLiveness: true | ||
debugInstrRef: true | ||
tracksDebugUserValues: true | ||
liveins: | ||
- { reg: '$xmm0' } | ||
- { reg: '$xmm1' } | ||
- { reg: '$xmm2' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
maxCallFrameSize: 0 | ||
machineFunctionInfo: {} | ||
body: | | ||
bb.0.entry: | ||
liveins: $xmm0, $xmm1, $xmm2 | ||
|
||
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr | ||
RET64 $xmm0 | ||
|
||
; CHECK: $xmm0 = VFMADD213PDr $xmm0, $xmm1, $xmm2, implicit $mxcsr | ||
; CHECK-NEXT: RET64 $xmm0 | ||
|
||
... | ||
--- | ||
name: _Z5test2Dv2_dS_S_ | ||
alignment: 16 | ||
tracksRegLiveness: true | ||
debugInstrRef: true | ||
tracksDebugUserValues: true | ||
liveins: | ||
- { reg: '$xmm0' } | ||
- { reg: '$xmm1' } | ||
- { reg: '$xmm2' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
maxCallFrameSize: 0 | ||
machineFunctionInfo: {} | ||
body: | | ||
bb.0.entry: | ||
liveins: $xmm0, $xmm1, $xmm2 | ||
|
||
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, renamable $xmm2, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, renamable $xmm1, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
RET64 $xmm0 | ||
|
||
; CHECK: $xmm0 = VFMADD213PDr $xmm0, $xmm2, $xmm1, implicit $mxcsr | ||
; CHECK-NEXT: $xmm0 = VFMADD213PDr $xmm0, $xmm2, $xmm1, implicit $mxcsr | ||
; CHECK-NEXT: RET64 $xmm0 | ||
|
||
... | ||
--- | ||
name: _Z5test3Dv2_dS_S_ | ||
alignment: 16 | ||
tracksRegLiveness: true | ||
debugInstrRef: true | ||
tracksDebugUserValues: true | ||
liveins: | ||
- { reg: '$xmm0' } | ||
- { reg: '$xmm1' } | ||
- { reg: '$xmm2' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
maxCallFrameSize: 0 | ||
machineFunctionInfo: {} | ||
body: | | ||
bb.0.entry: | ||
liveins: $xmm0, $xmm1, $xmm2 | ||
|
||
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept DIVPDrr killed renamable $xmm0, renamable $xmm1, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
RET64 $xmm0 | ||
|
||
; CHECK: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr | ||
; CHECK-NEXT: renamable $xmm0 = nofpexcept DIVPDrr killed renamable $xmm0, renamable $xmm1, implicit $mxcsr | ||
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
; CHECK-NEXT: RET64 $xmm0 | ||
|
||
... | ||
--- | ||
name: _Z5test4Dv2_dS_S_ | ||
alignment: 16 | ||
tracksRegLiveness: true | ||
debugInstrRef: true | ||
tracksDebugUserValues: true | ||
liveins: | ||
- { reg: '$xmm0' } | ||
- { reg: '$xmm1' } | ||
- { reg: '$xmm2' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
maxCallFrameSize: 0 | ||
machineFunctionInfo: {} | ||
body: | | ||
bb.0.entry: | ||
liveins: $xmm0, $xmm1, $xmm2 | ||
|
||
$xmm3 = MOVAPDrr $xmm0 | ||
renamable $xmm3 = nofpexcept MULPDrr killed renamable $xmm3, renamable $xmm1, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept SUBPDrr killed renamable $xmm0, renamable $xmm2, implicit $mxcsr | ||
renamable $xmm3 = nofpexcept ADDPDrr killed renamable $xmm3, killed renamable $xmm2, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm3, implicit $mxcsr | ||
RET64 $xmm0 | ||
|
||
; CHECK: $xmm3 = MOVAPDrr $xmm0 | ||
; CHECK-NEXT: $xmm3 = VFMADD213PDr $xmm3, $xmm1, $xmm2, implicit $mxcsr | ||
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
; CHECK-NEXT: renamable $xmm0 = nofpexcept SUBPDrr killed renamable $xmm0, renamable $xmm2, implicit $mxcsr | ||
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, killed renamable $xmm3, implicit $mxcsr | ||
; CHECK-NEXT: RET64 $xmm0 | ||
|
||
... | ||
--- | ||
name: _Z5test5Dv2_dS_S_ | ||
alignment: 16 | ||
tracksRegLiveness: true | ||
debugInstrRef: true | ||
tracksDebugUserValues: true | ||
liveins: | ||
- { reg: '$xmm0' } | ||
- { reg: '$xmm1' } | ||
- { reg: '$xmm2' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
maxCallFrameSize: 0 | ||
machineFunctionInfo: {} | ||
body: | | ||
bb.0.entry: | ||
liveins: $xmm0, $xmm1, $xmm2 | ||
|
||
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr | ||
RET64 $xmm0 | ||
|
||
; CHECK: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
; CHECK-NEXT: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm2, implicit $mxcsr | ||
; CHECK-NEXT: RET64 $xmm0 | ||
|
||
... | ||
--- | ||
name: _Z5test6Dv2_dS_ | ||
alignment: 16 | ||
tracksRegLiveness: true | ||
debugInstrRef: true | ||
tracksDebugUserValues: true | ||
liveins: | ||
- { reg: '$xmm0' } | ||
- { reg: '$xmm1' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
maxCallFrameSize: 0 | ||
machineFunctionInfo: {} | ||
body: | | ||
bb.0.entry: | ||
liveins: $xmm0, $xmm1 | ||
|
||
renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, renamable $xmm0, implicit $mxcsr | ||
RET64 $xmm0 | ||
|
||
; CHECK: renamable $xmm0 = nofpexcept MULPDrr killed renamable $xmm0, killed renamable $xmm1, implicit $mxcsr | ||
; CHECK-NEXT: renamable $xmm0 = nofpexcept ADDPDrr killed renamable $xmm0, renamable $xmm0, implicit $mxcsr | ||
; CHECK-NEXT: RET64 $xmm0 | ||
|
||
... |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.