[intermediate representation] improvements on constants
This commit is contained in:
@@ -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
|
||||
|
@@ -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_;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -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<std::pair<type*, unsigned>, pointer_type*> ptr_tys;
|
||||
std::map<std::pair<type*,std::vector<unsigned>>, tile_type*> tile_tys;
|
||||
// Int constants
|
||||
std::map<uint64_t, constant_int*> int_constants_;
|
||||
// Float constants
|
||||
std::map<double, constant_fp*> fp_constants_;
|
||||
// undef values
|
||||
std::map<type*, undef_value*> uv_constants_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -19,6 +19,7 @@ class value {
|
||||
public:
|
||||
// constructor
|
||||
value(type *ty, const std::string &name = "");
|
||||
virtual ~value(){ }
|
||||
// uses
|
||||
void add_use(use *arg);
|
||||
// name
|
||||
|
@@ -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 */
|
||||
|
@@ -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<phi_node*>(*it))
|
||||
return it;
|
||||
return it;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user