Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tsygankov Slava 21AMI-2; Lab1; 2nd variant #12

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions clang/lab1/plugin/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never
66 changes: 66 additions & 0 deletions clang/lab1/plugin/AlwaysInlineNoCondition.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "llvm/Passes/PassPlugin.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Attributes.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Passes/PassBuilder.h"

using namespace llvm;

namespace {
class AlwaysInlineNoConditionPass : public PassInfoMixin<AlwaysInlineNoConditionPass> {
public:
PreservedAnalyses run(Function &func, FunctionAnalysisManager &) {
errs() << "Running pass on function: " << func.getName() << "\n";
bool hasCondition = false;

for (BasicBlock &basicBlock : func) {
for (Instruction &inst : basicBlock) {
if (isa<ICmpInst>(&inst) || isa<SelectInst>(&inst)) {
if (auto *branchInst = dyn_cast<ICmpInst>(&inst)) {
errs() << "Found conditional branch in function: " << func.getName() << "\n";
hasCondition = true;
break;
} else if (isa<SelectInst>(&inst)) {
errs() << "Found switch instruction in function: " << func.getName() << "\n";
hasCondition = true;
break;
}
}
}
if (hasCondition) {
break;
}
}

if (!hasCondition) {
func.addFnAttr(Attribute::AlwaysInline);
errs() << "Added always_inline to function: " << func.getName() << "\n";
} else {
errs() << "Did not add always_inline to function: " << func.getName() << " because it has conditions\n";
func.addFnAttr(Attribute::NoInline);
}

return PreservedAnalyses::all();
}
};

}

extern "C" LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo llvmGetPassPluginInfo() {
return {
LLVM_PLUGIN_API_VERSION, "AlwaysInlineNoConditionPass", LLVM_VERSION_STRING,
[](PassBuilder &passBuilder) {
passBuilder.registerPipelineParsingCallback(
[](StringRef name, FunctionPassManager &functionPassManager,
ArrayRef<PassBuilder::PipelineElement>) {
if (name == "always-inline-no-condition") {
functionPassManager.addPass(AlwaysInlineNoConditionPass());
return true;
}
return false;
});
}
};
}
24 changes: 24 additions & 0 deletions clang/lab1/plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.13)
project(AlwaysInlineNoConditionPass)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)

find_package(LLVM REQUIRED CONFIG)
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(AddLLVM)

include_directories(${LLVM_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})

add_definitions(${LLVM_DEFINITIONS})

set(CMAKE_SHARED_MODULE_SUFFIX ".so")

add_llvm_library(AlwaysInlineNoConditionPass MODULE
AlwaysInlineNoCondition.cpp

PLUGIN_TOOL
opt
)
8 changes: 8 additions & 0 deletions clang/lab1/plugin/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ubuntu:latest

RUN apt-get update && apt-get install -y \
build-essential \
cmake \
clang \
llvm \
&& rm -rf /var/lib/apt/lists/* \
7 changes: 7 additions & 0 deletions clang/lab1/plugin/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

mkdir -p build
cd build

cmake ..
make
10 changes: 10 additions & 0 deletions clang/lab1/plugin/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

/usr/bin/clang++ -O1 -S -emit-llvm -o test/test.ll test/test.cpp

/usr/bin/opt -load-pass-plugin ./build/AlwaysInlineNoConditionPass.so -passes=always-inline-no-condition -debug-pass-manager -S test/test.ll -o test/testOpt.ll

echo "Compilation and plugin application completed. Executable created: testOpt.ll"

echo "Run tests...(By default - OK)"
/usr/bin/FileCheck-18 --dump-input=fail test/test.cpp < test/testOpt.ll
59 changes: 59 additions & 0 deletions clang/lab1/plugin/test/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// RUN: %clang_cc1 -emit-llvm -o - %s | opt -load /plugin/build/AlwaysInlineNoConditionPass.so -passes=always-inline-no-condition -S | FileCheck %s


// CHECK:; Function Attrs: alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
// CHECK-NEXT:define dso_local void @_Z10inlineFuncRi(ptr nocapture noundef nonnull align 4 dereferenceable(4) %0) local_unnamed_addr #0 {

void inlineFunc(int &var) {
++var;
}


// CHECK:; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable
// CHECK-NEXT:define dso_local noundef i1 @_Z15notInlineFunc_1i(i32 noundef %0) local_unnamed_addr #1 {

bool notInlineFunc_1(int var) {
if (var == 2 || var == 22) {
return false;
} else {
return true;
}
}


// CHECK:; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable
// CHECK-NEXT:define dso_local noundef i32 @_Z15notInlineFunc_2b(i1 noundef %0) local_unnamed_addr #1 {

int notInlineFunc_2(const bool var) {
int a = var ? 3 : 0;
return a;
}


// CHECK:; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable
// CHECK-NEXT:define dso_local noundef i32 @_Z15notInlineFunc_3i(i32 noundef %0) local_unnamed_addr #1 {

int notInlineFunc_3(int var) {
switch (var) {
case 1:
return true;
default:
return false;
}
}


// CHECK:; Function Attrs: alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
// CHECK-NEXT:define dso_local noundef i32 @main() local_unnamed_addr #2 {

int main() {
int a = 4;
inlineFunc(a);
notInlineFunc_1(12);
notInlineFunc_2(true);
notInlineFunc_3(a);
}

// CHECK:attributes #0 = { alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,-fmv" }
// CHECK-NEXT:attributes #1 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,-fmv" }
// CHECK-NEXT:attributes #2 = { alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,-fmv" }