├── lib ├── CMakeLists.txt ├── CodeMorphing │ ├── CMakeLists.txt │ ├── Makefile │ ├── InstructionAlternativeUtils.cpp │ ├── InstructionAlternatives.cpp │ ├── DeclareRandomizeFunction.cpp │ ├── AlternativesNumberVector.cpp │ └── CodeMorphing.cpp └── Makefile ├── tools ├── CMakeLists.txt ├── cmp │ ├── CMakeLists.txt │ ├── Makefile │ └── ForceLinking.cpp └── Makefile ├── .gitignore ├── test ├── cmp │ ├── dg.exp │ └── xor.ll ├── Makefile.tests ├── site.exp.in ├── lit.site.cfg.in ├── Makefile └── lit.cfg ├── Makefile.common ├── include ├── generated │ └── README.org └── cmp │ ├── InstructionAlternatives.h │ ├── AlternativesNumberVector.h │ ├── DeclareRandomizeFunction.h │ ├── CodeMorphing.h │ ├── AllPasses.h │ └── InstructionAlternativeUtils.h ├── Makefile ├── Makefile.config.in ├── Makefile.config ├── CMakeLists.txt ├── autoconf ├── AutoRegen.sh └── configure.ac └── README.org /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(CodeMorphing) 2 | -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(cmp) 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /autoconf/aclocal.m4 2 | /autoconf/autom4te.cache/ 3 | /autoconf/configure.bak 4 | /configure 5 | -------------------------------------------------------------------------------- /test/cmp/dg.exp: -------------------------------------------------------------------------------- 1 | load_lib llvm.exp 2 | 3 | RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] 4 | -------------------------------------------------------------------------------- /tools/cmp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(CMPasses SHARED ForceLinking.cpp) 2 | target_link_libraries(CMPasses CodeMorphing ${llvm_libs}) 3 | -------------------------------------------------------------------------------- /test/Makefile.tests: -------------------------------------------------------------------------------- 1 | ##===- test/Makefile.tests ---------------------------------*- Makefile -*-===## 2 | 3 | include $(LLVM_SRC_ROOT)/test/Makefile.tests 4 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | 2 | # Include project configurations. 3 | include $(LEVEL)/Makefile.config 4 | 5 | # Include LLVM's Master Makefile. 6 | include $(LLVM_SRC_ROOT)/Makefile.common 7 | -------------------------------------------------------------------------------- /lib/CodeMorphing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(CodeMorphing SHARED 2 | AlternativesNumberVector.cpp 3 | CodeMorphing.cpp 4 | DeclareRandomizeFunction.cpp 5 | InstructionAlternatives.cpp 6 | InstructionAlternativeUtils.cpp 7 | ) 8 | -------------------------------------------------------------------------------- /include/generated/README.org: -------------------------------------------------------------------------------- 1 | 2 | * What is this? 3 | 4 | This directory is meant to contain heards generated with 5 | morph-pass-generator. 6 | 7 | Everything is explained in the top README.org, please refer to that to 8 | find out how to do it. 9 | -------------------------------------------------------------------------------- /tools/cmp/Makefile: -------------------------------------------------------------------------------- 1 | ##===- tools/COTPasses/Makefile ----------------------------*- Makefile -*-===## 2 | 3 | LEVEL = ../.. 4 | 5 | LIBRARYNAME = CMPasses 6 | 7 | LOADABLE_MODULE = 1 8 | 9 | USEDLIBS = CodeMorphing.a 10 | 11 | include $(LEVEL)/Makefile.common 12 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | ##===- tools/Makefile --------------------------------------*- Makefile -*-===## 2 | 3 | # 4 | # Relative path to the top of the source tree. 5 | # 6 | LEVEL = .. 7 | 8 | # 9 | # List all of the subdirectories that we will compile. 10 | # 11 | DIRS = cmp 12 | 13 | include $(LEVEL)/Makefile.common 14 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | ##===- lib/Makefile ----------------------------------------*- Makefile -*-===## 2 | 3 | # 4 | # Relative path to the top of the source tree. 5 | # 6 | LEVEL = .. 7 | 8 | # 9 | # List all of the subdirectories that we will compile. 10 | # 11 | DIRS = CodeMorphing 12 | 13 | include $(LEVEL)/Makefile.common 14 | -------------------------------------------------------------------------------- /lib/CodeMorphing/Makefile: -------------------------------------------------------------------------------- 1 | ##===- lib/CodeMorphing/Makefile ---------------------------*- Makefile -*-===## 2 | 3 | # 4 | # Indicate where we are relative to the top of the source tree. 5 | # 6 | LEVEL = ../.. 7 | 8 | # 9 | # Give the name of a library. This will build a dynamic version. 10 | # 11 | LIBRARYNAME = CodeMorphing 12 | 13 | # 14 | # Include Makefile.common so we know what to do. 15 | # 16 | include $(LEVEL)/Makefile.common 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ##===- Makefile --------------------------------------------*- Makefile -*-===## 2 | # 3 | # Main Makefile. 4 | # 5 | ##===----------------------------------------------------------------------===## 6 | 7 | # 8 | # Indicates our relative path to the top of the project's root directory. 9 | # 10 | LEVEL = . 11 | DIRS = lib tools 12 | EXTRA_DIST = include test 13 | 14 | # 15 | # Include the Master Makefile that knows how to build all. 16 | # 17 | include $(LEVEL)/Makefile.common 18 | -------------------------------------------------------------------------------- /test/site.exp.in: -------------------------------------------------------------------------------- 1 | set target_triplet "@TARGET_TRIPLE@" 2 | set TARGETS_TO_BUILD "@TARGETS_TO_BUILD@" 3 | set llvmtoolsdir "@LLVM_TOOLS_DIR@" 4 | set projlibsdir "@LLVM_LIBS_DIR@" 5 | set projshlibdir "@SHLIBDIR@" 6 | set compile_c "@TEST_COMPILE_C_CMD@" 7 | set compile_cxx "@TEST_COMPILE_CXX_CMD@" 8 | set link "@TEST_LINK_CMD@" 9 | set llvmgcc "@LLVMGCC@" 10 | set llvmgxx "@LLVMGXX@" 11 | set bugpoint_topts "@BUGPOINT_TOPTS@" 12 | set shlibext "@SHLIBEXT@" 13 | set valgrind "@VALGRIND@" 14 | set grep "@GREP@" 15 | set gas "@AS@" 16 | set llvmdsymutil "@DSYMUTIL@" 17 | set emitir "@LLVMCC_EMITIR_FLAG@" 18 | -------------------------------------------------------------------------------- /Makefile.config.in: -------------------------------------------------------------------------------- 1 | # Project name. 2 | PROJECT_NAME := hello-llvm 3 | PROJ_VERSION := 0.1 4 | 5 | # Set this variable to the top of the LLVM source tree. 6 | LLVM_SRC_ROOT = @LLVM_SRC@ 7 | 8 | # Set this variable to the top level directory where LLVM was built. 9 | # (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config). 10 | LLVM_OBJ_ROOT = @LLVM_OBJ@ 11 | 12 | # Set the directory root of this project's source files. 13 | PROJ_SRC_ROOT := $(subst //,/,@abs_top_srcdir@) 14 | 15 | # Set the root directory of this project's object files. 16 | PROJ_OBJ_ROOT := $(subst //,/,@abs_top_objdir@) 17 | 18 | # Set the root directory of this project's install prefix. 19 | PROJ_INSTALL_ROOT := @prefix@ 20 | -------------------------------------------------------------------------------- /Makefile.config: -------------------------------------------------------------------------------- 1 | # Project name. 2 | PROJECT_NAME := hello-llvm 3 | PROJ_VERSION := 0.1 4 | 5 | # Set this variable to the top of the LLVM source tree. 6 | LLVM_SRC_ROOT = /home/mminutoli/projects/llvm/src 7 | 8 | # Set this variable to the top level directory where LLVM was built. 9 | # (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config). 10 | LLVM_OBJ_ROOT = /home/mminutoli/projects/llvm/src 11 | 12 | # Set the directory root of this project's source files. 13 | PROJ_SRC_ROOT := $(subst //,/,/home/mminutoli/projects/llvm/src/projects/code-morphing) 14 | 15 | # Set the root directory of this project's object files. 16 | PROJ_OBJ_ROOT := $(subst //,/,@abs_top_objdir@) 17 | 18 | # Set the root directory of this project's install prefix. 19 | PROJ_INSTALL_ROOT := /usr/local 20 | -------------------------------------------------------------------------------- /test/lit.site.cfg.in: -------------------------------------------------------------------------------- 1 | 2 | config.proj_obj_root = "@PROJ_BINARY_DIR@" 3 | 4 | config.llvm_src_root = "@LLVM_SOURCE_DIR@" 5 | config.llvm_obj_root = "@LLVM_BINARY_DIR@" 6 | 7 | config.python_executable = "@PYTHON_EXECUTABLE@" 8 | 9 | config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" 10 | config.llvmgcc_dir = "@LLVMGCCDIR@" 11 | 12 | config.enable_shared = @ENABLE_SHARED@ 13 | config.enable_assertions = @ENABLE_ASSERTIONS@ 14 | 15 | # Support substitution of the tools_dir with user parameters. This is 16 | # used when we can't determine the tool dir at configuration time. 17 | try: 18 | config.llvm_tools_dir = config.llvm_tools_dir % lit.params 19 | except KeyError,e: 20 | key, = e.args 21 | lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) 22 | 23 | # Let the main config do the real work. 24 | lit.load_config(config, "@PROJ_SOURCE_DIR@/test/lit.cfg") 25 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.3) 2 | project(SimpleProject) 3 | 4 | find_package(LLVM REQUIRED CONFIG) 5 | 6 | list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") 7 | include(AddLLVM) 8 | 9 | message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 10 | message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") 11 | 12 | # Set your project compile flags. 13 | # E.g. if using the C++ header files 14 | # you will need to enable C++11 support 15 | # for your compiler. 16 | 17 | set(CMAKE_CXX_FLAGS "-std=c++11 -D__STDC_LIMIT_MACROS=1") 18 | 19 | include_directories( 20 | ${LLVM_INCLUDE_DIRS} 21 | ${CMAKE_SOURCE_DIR}/include 22 | ) 23 | add_definitions(${LLVM_DEFINITIONS}) 24 | 25 | # Now build our tools 26 | # add_executable(simple-tool tool.cpp) 27 | 28 | # Find the libraries that correspond to the LLVM components 29 | # that we wish to use 30 | llvm_map_components_to_libnames(llvm_libs support core irreader) 31 | 32 | # Link against LLVM libraries 33 | # target_link_libraries(simple-tool ${llvm_libs}) 34 | 35 | add_subdirectory(lib) 36 | add_subdirectory(tools) 37 | -------------------------------------------------------------------------------- /include/cmp/InstructionAlternatives.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #ifndef _INSTRUCTIONALTERNATIVES_H_ 20 | #define _INSTRUCTIONALTERNATIVES_H_ 21 | 22 | #include "llvm/IR/BasicBlock.h" 23 | #include "llvm/IR/Instruction.h" 24 | 25 | #include 26 | 27 | 28 | namespace cmp 29 | { 30 | 31 | class InstructionAlternatives 32 | { 33 | public: 34 | static std::vector Build(llvm::Instruction & I); 35 | }; 36 | 37 | } 38 | 39 | #endif /* _INSTRUCTIONALTERNATIVES_H_ */ 40 | -------------------------------------------------------------------------------- /lib/CodeMorphing/InstructionAlternativeUtils.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #include "cmp/InstructionAlternativeUtils.h" 20 | 21 | #include "llvm/IR/Instruction.h" 22 | 23 | 24 | using namespace cmp; 25 | using namespace llvm; 26 | 27 | 28 | InstructionTy 29 | cmp::getInstTy(Instruction * I) 30 | { 31 | #define CHECK_INST(Ty) \ 32 | do { if (I->getOpcode() == Instruction::Ty) return Ty; } while (0) 33 | 34 | #include 35 | 36 | #undef CHECK_INST 37 | return LastInstructionTy; 38 | } 39 | -------------------------------------------------------------------------------- /include/cmp/AlternativesNumberVector.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #ifndef _ALTERNATIVESNUMBERVECTOR_H_ 20 | #define _ALTERNATIVESNUMBERVECTOR_H_ 21 | 22 | #include "llvm/Pass.h" 23 | 24 | namespace cmp 25 | { 26 | 27 | class AlternativesNumberVector : public llvm::ModulePass 28 | { 29 | public: 30 | static char ID; 31 | 32 | AlternativesNumberVector(); 33 | 34 | bool runOnModule(llvm::Module & M); 35 | 36 | void getAnalysisUsage(llvm::AnalysisUsage &AU) const; 37 | }; 38 | 39 | } 40 | 41 | #endif /* _ALTERNATIVESNUMBERVECTOR_H_ */ 42 | -------------------------------------------------------------------------------- /include/cmp/DeclareRandomizeFunction.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #ifndef _DECLARERANDOMIZEFUNCTION_H_ 20 | #define _DECLARERANDOMIZEFUNCTION_H_ 21 | 22 | #include 23 | 24 | namespace cmp 25 | { 26 | 27 | class DeclareRandomizeFunction : public llvm::ModulePass 28 | { 29 | public: 30 | static char ID; 31 | 32 | DeclareRandomizeFunction(); 33 | 34 | bool runOnModule(llvm::Module & M); 35 | 36 | void getAnalysisUsage(llvm::AnalysisUsage &AU) const; 37 | }; 38 | 39 | } 40 | 41 | #endif /* _DECLARERANDOMIZEFUNCTION_H_ */ 42 | -------------------------------------------------------------------------------- /include/cmp/CodeMorphing.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #ifndef _CODEMORPHING_H_ 20 | #define _CODEMORPHING_H_ 21 | 22 | #include "llvm/Pass.h" 23 | 24 | namespace cmp 25 | { 26 | 27 | class CodeMorphing : public llvm::FunctionPass 28 | { 29 | public: 30 | static char ID; 31 | 32 | CodeMorphing(); 33 | 34 | bool runOnFunction(llvm::Function &F); 35 | 36 | void getAnalysisUsage(llvm::AnalysisUsage &AU) const; 37 | 38 | const char * getPassName() const 39 | { 40 | return "Code Morphing Pass"; 41 | } 42 | }; 43 | 44 | } 45 | 46 | #endif /* _CODEMORPHING_H_ */ 47 | -------------------------------------------------------------------------------- /include/cmp/AllPasses.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Marco Minutoli 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301, USA. 18 | */ 19 | 20 | 21 | #ifndef CMP_ALLPASSES_H 22 | #define CMP_ALLPASSES_H 23 | 24 | #include "llvm/ADT/StringRef.h" 25 | #include "llvm/Pass.h" 26 | 27 | namespace cmp { 28 | 29 | class AlternativesNumberVector; 30 | class CodeMorphing; 31 | class DeclareRandomizeFunction; 32 | 33 | // Transformations 34 | AlternativesNumberVector * CreateAlternativesNumberVectorPass(); 35 | CodeMorphing * CreateCodeMorphingPass(); 36 | DeclareRandomizeFunction * CreateDeclareRandomizeFunctionPass(); 37 | 38 | } // End namespace cot. 39 | 40 | namespace llvm { 41 | 42 | class PassRegistry; 43 | 44 | // Transformations 45 | void initializeAlternativesNumberVectorPass(PassRegistry & Registry); 46 | void initializeCodeMorphingPass(PassRegistry & Registry); 47 | void initializeDeclareRandomizeFunctionPass(PassRegistry & Registry); 48 | 49 | } // End namespace llvm. 50 | 51 | #endif // CMP_ALLPASSES_H 52 | -------------------------------------------------------------------------------- /autoconf/AutoRegen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | die () { 3 | echo "$@" 1>&2 4 | exit 1 5 | } 6 | test -d autoconf && test -f autoconf/configure.ac && cd autoconf 7 | test -f configure.ac || die "Can't find 'autoconf' dir; please cd into it first" 8 | autoconf --version | egrep '2\.[56][0-9]' > /dev/null 9 | if test $? -ne 0 ; then 10 | die "Your autoconf was not detected as being 2.5x or 2.6x" 11 | fi 12 | cwd=`pwd` 13 | if test -d ../../../autoconf/m4 ; then 14 | cd ../../../autoconf/m4 15 | llvm_m4=`pwd` 16 | llvm_src_root=../.. 17 | llvm_obj_root=../.. 18 | cd $cwd 19 | elif test -d ../../llvm/autoconf/m4 ; then 20 | cd ../../llvm/autoconf/m4 21 | llvm_m4=`pwd` 22 | llvm_src_root=.. 23 | llvm_obj_root=.. 24 | cd $cwd 25 | else 26 | while true ; do 27 | echo "LLVM source root not found." 28 | read -p "Enter full path to LLVM source:" REPLY 29 | if test -d "$REPLY/autoconf/m4" ; then 30 | llvm_src_root="$REPLY" 31 | llvm_m4="$REPLY/autoconf/m4" 32 | read -p "Enter full path to LLVM objects (empty for same as source):" REPLY 33 | if test -d "$REPLY" ; then 34 | llvm_obj_root="$REPLY" 35 | else 36 | llvm_obj_root="$llvm_src_root" 37 | fi 38 | break 39 | fi 40 | done 41 | fi 42 | # Patch the LLVM_ROOT in configure.ac, if it needs it 43 | cp configure.ac configure.bak 44 | sed -e "s#^LLVM_SRC_ROOT=.*#LLVM_SRC_ROOT=\"$llvm_src_root\"#" \ 45 | -e "s#^LLVM_OBJ_ROOT=.*#LLVM_OBJ_ROOT=\"$llvm_obj_root\"#" configure.bak > configure.ac 46 | echo "Regenerating aclocal.m4 with aclocal" 47 | rm -f aclocal.m4 48 | aclocal -I $llvm_m4 -I "$llvm_m4/.." || die "aclocal failed" 49 | echo "Regenerating configure with autoconf" 50 | autoconf --warnings=all -o ../configure configure.ac || die "autoconf failed" 51 | cd .. 52 | exit 0 53 | -------------------------------------------------------------------------------- /lib/CodeMorphing/InstructionAlternatives.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #include "cmp/InstructionAlternatives.h" 20 | 21 | #include "cmp/InstructionAlternativeUtils.h" 22 | 23 | #include "llvm/IR/BasicBlock.h" 24 | #include "llvm/IR/Instructions.h" 25 | #include "llvm/IR/Type.h" 26 | #include "llvm/IR/DerivedTypes.h" 27 | 28 | 29 | using namespace cmp; 30 | using namespace llvm; 31 | 32 | 33 | template 34 | std::vector buildAlternatives(llvm::Instruction & I); 35 | 36 | 37 | // Do not define it. 38 | template <> 39 | std::vector 40 | buildAlternatives(llvm::Instruction & I); 41 | 42 | 43 | #include 44 | 45 | 46 | std::vector 47 | InstructionAlternatives::Build(llvm::Instruction & I) 48 | { 49 | std::vector alternatives; 50 | 51 | InstructionTy type = getInstTy(&I); 52 | 53 | #define HANDLE_ISTRUCTION_TYPE(TYPE) \ 54 | case TYPE: \ 55 | alternatives = buildAlternatives(I); \ 56 | break 57 | 58 | switch (type) { 59 | #include 60 | case LastInstructionTy: 61 | break; 62 | } 63 | 64 | #undef HANDLE_ISTRUCTION_TYPE 65 | 66 | return alternatives; 67 | } 68 | -------------------------------------------------------------------------------- /lib/CodeMorphing/DeclareRandomizeFunction.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #include "cmp/DeclareRandomizeFunction.h" 20 | 21 | #include "cmp/AllPasses.h" 22 | #include "cmp/InstructionAlternatives.h" 23 | 24 | #include "llvm/IR/DerivedTypes.h" 25 | #include "llvm/IR/Module.h" 26 | #include "llvm/IR/Type.h" 27 | 28 | 29 | using namespace cmp; 30 | using namespace llvm; 31 | 32 | 33 | char DeclareRandomizeFunction::ID = 0; 34 | 35 | 36 | DeclareRandomizeFunction::DeclareRandomizeFunction() : 37 | llvm::ModulePass(ID) 38 | {} 39 | 40 | 41 | bool 42 | DeclareRandomizeFunction::runOnModule(llvm::Module & M) 43 | { 44 | llvm::Function * randomize = M.getFunction("randomize"); 45 | 46 | // Maybe the function type should be checked 47 | if (randomize != NULL) return false; 48 | 49 | llvm::LLVMContext &Ctx = M.getContext(); 50 | llvm::Type * IntTy = llvm::Type::getInt32Ty(Ctx); 51 | llvm::FunctionType * RandomizeTy = 52 | llvm::FunctionType::get(IntTy, IntTy, false); 53 | 54 | // Insert a declaration of randomize 55 | M.getOrInsertFunction("randomize", RandomizeTy); 56 | return true; 57 | } 58 | 59 | 60 | void 61 | DeclareRandomizeFunction::getAnalysisUsage(llvm::AnalysisUsage & AU) const 62 | { 63 | AU.setPreservesAll(); 64 | } 65 | 66 | 67 | DeclareRandomizeFunction * 68 | CreateDeclareRandomizeFunctionPass() 69 | { 70 | return new DeclareRandomizeFunction(); 71 | } 72 | 73 | 74 | INITIALIZE_PASS(DeclareRandomizeFunction, "", 75 | "Declare Randomize", 76 | false, 77 | false) 78 | -------------------------------------------------------------------------------- /tools/cmp/ForceLinking.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Marco Minutoli 2 | 3 | // This program is free software; you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation; either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program; if not, write to the Free Software 15 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 16 | // MA 02110-1301, USA. 17 | 18 | 19 | #include "cmp/AllPasses.h" 20 | 21 | #include 22 | 23 | using namespace cmp; 24 | 25 | // I have used the following layout for the project. Each pass is a static 26 | // library. All passes are contained in a loadable module, allowing using them 27 | // with opt. In order to achieve this behaviour, we need to perform some 28 | // black-magic with the linker. 29 | namespace { 30 | 31 | // First of all, we have to reference all pass creation functions, in order to 32 | // force linking them inside the loadable module. Using a static object with a 33 | // constructor referencing those functions in an unreachable code section is a 34 | // standard trick. 35 | class ForceLinking { 36 | public: 37 | ForceLinking() { 38 | // We must reference the passes in such a way that compilers will not 39 | // delete it all as dead code, even with whole program optimization, 40 | // yet is effectively a NO-OP. As the compiler isn't smart enough 41 | // to know that getenv() never returns -1, this will do the job. 42 | if(std::getenv("bar") != (char*) -1) 43 | return; 44 | 45 | // Analysis. 46 | 47 | // Transformations. 48 | CreateAlternativesNumberVectorPass(); 49 | CreateCodeMorphingPass(); 50 | CreateDeclareRandomizeFunctionPass(); 51 | } 52 | }; 53 | 54 | ForceLinking Link; 55 | 56 | // The second step is registering all passes to the LLVM pass registry. We can 57 | // still use the static-object-constructor trick, but this time you have to 58 | // really execute functions! 59 | class ForceInitialization { 60 | public: 61 | ForceInitialization() { 62 | llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); 63 | 64 | // Analysis 65 | 66 | // Dot Viewer Passes 67 | 68 | // Dot Printer Passes 69 | 70 | // Transformations 71 | initializeAlternativesNumberVectorPass(Registry); 72 | initializeCodeMorphingPass(Registry); 73 | initializeDeclareRandomizeFunctionPass(Registry); 74 | } 75 | }; 76 | 77 | ForceInitialization FI; 78 | 79 | } // End anonymous namespace 80 | -------------------------------------------------------------------------------- /test/cmp/xor.ll: -------------------------------------------------------------------------------- 1 | ; RUN: opt -load %projshlibdir/CMPasses.so \ 2 | ; RUN: -static-morphing \ 3 | ; RUN: -S -o - %s | FileCheck %s 4 | ; REQUIRES: loadable_module 5 | 6 | 7 | target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 8 | target triple = "x86_64-unknown-linux-gnu" 9 | 10 | define i32 @prova(i32 %a, i32 %b) #0 { 11 | entry: 12 | %a.addr = alloca i32, align 4 13 | %b.addr = alloca i32, align 4 14 | store i32 %a, i32* %a.addr, align 4 15 | store i32 %b, i32* %b.addr, align 4 16 | %0 = load i32* %a.addr, align 4 17 | %1 = load i32* %b.addr, align 4 18 | %xor = xor i32 %0, %1 19 | ret i32 %xor 20 | } 21 | ;CHECK: AlternativeNumber 22 | 23 | ;CHECK: prova 24 | ;CHECK: loopCondition: 25 | ;CHECK-NEXT: %0 = load i32* %idx.vector 26 | ;CHECK-NEXT: %.dec = add i32 %0, -1 27 | ;CHECK-NEXT: store i32 %.dec, i32* %idx.vector 28 | ;CHECK-NEXT: %1 = icmp ne i32 %0, 0 29 | ;CHECK-NEXT: br i1 %1, label %loopBody, label %oldEntry 30 | 31 | ;CHECK: loopBody: 32 | ;CHECK-NEXT: %2 = load i32* %idx.vector 33 | ;CHECK-NEXT: %3 = getelementptr inbounds [1 x i32]* @AlternativeNumber, i32 0, i32 %2 34 | ;CHECK-NEXT: %4 = load i32* %3 35 | ;CHECK-NEXT: %5 = call i32 @randomize(i32 %4) 36 | ;CHECK-NEXT: %6 = getelementptr inbounds [1 x i32]* %choice.vector, i32 0, i32 %2 37 | ;CHECK-NEXT: store i32 %5, i32* %6 38 | ;CHECK-NEXT: br label %loopCondition 39 | 40 | ;CHECK: oldEntry: 41 | ;CHECK-NEXT: %a.addr = alloca i32, align 4 42 | ;CHECK-NEXT: %b.addr = alloca i32, align 4 43 | ;CHECK-NEXT: store i32 %a, i32* %a.addr, align 4 44 | ;CHECK-NEXT: store i32 %b, i32* %b.addr, align 4 45 | ;CHECK-NEXT: %7 = load i32* %a.addr, align 4 46 | ;CHECK-NEXT: %8 = load i32* %b.addr, align 4 47 | ;CHECK-NEXT: %9 = getelementptr [1 x i32]* %choice.vector, i32 0, i32 0 48 | ;CHECK-NEXT: %10 = load i32* %9 49 | ;CHECK-NEXT: switch i32 %10, label %11 [ 50 | ;CHECK-NEXT: i32 0, label %11 51 | ;CHECK-NEXT: i32 1, label %14 52 | ;CHECK-NEXT: i32 2, label %19 53 | ;CHECK-NEXT: ] 54 | 55 | ;CHECK: ;