From 8f4aafb4ac68835d6c93e31267e780ec6f67a3fc Mon Sep 17 00:00:00 2001 From: Philippe Tillet Date: Thu, 3 Jan 2019 03:42:10 -0500 Subject: [PATCH] [intermediate representation] improvements on constants --- include/ir/basic_block.h | 3 ++ include/ir/constant.h | 28 +++++++++--- include/ir/context_impl.h | 9 ++++ include/ir/type.h | 19 ++++---- include/ir/value.h | 1 + lib/codegen.cpp | 5 ++- lib/ir/basic_block.cpp | 29 ++++++++++++ lib/ir/constant.cpp | 93 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 170 insertions(+), 17 deletions(-) diff --git a/include/ir/basic_block.h b/include/ir/basic_block.h index 3a4989f27..f6c7897f6 100644 --- a/include/ir/basic_block.h +++ b/include/ir/basic_block.h @@ -22,6 +22,9 @@ public: typedef inst_list_t::reverse_iterator reverse_iterator; typedef inst_list_t::const_reverse_iterator const_reverse_iterator; +private: + // constructors + basic_block(context &ctx, const std::string &name, function *parent); public: // accessors diff --git a/include/ir/constant.h b/include/ir/constant.h index 40f3b056c..c7c53ae2a 100644 --- a/include/ir/constant.h +++ b/include/ir/constant.h @@ -10,32 +10,46 @@ class type; class context; /* Constant */ -class constant: public value{ +class constant: public user{ +protected: + using user::user; + public: static constant* get_all_ones_value(type *ty); + static constant* get_null_value(type *ty); }; /* Undef value */ class undef_value: public constant{ +private: + undef_value(type *ty); + public: static undef_value* get(type* ty); }; -/* Data array */ -class constant_data_array: public constant{ -public: - static constant_data_array* get_string(context &ctx, const std::string &str); -}; - /* Constant int */ class constant_int: public constant{ + constant_int(type *ty, uint64_t value); +public: + static constant *get(type *ty, uint64_t value); + +private: + uint64_t value_; }; /* constant fp */ class constant_fp: public constant{ + constant_fp(context &ctx, double value); + public: + static constant* get_negative_zero(type *ty); static constant* get_zero_value_for_negation(type *ty); + static constant *get(context &ctx, double v); + +private: + double value_; }; diff --git a/include/ir/context_impl.h b/include/ir/context_impl.h index 091a563b6..cb3acc186 100644 --- a/include/ir/context_impl.h +++ b/include/ir/context_impl.h @@ -9,6 +9,9 @@ namespace tdl{ namespace ir{ class context; +class constant_int; +class constant_fp; +class undef_value; /* Context impl */ class context_impl { @@ -24,6 +27,12 @@ public: // Pointer types std::map, pointer_type*> ptr_tys; std::map>, tile_type*> tile_tys; + // Int constants + std::map int_constants_; + // Float constants + std::map fp_constants_; + // undef values + std::map uv_constants_; }; } diff --git a/include/ir/type.h b/include/ir/type.h index 43b6d1c34..8ff710373 100644 --- a/include/ir/type.h +++ b/include/ir/type.h @@ -19,14 +19,17 @@ public: HalfTyID, ///< 1: 16-bit floating point type FloatTyID, ///< 2: 32-bit floating point type DoubleTyID, ///< 3: 64-bit floating point type - LabelTyID, ///< 4: Labels - MetadataTyID, ///< 5: Metadata - TokenTyID, ///< 6: Token + X86_FP80TyID, ///< 4: 80-bit floating point type (X87) + FP128TyID, ///< 5: 128-bit floating point type (112-bit mantissa) + PPC_FP128TyID, ///< 6: 128-bit floating point type (two 64-bits, PowerPC) + LabelTyID, ///< 7: Labels + MetadataTyID, ///< 8: Metadata + TokenTyID, ///< 9: Token // derived types - IntegerTyID, ///< 7: Arbitrary bit width integers - FunctionTyID, ///< 8: Functions - PointerTyID, ///< 9: Pointers - TileTyID, ///< 10: Tile + IntegerTyID, ///< 10: Arbitrary bit width integers + FunctionTyID, ///< 11: Functions + PointerTyID, ///< 12: Pointers + TileTyID, ///< 13: Tile }; public: @@ -38,7 +41,7 @@ public: // accessors context &get_context() const { return ctx_; } - + id_t get_type_id() const { return id_; } // type attributes unsigned get_fp_mantissa_width() const; unsigned get_integer_bitwidth() const; diff --git a/include/ir/value.h b/include/ir/value.h index 1b26391f3..bab034603 100644 --- a/include/ir/value.h +++ b/include/ir/value.h @@ -19,6 +19,7 @@ class value { public: // constructor value(type *ty, const std::string &name = ""); + virtual ~value(){ } // uses void add_use(use *arg); // name diff --git a/lib/codegen.cpp b/lib/codegen.cpp index 9f8ad8420..6d4b7038c 100644 --- a/lib/codegen.cpp +++ b/lib/codegen.cpp @@ -477,8 +477,9 @@ ir::type *type_name::type(ir::module *mod) const{ } /* String literal */ -ir::value* string_literal::codegen(ir::module *mod) const{ - return ir::constant_data_array::get_string(mod->get_context(), value_); +ir::value* string_literal::codegen(ir::module *) const{ + throw std::runtime_error("not supported"); +// return ir::constant_data_array::get_string(mod->get_context(), value_); } /* Constant */ diff --git a/lib/ir/basic_block.cpp b/lib/ir/basic_block.cpp index e69de29bb..359c55d0c 100644 --- a/lib/ir/basic_block.cpp +++ b/lib/ir/basic_block.cpp @@ -0,0 +1,29 @@ +#include "ir/basic_block.h" +#include "ir/instructions.h" +#include "ir/type.h" + +namespace tdl { +namespace ir { + +class phi_node; + +basic_block::basic_block(context &ctx, const std::string &name, function *parent): + value(type::get_label_ty(ctx), name), ctx_(ctx), parent_(parent){ + +} + +basic_block* basic_block::create(context &ctx, const std::string &name, function *parent){ + return new basic_block(ctx, name, parent); +} + +basic_block::iterator basic_block::get_first_non_phi(){ + auto it = begin(); + for(; it != end(); it++) + if(!dynamic_cast(*it)) + return it; + return it; +} + +} + +} diff --git a/lib/ir/constant.cpp b/lib/ir/constant.cpp index e69de29bb..f2a3bd7e9 100644 --- a/lib/ir/constant.cpp +++ b/lib/ir/constant.cpp @@ -0,0 +1,93 @@ +#include "ir/constant.h" +#include "ir/type.h" +#include "ir/context.h" +#include "ir/context_impl.h" + +namespace tdl{ +namespace ir{ + + +// constant + +constant *constant::get_null_value(type *ty) { + context &ctx = ty->get_context(); + switch (ty->get_type_id()) { + case type::IntegerTyID: + return constant_int::get(ty, 0); + case type::HalfTyID: + return constant_fp::get(ctx, 0); + case type::FloatTyID: + return constant_fp::get(ctx, 0); + case type::DoubleTyID: + return constant_fp::get(ctx, 0); + case type::X86_FP80TyID: + return constant_fp::get(ctx, 0); + case type::FP128TyID: + return constant_fp::get(ctx, 0); + case type::PPC_FP128TyID: + return constant_fp::get(ctx, 0); + default: + throw std::runtime_error("Cannot create a null constant of that type!"); + } +} + +// FIXME + +constant *constant::get_all_ones_value(type *ty) { + if(ty->is_integer_ty()) + return constant_int::get(ty, 0xFFFFFFFF); + if(ty->is_floating_point_ty()) + return constant_fp::get(ty->get_context(), 0xFFFFFFFF); + throw std::runtime_error("Cannot create all ones value for that type!"); +} + +// constant_int +// FIXME use something like APInt + +constant_int::constant_int(type *ty, uint64_t value) + : constant(ty, 0), value_(value){ } + +constant *constant_int::get(type *ty, uint64_t value) { + return new constant_int(ty, value); +} + +// constant_fp +// FIXME use something like APFloat + +constant_fp::constant_fp(context &ctx, double value) + : constant(type::get_float_ty(ctx), 0), value_(value){ } + +constant *constant_fp::get_negative_zero(type *ty){ + double neg_zero = 0; + return get(ty->get_context(), neg_zero); +} + +constant *constant_fp::get_zero_value_for_negation(type *ty) { + if(ty->get_scalar_ty()->is_floating_point_ty()) + return get_negative_zero(ty); + return constant::get_null_value(ty); +} + +constant *constant_fp::get(context &ctx, double v){ + context_impl *impl = ctx.p_impl.get(); + constant_fp *&result = impl->fp_constants_[v]; + if(!result) + result = new constant_fp(ctx, v); + return result; +} + +// undef value +undef_value::undef_value(type *ty) + : constant(ty, 0) { } + +undef_value *undef_value::get(type *ty) { + context_impl *impl = ty->get_context().p_impl.get(); + undef_value *&result = impl->uv_constants_[ty]; + if(!result) + result = new undef_value(ty); + return result; +} + + +} +}