diff --git a/CMakeLists.txt b/CMakeLists.txt index b20429946..cea5cc99d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/cmake/FindLLVM.cmake b/cmake/FindLLVM.cmake index b3196d444..e3e3606df 100644 --- a/cmake/FindLLVM.cmake +++ b/cmake/FindLLVM.cmake @@ -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) diff --git a/include/ir/constant.h b/include/ir/constant.h index c7c53ae2a..6dc8ecec8 100644 --- a/include/ir/constant.h +++ b/include/ir/constant.h @@ -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); +}; + } } diff --git a/include/ir/function.h b/include/ir/function.h index 3b8816b48..456faf5f3 100644 --- a/include/ir/function.h +++ b/include/ir/function.h @@ -3,35 +3,52 @@ #include #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 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_; }; } diff --git a/include/ir/instructions.h b/include/ir/instructions.h index 3c4c408ed..1d7ecffcd 100644 --- a/include/ir/instructions.h +++ b/include/ir/instructions.h @@ -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 &shapes, const std::string &name, instruction *next); }; diff --git a/include/ir/type.h b/include/ir/type.h index a82ed8e63..ebbbe5952 100644 --- a/include/ir/type.h +++ b/include/ir/type.h @@ -49,6 +49,7 @@ public: const std::vector &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 ¶m_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& param_tys); }; diff --git a/lib/codegen.cpp b/lib/codegen.cpp index 6d4b7038c..d6f41bba3 100644 --- a/lib/codegen.cpp +++ b/lib/codegen.cpp @@ -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 args; - std::transform(fn->arg_begin(), fn->arg_end(), std::back_inserter(args), [&](ir::argument& x){ return &x;}); + std::vector 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); diff --git a/lib/ir/builder.cpp b/lib/ir/builder.cpp index 43cca943d..b26c1946e 100644 --- a/lib/ir/builder.cpp +++ b/lib/ir/builder.cpp @@ -1,7 +1,9 @@ #include #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 diff --git a/lib/ir/constant.cpp b/lib/ir/constant.cpp index f2a3bd7e9..35e244613 100644 --- a/lib/ir/constant.cpp +++ b/lib/ir/constant.cpp @@ -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) { } + } } diff --git a/lib/ir/function.cpp b/lib/ir/function.cpp index e69de29bb..b7cc14df5 100644 --- a/lib/ir/function.cpp +++ b/lib/ir/function.cpp @@ -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(get_type()); } + + +} +} + diff --git a/lib/ir/instructions.cpp b/lib/ir/instructions.cpp index 51a778589..d330e015d 100644 --- a/lib/ir/instructions.cpp +++ b/lib/ir/instructions.cpp @@ -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 &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 diff --git a/lib/ir/type.cpp b/lib/ir/type.cpp index b6c9a4dff..50ffa7c23 100644 --- a/lib/ir/type.cpp +++ b/lib/ir/type.cpp @@ -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 &type::get_tile_shapes() const { assert(is_tile_ty()); return ((tile_type*)this)->get_shapes();