-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8dcdfea
Showing
12 changed files
with
1,120 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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,5 @@ | ||
# LLVM Course | ||
|
||
- `LLVM-passes`: suite of examples of llvm analyses and | ||
transformations to guide help newcomers write their own | ||
passes. |
This file contains 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,6 @@ | ||
BasedOnStyle: LLVM | ||
IndentWidth: 4 | ||
AllowShortIfStatementsOnASingleLine: true | ||
AllowShortFunctionsOnASingleLine: true | ||
AllowShortLambdasOnASingleLine: true | ||
AllowShortLoopsOnASingleLine: true |
This file contains 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,10 @@ | ||
compile_commands.json | ||
cmake_install.cmake | ||
CMakeCache.txt | ||
CMakeFiles/ | ||
|
||
.clangd | ||
.ninja_deps | ||
.ninja_log | ||
|
||
build/ |
This file contains 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,92 @@ | ||
#=============================================================================== | ||
# See: https://github.com/banach-space/llvm-tutor/blob/master/CMakeLists.txt | ||
#=============================================================================== | ||
cmake_minimum_required(VERSION 3.13.4) | ||
project(addconst) | ||
|
||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | ||
|
||
#=============================================================================== | ||
# 1. VERIFY LLVM INSTALLATION DIR | ||
#=============================================================================== | ||
# Set this to a valid LLVM installation dir: | ||
set(LLVM_INSTALL_DIR "" CACHE PATH "LLVM installation directory") | ||
|
||
# A bit of a sanity checking: | ||
set(LLVM_INSTALL_INCLUDE "${LLVM_INSTALL_DIR}/include/llvm") | ||
if(NOT EXISTS "${LLVM_INSTALL_INCLUDE}") | ||
message(FATAL_ERROR | ||
" LLVM_INSTALL_INCLUDE (${LLVM_INSTALL_INCLUDE}) is invalid.") | ||
endif() | ||
|
||
set(LLVM_INSTALL_CMAKE "${LLVM_INSTALL_DIR}/lib/cmake/llvm/LLVMConfig.cmake") | ||
if(NOT EXISTS "${LLVM_INSTALL_CMAKE}") | ||
message(FATAL_ERROR | ||
" LLVM_INSTALL_CMAKE (${LLVM_INSTALL_CMAKE}) is invalid.") | ||
endif() | ||
|
||
#=============================================================================== | ||
# 2. LOAD LLVM CONFIGURATION | ||
# For more: http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project | ||
#=============================================================================== | ||
# Add the location of LLVMConfig.cmake to CMake search paths (so that | ||
# find_package can locate it): | ||
list(APPEND CMAKE_PREFIX_PATH "${LLVM_INSTALL_DIR}/lib/cmake/llvm/") | ||
|
||
find_package(LLVM REQUIRED CONFIG) | ||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") | ||
message(STATUS "Using LLVMConfig.cmake in: ${LT_LLVM_INSTALL_DIR}") | ||
|
||
message("LLVM STATUS: | ||
Definitions ${LLVM_DEFINITIONS} | ||
Includes ${LLVM_INCLUDE_DIRS} | ||
Libraries ${LLVM_LIBRARY_DIRS} | ||
Targets ${LLVM_TARGETS_TO_BUILD}" | ||
) | ||
|
||
# Set the LLVM header and library paths | ||
include_directories(${LLVM_INCLUDE_DIRS}) | ||
link_directories(${LLVM_LIBRARY_DIRS}) | ||
add_definitions(${LLVM_DEFINITIONS}) | ||
|
||
#=============================================================================== | ||
# 3. BUILD CONFIGURATION | ||
#=============================================================================== | ||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "") | ||
|
||
# Build type | ||
if (NOT CMAKE_BUILD_TYPE) | ||
set(CMAKE_BUILD_TYPE Debug CACHE | ||
STRING "Build type (default Debug):" FORCE) | ||
endif() | ||
|
||
# Compiler flags | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall\ | ||
-fdiagnostics-color=always") | ||
|
||
# LLVM is normally built without RTTI. Be consistent with that. | ||
if(NOT LLVM_ENABLE_RTTI) | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") | ||
endif() | ||
|
||
# -fvisibility-inlines-hidden is set when building LLVM and on | ||
# Darwin warnings are triggered if the project is built without | ||
# this flag (though otherwise it builds fine). For consistency, | ||
# add it here too. | ||
include(CheckCXXCompilerFlag) | ||
check_cxx_compiler_flag("-fvisibility-inlines-hidden" SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG) | ||
if (${SUPPORTS_FVISIBILITY_INLINES_HIDDEN_FLAG} EQUAL "1") | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") | ||
endif() | ||
|
||
# Set the build directories | ||
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") | ||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") | ||
|
||
#=============================================================================== | ||
# 4. ADD SUB-TARGETS | ||
# Doing this at the end so that all definitions and link/include paths are | ||
# available for the sub-projects. | ||
#=============================================================================== | ||
# add_subdirectory(tool) | ||
add_subdirectory(lib) |
This file contains 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,52 @@ | ||
# LLVM Passes | ||
|
||
## Description | ||
TODO | ||
|
||
## Requirements | ||
TODO | ||
|
||
## Build | ||
First, let us define a set of path variables: | ||
|
||
```bash | ||
$ LLVM_INSTALL_DIR=</path/to/llvm/> | ||
$ LLVM_OPT=</path/to/opt> | ||
``` | ||
|
||
For instance, if you built LLVM from source the commands above | ||
will be like: | ||
|
||
```bash | ||
$ LLVM_INSTALL_DIR=/path/to/llvm-project/build | ||
$ LLVM_OPT=$LLVM_INSTALL_DIR/bin/opt | ||
``` | ||
|
||
Then, run CMake to prepare the build files. We will use the | ||
folder `build` for that. You can use any build tool that you | ||
want, e.g. ninja or make. In this example, we are using Ninja. | ||
|
||
```bash | ||
$ cmake -DLLVM_INSTALL_DIR=$LLVM_INSTALL_DIR -G "Ninja" -B build/ . | ||
``` | ||
|
||
Next, move to the build folder and build the project: | ||
|
||
```bash | ||
$ cd build | ||
$ cmake --build . | ||
``` | ||
|
||
## Run | ||
After building the project, the shared library will be at | ||
`build/lib`. There is an example of a code written in LLVM IR at | ||
`examples/foo.ll`. Let us first run the analysis printer on it: | ||
|
||
```bash | ||
$ $LLVM_OPT -load-pass-plugin build/lib/libAddConst.so \ | ||
$ -passes="print<add-const>" -disable-output examples/foo.ll | ||
``` | ||
|
||
TODO: | ||
- Run the transformation pass | ||
- Run the tool |
This file contains 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,11 @@ | ||
; ModuleID = 'llvm-ir/foo.ll' | ||
source_filename = "llvm-ir/foo.ll" | ||
|
||
define i32 @foo(i32 %a, i32 %b) { | ||
%c = add i32 1, 2 | ||
%d = add i32 3, 4 | ||
%e = add i32 %a, %b | ||
%f = add i32 %c, %d | ||
%g = add i32 %e, %f | ||
ret i32 %g | ||
} |
This file contains 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,82 @@ | ||
//===-- AddConst.h ----------------------------------------------*- C++ -*-===// | ||
// Copyright (C) 2020 Luigi D. C. Soares, Augusto Dias Noronha | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// This file contains the declaration of the analysis used to collect all add | ||
/// instructions within a function. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef ADD_CONST_H | ||
#define ADD_CONST_H | ||
|
||
#include "llvm/IR/InstrTypes.h" | ||
#include <llvm/IR/PassManager.h> | ||
|
||
namespace addconst { | ||
/// An analysis that traverses a function and collects all the "add" | ||
/// instructions with constant operands. | ||
struct AddConstAnalysis : public llvm::AnalysisInfoMixin<AddConstAnalysis> { | ||
/// Result of the analysis: a list of instructions of type | ||
/// "BinaryOperator", opcode "add" and constant operands. | ||
using Result = llvm::SmallVector<llvm::BinaryOperator *, 0>; | ||
/// Traverses the function \p F, collecting all the "add" instructions | ||
/// inside it. | ||
/// | ||
/// \returns a list of all the collected "add" instructions. | ||
Result run(llvm::Function &F, llvm::FunctionAnalysisManager &FAM); | ||
// A special type used by analysis passes to provide an address that | ||
// identifies that particular analysis pass type. | ||
static llvm::AnalysisKey Key; | ||
}; | ||
|
||
/// Takes an instruction and checks whether its operands are constant or not. | ||
/// | ||
/// \returns true if all operands are constant; otherwise, returns false. | ||
bool isConstantIntOnly(llvm::Instruction &I); | ||
|
||
/// A wrapper around AddAnalysis to be used with "opt -passes=" to print the | ||
/// collected add instructions. | ||
struct AddConstPrinterPass : public llvm::PassInfoMixin<AddConstPrinterPass> { | ||
/// Takes a ostream \p OS and constructs an instance of the | ||
// AddPrinterClass. | ||
explicit AddConstPrinterPass(llvm::raw_ostream &OS) : OS(OS) {} | ||
/// Run the AddAnalysis on function \p F and prints its result. | ||
/// | ||
/// \returns llvm::PreservedAnalyses::all(), since nothing changed. | ||
llvm::PreservedAnalyses run(llvm::Function &F, | ||
llvm::FunctionAnalysisManager &FAM); | ||
|
||
private: | ||
llvm::raw_ostream &OS; | ||
}; | ||
|
||
/// A transformation pass that evaluates all constant-only add instructions | ||
/// and replaces their uses by the computed constant. | ||
struct AddConstPass : public llvm::PassInfoMixin<AddConstPass> { | ||
/// Gets the result of AddConstAnalysis for the function \p F and uses it | ||
/// to replace the uses of the collected add instructions by their final | ||
/// value. | ||
/// | ||
/// \returns set of preserved analyses (all of them, except for | ||
/// AddConstAnalysis). | ||
llvm::PreservedAnalyses run(llvm::Function &F, | ||
llvm::FunctionAnalysisManager &FAM); | ||
}; | ||
} // namespace addconst | ||
|
||
#endif |
This file contains 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,71 @@ | ||
//===-- AddConstAnalysis.cpp ----------------------------------------------===// | ||
// Copyright (C) 2020 Luigi D. C. Soares, Augusto Dias Noronha | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// This file contains the implementation of the AddConstAnalysis pass as well | ||
/// as the AddConstPrinterPass. | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "AddConst.h" | ||
#include "llvm/IR/Constants.h" | ||
#include "llvm/IR/InstrTypes.h" | ||
#include "llvm/Support/Casting.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace addconst { | ||
// Initialize the analysis key. | ||
AnalysisKey AddConstAnalysis::Key; | ||
|
||
AddConstAnalysis::Result AddConstAnalysis::run(Function &F, | ||
FunctionAnalysisManager &FAM) { | ||
SmallVector<BinaryOperator *, 0> AddInsts; | ||
for (BasicBlock &BB : F) { | ||
for (Instruction &I : BB) { | ||
// First, check if "I" is an instance of BinaryOperator: | ||
if (!I.isBinaryOp()) continue; | ||
// If it is, check if its opcode is "Add": | ||
if (!(I.getOpcode() == Instruction::BinaryOps::Add)) continue; | ||
// Check if all operands are constant integer: | ||
if (!isConstantIntOnly(I)) continue; | ||
// If it is "Add", append it to the result vector: | ||
AddInsts.push_back(&cast<BinaryOperator>(I)); | ||
} | ||
} | ||
return AddInsts; | ||
} | ||
|
||
bool isConstantIntOnly(Instruction &I) { | ||
for (Use &Op : I.operands()) { | ||
// Check if the operand is a constant integer: | ||
if (!isa<ConstantInt>(Op)) return false; | ||
} | ||
// Return true if all operands are constant integer. | ||
return true; | ||
} | ||
|
||
PreservedAnalyses AddConstPrinterPass::run(Function &F, | ||
FunctionAnalysisManager &FAM) { | ||
auto &AddInsts = FAM.getResult<AddConstAnalysis>(F); | ||
OS << "=============================================\n"; | ||
OS << "|| " << F.getName() << " ||\n"; | ||
OS << "=============================================\n"; | ||
for (auto &Add : AddInsts) OS << *Add << "\n"; | ||
OS << "=============================================\n"; | ||
return PreservedAnalyses::all(); | ||
} | ||
} // namespace addconst |
This file contains 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,39 @@ | ||
//===-- AddConstPass.cpp --------------------------------------------------===// | ||
// Copyright (C) 2020 Luigi D. C. Soares, Augusto Dias Noronha | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// This file contains the implementation of the AddConstPass, which uses | ||
/// AddConstAnalysis to get all the constant-only add instructions and replace | ||
/// their uses by their final values. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "AddConst.h" | ||
#include "llvm/IR/Function.h" | ||
#include "llvm/IR/PassManager.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace addconst { | ||
PreservedAnalyses AddConstPass::run(Function &F, FunctionAnalysisManager &FAM) { | ||
auto &AddInsts = FAM.getResult<AddConstAnalysis>(F); | ||
// TODO: Evaluate constants and replace uses... | ||
auto PA = PreservedAnalyses::all(); | ||
PA.abandon<AddConstAnalysis>(); | ||
return PA; | ||
} | ||
} // namespace addconst |
Oops, something went wrong.