[intermediate representation] defined more symbols

This commit is contained in:
Philippe Tillet
2019-01-03 15:32:22 -05:00
parent 9a1739957d
commit c35ca8353e
12 changed files with 355 additions and 101 deletions

View File

@@ -22,10 +22,7 @@ file( GLOB_RECURSE ALL_SRC *.cpp *.hpp *.h *.py *.y *.l)
add_custom_target( ALL SOURCES ${ALL_SRC} )
# Compiler flags
link_directories(/home/philippe/Development/llvm-tlvm/build/lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(/home/philippe/Development/llvm-tlvm/include)
include_directories(/home/philippe/Development/llvm-tlvm/build/include)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Library

View File

@@ -1,88 +1,185 @@
# - Find LLVM
# This module can be used to find LLVM.
# It requires that the llvm-config executable be available on the system path.
# Once found, llvm-config is used for everything else.
# - Find LLVM headers and libraries.
# This module locates LLVM and adapts the llvm-config output for use with
# CMake.
#
# Typical usage could be:
# find_package(LLVM QUIET REQUIRED COMPONENTS jit native interpreter)
# A given list of COMPONENTS is passed to llvm-config.
#
# If the QUIET flag is not set, the specified components and LLVM version are
# outputted.
# The following variables are defined:
# LLVM_FOUND - true if LLVM was found
# LLVM_CXXFLAGS - C++ compiler flags for files that include LLVM headers.
# LLVM_HOST_TARGET - Target triple used to configure LLVM.
# LLVM_INCLUDE_DIRS - Directory containing LLVM include files.
# LLVM_LDFLAGS - Linker flags to add when linking against LLVM
# (includes -LLLVM_LIBRARY_DIRS).
# LLVM_LIBRARIES - Full paths to the library files to link against.
# LLVM_LIBRARY_DIRS - Directory containing LLVM libraries.
# LLVM_ROOT_DIR - The root directory of the LLVM installation.
# llvm-config is searched for in ${LLVM_ROOT_DIR}/bin.
# LLVM_VERSION_MAJOR - Major version of LLVM.
# LLVM_VERSION_MINOR - Minor version of LLVM.
# LLVM_VERSION_STRING - Full LLVM version string (e.g. 6.0.0svn).
# LLVM_VERSION_BASE_STRING - Base LLVM version string without git/svn suffix (e.g. 6.0.0).
#
# If the COMPONENTS are not set, the default set of "all" is used.
#
# The following variables are set:
#
# LLVM_FOUND - Set to YES if LLVM is found.
# LLVM_VERSION - Set to the decimal version of the LLVM library.
# LLVM_C_FLAGS - All flags that should be passed to a C compiler.
# LLVM_CXX_FLAGS - All flags that should be passed to a C++ compiler.
# LLVM_CPP_FLAGS - All flags that should be passed to the C pre-processor.
# LLVM_LD_FLAGS - Additional flags to pass to the linker.
# LLVM_LIBRARY_DIRS - A list of directories where the LLVM libraries are located.
# LLVM_INCLUDE_DIRS - A list of directories where the LLVM headers are located.
# LLVM_LIBRARIES - A list of libraries which should be linked against.
# Note: The variable names were chosen in conformance with the offical CMake
# guidelines, see ${CMAKE_ROOT}/Modules/readme.txt.
# A macro to run llvm config
macro(_llvm_config _var_name)
# Firstly, locate the LLVM config executable
find_program(_llvm_config_exe
NAMES llvm-config
PATHS /home/philippe/Development/llvm-tlvm/build/bin/
DOC "llvm-config executable location"
)
# Try suffixed versions to pick up the newest LLVM install available on Debian
# derivatives.
# We also want an user-specified LLVM_ROOT_DIR to take precedence over the
# system default locations such as /usr/local/bin. Executing find_program()
# multiples times is the approach recommended in the docs.
set(llvm_config_names llvm-config-8.0 llvm-config80
llvm-config-7.0 llvm-config70
llvm-config-6.0 llvm-config60
llvm-config-5.0 llvm-config50
llvm-config-4.0 llvm-config40
llvm-config-3.9 llvm-config39
llvm-config)
find_program(LLVM_CONFIG
NAMES ${llvm_config_names}
PATHS ${LLVM_ROOT_DIR}/bin NO_DEFAULT_PATH
DOC "Path to llvm-config tool.")
find_program(LLVM_CONFIG NAMES ${llvm_config_names})
# If no llvm-config executable was found, set the output variable to not
# found.
if(NOT _llvm_config_exe)
set(${_var_name} "${_var_name}-NOTFOUND")
else(NOT _llvm_config_exe)
# Otherwise, run llvm-config
execute_process(
COMMAND ${_llvm_config_exe} ${ARGN}
OUTPUT_VARIABLE ${_var_name}
RESULT_VARIABLE _llvm_config_retval
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(RESULT_VARIABLE)
message(SEND_ERROR
"Error running llvm-config with arguments: ${ARGN}")
endif(RESULT_VARIABLE)
endif(NOT _llvm_config_exe)
endmacro(_llvm_config)
# Prints a warning/failure message depending on the required/quiet flags. Copied
# from FindPackageHandleStandardArgs.cmake because it doesn't seem to be exposed.
macro(_LLVM_FAIL _msg)
if(LLVM_FIND_REQUIRED)
message(FATAL_ERROR "${_msg}")
else()
if(NOT LLVM_FIND_QUIETLY)
message(STATUS "${_msg}")
endif()
endif()
endmacro()
# The default set of components
set(_llvm_components all)
# If components have been specified via find_package, use them
if(LLVM_FIND_COMPONENTS)
set(_llvm_components ${LLVM_FIND_COMPONENTS})
endif(LLVM_FIND_COMPONENTS)
if(NOT LLVM_CONFIG)
if(NOT LLVM_FIND_QUIETLY)
message(WARNING "Could not find llvm-config (LLVM >= ${LLVM_FIND_VERSION}). Try manually setting LLVM_CONFIG to the llvm-config executable of the installation to use.")
endif()
else()
macro(llvm_set var flag)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
endif()
set(result_code)
execute_process(
COMMAND ${LLVM_CONFIG} --${flag}
RESULT_VARIABLE result_code
OUTPUT_VARIABLE LLVM_${var}
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
if(result_code)
_LLVM_FAIL("Failed to execute llvm-config ('${LLVM_CONFIG}', result code: '${result_code})'")
else()
if(${ARGV2})
file(TO_CMAKE_PATH "${LLVM_${var}}" LLVM_${var})
endif()
endif()
endmacro()
macro(llvm_set_libs var flag)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
endif()
set(result_code)
execute_process(
COMMAND ${LLVM_CONFIG} --${flag} ${LLVM_FIND_COMPONENTS}
RESULT_VARIABLE result_code
OUTPUT_VARIABLE tmplibs
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
if(result_code)
_LLVM_FAIL("Failed to execute llvm-config ('${LLVM_CONFIG}', result code: '${result_code})'")
else()
file(TO_CMAKE_PATH "${tmplibs}" tmplibs)
string(REGEX MATCHALL "${pattern}[^ ]+" LLVM_${var} ${tmplibs})
endif()
endmacro()
if(NOT LLVM_FIND_QUIETLY)
message(STATUS "Looking for LLVM components: ${_llvm_components}")
endif(NOT LLVM_FIND_QUIETLY)
llvm_set(VERSION_STRING version)
llvm_set(CXXFLAGS cxxflags)
llvm_set(HOST_TARGET host-target)
llvm_set(INCLUDE_DIRS includedir true)
llvm_set(ROOT_DIR prefix true)
llvm_set(ENABLE_ASSERTIONS assertion-mode)
_llvm_config(LLVM_VERSION --version)
_llvm_config(LLVM_C_FLAGS --cflags)
_llvm_config(LLVM_CXX_FLAGS --cxxflags)
_llvm_config(LLVM_CPP_FLAGS --cppflags)
_llvm_config(LLVM_LD_FLAGS --ldflags)
_llvm_config(LLVM_LIBRARY_DIRS --libdir)
_llvm_config(LLVM_INCLUDE_DIRS --includedir)
_llvm_config(LLVM_LIBRARIES --libs)
# The LLVM version string _may_ contain a git/svn suffix, so cut that off
string(SUBSTRING "${LLVM_VERSION_STRING}" 0 5 LLVM_VERSION_BASE_STRING)
if(NOT LLVM_FIND_QUIETLY)
message(STATUS "Found LLVM version: ${LLVM_VERSION}")
endif(NOT LLVM_FIND_QUIETLY)
# Versions below 3.9 do not support components debuginfocodeview, globalisel, ipa
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfocodeview" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "globalisel" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "ipa" index)
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-9][\\.0-9A-Za-z]*")
# Versions below 4.0 do not support component debuginfomsf
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfomsf" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^[3-5]\\..*")
# Versions below 6.0 do not support component windowsmanifest
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "windowsmanifest" index)
endif()
# handle the QUIETLY and REQUIRED arguments and set LLVM_FOUND to TRUE if
# all listed variables are TRUE
llvm_set(LDFLAGS ldflags)
# In LLVM 3.5+, the system library dependencies (e.g. "-lz") are accessed
# using the separate "--system-libs" flag.
llvm_set(SYSTEM_LIBS system-libs)
string(REPLACE "\n" " " LLVM_LDFLAGS "${LLVM_LDFLAGS} ${LLVM_SYSTEM_LIBS}")
llvm_set(LIBRARY_DIRS libdir true)
llvm_set_libs(LIBRARIES libs)
# LLVM bug: llvm-config --libs tablegen returns -lLLVM-3.8.0
# but code for it is not in shared library
if("${LLVM_FIND_COMPONENTS}" MATCHES "tablegen")
if (NOT "${LLVM_LIBRARIES}" MATCHES "LLVMTableGen")
set(LLVM_LIBRARIES "${LLVM_LIBRARIES};-lLLVMTableGen")
endif()
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-9][\\.0-9A-Za-z]*")
# Versions below 4.0 do not support llvm-config --cmakedir
set(LLVM_CMAKEDIR ${LLVM_LIBRARY_DIRS}/cmake/llvm)
else()
llvm_set(CMAKEDIR cmakedir)
endif()
llvm_set(TARGETS_TO_BUILD targets-built)
string(REGEX MATCHALL "${pattern}[^ ]+" LLVM_TARGETS_TO_BUILD ${LLVM_TARGETS_TO_BUILD})
endif()
# On CMake builds of LLVM, the output of llvm-config --cxxflags does not
# include -fno-rtti, leading to linker errors. Be sure to add it.
if(NOT MSVC AND (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")))
if(NOT ${LLVM_CXXFLAGS} MATCHES "-fno-rtti")
set(LLVM_CXXFLAGS "${LLVM_CXXFLAGS} -fno-rtti")
endif()
endif()
# Remove some clang-specific flags for gcc.
if(CMAKE_COMPILER_IS_GNUCXX)
string(REPLACE "-Wcovered-switch-default " "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS})
string(REPLACE "-Wstring-conversion " "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS})
string(REPLACE "-fcolor-diagnostics " "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS})
# this requires more recent gcc versions (not supported by 4.9)
string(REPLACE "-Werror=unguarded-availability-new " "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS})
endif()
# Remove gcc-specific flags for clang.
if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
string(REPLACE "-Wno-maybe-uninitialized " "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS})
endif()
string(REGEX REPLACE "([0-9]+).*" "\\1" LLVM_VERSION_MAJOR "${LLVM_VERSION_STRING}" )
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*[A-Za-z]*" "\\1" LLVM_VERSION_MINOR "${LLVM_VERSION_STRING}" )
if (${LLVM_VERSION_STRING} VERSION_LESS ${LLVM_FIND_VERSION})
message(FATAL_ERROR "Unsupported LLVM version found ${LLVM_VERSION_STRING}. At least version ${LLVM_FIND_VERSION} is required.")
endif()
# Use the default CMake facilities for handling QUIET/REQUIRED.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVM
DEFAULT_MSG
LLVM_LIBRARIES
LLVM_INCLUDE_DIRS
LLVM_LIBRARY_DIRS)
# vim:sw=4:ts=4:autoindent
find_package_handle_standard_args(LLVM
REQUIRED_VARS LLVM_ROOT_DIR LLVM_HOST_TARGET
VERSION_VAR LLVM_VERSION_STRING)

View File

@@ -52,6 +52,30 @@ private:
double value_;
};
/* global value */
class global_value: public constant {
public:
enum linkage_types_t {
internal
};
public:
global_value(type *ty, unsigned num_ops,
linkage_types_t linkage, const std::string &name,
unsigned addr_space);
private:
linkage_types_t linkage_;
};
/* global object */
class global_object: public global_value {
public:
global_object(type *ty, unsigned num_ops,
linkage_types_t linkage, const std::string &name,
unsigned addr_space = 0);
};
}
}

View File

@@ -3,35 +3,52 @@
#include <string>
#include "value.h"
#include "constant.h"
namespace tdl{
namespace ir{
class function;
class function_type;
class module;
/* Argument */
class argument: public value{
argument(type *ty, const std::string &name, function *parent, unsigned arg_no);
public:
static argument* create(type *ty, const std::string &name,
function *parent = nullptr, unsigned arg_no = 0);
private:
function *parent_;
unsigned arg_no_;
};
/* Function */
class function: public value{
using arg_iterator = argument *;
using const_arg_iterator = const argument *;
class function: public global_object{
typedef std::vector<argument*> args_t;
typedef args_t::iterator arg_iterator;
typedef args_t::const_iterator const_arg_iterator;
private:
function(function_type *ty, linkage_types_t linkage,
const std::string &name = "", module *parent = nullptr);
public:
arg_iterator arg_begin();
arg_iterator arg_end();
const_arg_iterator arg_begin() const;
const_arg_iterator arg_end() const;
arg_iterator arg_begin() { return args_.begin(); }
arg_iterator arg_end() { return args_.end(); }
const_arg_iterator arg_begin() const { return args_.begin(); }
const_arg_iterator arg_end() const { return args_.end(); }
// Accessors
function_type* get_function_ty() const;
// Factory methods
static function *create(function_type *type, const std::string &name, module *mod);
static function *create(function_type *ty, linkage_types_t linkage,
const std::string &name, module *mod);
private:
function_type *type_;
std::string name_;
module *mod_;
module *parent_;
args_t args_;
bool init_;
};
}

View File

@@ -68,6 +68,10 @@ public:
// Get operand
op_t get_op() const { return op_; }
// Wraps
void set_has_no_unsigned_wrap(bool b = true) { has_no_unsigned_wrap_ = b; }
void set_has_no_signed_wrap(bool b = true) { has_no_signed_wrap_ = b; }
// Factory methods
static binary_operator *create(op_t op, value *lhs, value *rhs,
const std::string &name = "", instruction *next = nullptr);
@@ -77,6 +81,8 @@ public:
public:
op_t op_;
bool has_no_unsigned_wrap_;
bool has_no_signed_wrap_;
};
@@ -235,13 +241,26 @@ private:
type *res_elt_ty;
};
//===----------------------------------------------------------------------===//
// load_inst/store_inst classes
//===----------------------------------------------------------------------===//
class load_inst: public unary_inst{
load_inst(value *ptr, const std::string &name, instruction *next);
public:
static load_inst* create(value *ptr, const std::string &name = "",
instruction *next = nullptr);
};
//===----------------------------------------------------------------------===//
// retile_inst classes
//===----------------------------------------------------------------------===//
// retile
class retile_inst: public instruction {
class retile_inst: public unary_inst {
protected:
retile_inst(value *arg, const std::vector<unsigned> &shapes, const std::string &name, instruction *next);
};

View File

@@ -49,6 +49,7 @@ public:
const std::vector<unsigned> &get_tile_shapes() const;
type *get_tile_element_ty() const;
unsigned get_pointer_address_space() const;
type *get_pointer_element_ty() const;
// primitive predicates
bool is_void_ty() const { return id_ == VoidTyID; }
@@ -159,6 +160,10 @@ private:
function_type(type *ret_ty, const std::vector<type *> &param_tys);
public:
// accessors
unsigned get_num_params() const { return contained_tys_.size() - 1; }
type* get_param_ty(unsigned i) const { return contained_tys_.at(1 + i); }
// factory methods
static function_type* get(type *ret_ty, const std::vector<type*>& param_tys);
};

View File

@@ -76,8 +76,7 @@ ir::type* pointer::type_impl(ir::module*, ir::type *type) const{
// Function
void function::bind_parameters(ir::module *mod, ir::function *fn) const{
std::vector<ir::value*> args;
std::transform(fn->arg_begin(), fn->arg_end(), std::back_inserter(args), [&](ir::argument& x){ return &x;});
std::vector<ir::value*> args(fn->arg_begin(), fn->arg_end());
assert(args.size() == args_->values().size());
for(size_t i = 0; i < args.size(); i++){
parameter *param_i = args_->values().at(i);
@@ -100,7 +99,7 @@ ir::type* function::type_impl(ir::module* mod, ir::type *type) const{
ir::value* function_definition::codegen(ir::module *mod) const{
ir::function_type *prototype = (ir::function_type*)header_->type(mod, spec_->type(mod));
const std::string &name = header_->id()->name();
ir::function *fn = ir::function::create(prototype, name, mod);
ir::function *fn = ir::function::create(prototype, ir::function::internal, name, mod);
header_->bind_parameters(mod, fn);
ir::basic_block *entry = ir::basic_block::create(mod->get_context(), "entry", fn);
mod->seal_block(entry);

View File

@@ -1,7 +1,9 @@
#include <string>
#include "ir/basic_block.h"
#include "ir/builder.h"
#include "ir/constant.h"
#include "ir/instructions.h"
#include "ir/type.h"
#include "llvm/IR/Instruction.h"
namespace tdl{
@@ -11,7 +13,7 @@ builder::builder(context &ctx):
ctx_(ctx){}
//===----------------------------------------------------------------------===//
// insertion helpers
// utilities
//===----------------------------------------------------------------------===//
void builder::set_insert_point(basic_block::iterator instr){
@@ -24,6 +26,16 @@ void builder::set_insert_point(basic_block *block){
insert_point_ = block->end();
}
//===----------------------------------------------------------------------===//
// convenience functions
//===----------------------------------------------------------------------===//
value *builder::get_int32(unsigned val) {
return constant_int::get(type::get_int32_ty(ctx_), val);
}
//===----------------------------------------------------------------------===//
// terminator instructions
//===----------------------------------------------------------------------===//
@@ -99,6 +111,16 @@ DEFINE_UNARY_FLOAT(fneg)
// binary int instructions
//===----------------------------------------------------------------------===//
value* builder::create_insert_nuwnswb_binop(binary_operator::op_t op, value *lhs,
value *rhs, const std::string &name,
bool has_nuw, bool has_nsw) {
binary_operator* result = insert(binary_operator::create(op, lhs, rhs), name);
if (has_nuw) result->set_has_no_unsigned_wrap();
if (has_nsw) result->set_has_no_signed_wrap();
return result;
}
#define DEFINE_NOWRAP_BINARY(SUFFIX, OPCODE)\
value* builder::create_ ## SUFFIX(value *lhs, value *rhs, const std::string &name, bool has_nuw, bool has_nsw){\
return create_insert_nuwnswb_binop(OPCODE, lhs, rhs, name, has_nuw, has_nsw);\
@@ -192,12 +214,12 @@ DEFINE_FCMP_INSTR(ONE, llvm::FCmpInst::FCMP_ONE)
//===----------------------------------------------------------------------===//
// load instructions
// load/store instructions
//===----------------------------------------------------------------------===//
//value *builder::create_load(value *arg, const std::string &name){
//}
value *builder::create_load(value *arg, const std::string &name){
return load_inst::create(arg, name);
}
//===----------------------------------------------------------------------===//
// tile instructions

View File

@@ -88,6 +88,20 @@ undef_value *undef_value::get(type *ty) {
return result;
}
/* global value */
global_value::global_value(type *ty, unsigned num_ops,
linkage_types_t linkage,
const std::string &name, unsigned addr_space)
: constant(pointer_type::get(ty, addr_space), num_ops, name),
linkage_(linkage) { }
/* global object */
global_object::global_object(type *ty, unsigned num_ops,
linkage_types_t linkage,
const std::string &name, unsigned addr_space)
: global_value(ty, num_ops, linkage, name, addr_space) { }
}
}

View File

@@ -0,0 +1,47 @@
#include "ir/function.h"
#include "ir/type.h"
namespace tdl{
namespace ir{
/* Argument */
argument::argument(type *ty, const std::string &name, function *parent, unsigned arg_no)
: value(ty, name), parent_(parent), arg_no_(arg_no) { }
argument *argument::create(type *ty, const std::string &name,
function *parent, unsigned arg_no) {
return new argument(ty, name, parent, arg_no);
}
/* function */
function::function(function_type *ty, linkage_types_t linkage,
const std::string &name, module *parent)
: global_object(ty, 0, linkage, name), parent_(parent) {
// create arguments
function_type *fn_ty = get_function_ty();
unsigned num_params = fn_ty->get_num_params();
if(num_params > 0) {
args_.resize(num_params);
for(unsigned i = 0; i < num_params; i++){
type *param_ty = fn_ty->get_param_ty(i);
args_.push_back(argument::create(param_ty, "", this, i));
}
}
}
function *function::create(function_type *ty, linkage_types_t linkage,
const std::string &name, module *mod){
return new function(ty, linkage, name, mod);
}
function_type* function::get_function_ty() const
{ return static_cast<function_type*>(get_type()); }
}
}

View File

@@ -285,6 +285,15 @@ getelementptr_inst *getelementptr_inst::create(type *pointee_ty, value *ptr, con
}
//===----------------------------------------------------------------------===//
// load_inst/store_inst classes
//===----------------------------------------------------------------------===//
load_inst::load_inst(value *ptr, const std::string &name, instruction *next)
: unary_inst(ptr->get_type()->get_pointer_element_ty(), ptr, name, next) { }
load_inst* load_inst::create(value *ptr, const std::string &name, instruction *next) {
return new load_inst(ptr, name, next);
}
//===----------------------------------------------------------------------===//
// retile_inst classes
@@ -292,9 +301,7 @@ getelementptr_inst *getelementptr_inst::create(type *pointee_ty, value *ptr, con
retile_inst::retile_inst(value *arg, const std::vector<unsigned> &shapes,
const std::string &name, instruction *next)
: instruction(tile_type::get(arg->get_type()->get_scalar_ty(), shapes), 1, name, next) {
set_operand(0, arg);
}
: unary_inst(tile_type::get(arg->get_type()->get_scalar_ty(), shapes), arg, name, next) { }
// reshape

View File

@@ -40,6 +40,12 @@ unsigned type::get_pointer_address_space() const {
return ((pointer_type*)this)->get_address_space();
}
type * type::get_pointer_element_ty() const {
assert(is_pointer_ty());
return ((pointer_type*)this)->get_element_ty();
}
const std::vector<unsigned> &type::get_tile_shapes() const {
assert(is_tile_ty());
return ((tile_type*)this)->get_shapes();