2019-01-02 01:06:43 -05:00
|
|
|
#include "ir/basic_block.h"
|
|
|
|
#include "ir/instructions.h"
|
2019-01-02 14:37:14 -05:00
|
|
|
#include "ir/constant.h"
|
2019-01-02 01:06:43 -05:00
|
|
|
|
|
|
|
namespace tdl{
|
|
|
|
namespace ir{
|
|
|
|
|
2019-01-02 14:37:14 -05:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// instruction classes
|
|
|
|
//===----------------------------------------------------------------------===//
|
2019-01-02 01:06:43 -05:00
|
|
|
|
|
|
|
instruction::instruction(type *ty, unsigned num_ops, instruction *next)
|
|
|
|
: user(ty, num_ops) {
|
|
|
|
if(next){
|
|
|
|
basic_block *block = next->get_parent();
|
|
|
|
assert(block && "Next instruction is not in a basic block!");
|
2019-01-02 14:37:14 -05:00
|
|
|
auto it = std::find(block->begin(), block->end(), next);
|
|
|
|
block->get_inst_list().insert(it, next);
|
2019-01-02 01:06:43 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-02 14:37:14 -05:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// phi_node classes
|
|
|
|
//===----------------------------------------------------------------------===//
|
2019-01-02 01:06:43 -05:00
|
|
|
|
2019-01-02 14:37:14 -05:00
|
|
|
// Add incoming
|
|
|
|
void phi_node::add_incoming(value *x, basic_block *bb){
|
2019-01-02 01:06:43 -05:00
|
|
|
|
2019-01-02 14:37:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Factory methods
|
|
|
|
phi_node* phi_node::create(type *ty, unsigned num_reserved){
|
|
|
|
return new phi_node(ty, num_reserved);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// binary_operator classes
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
binary_operator::binary_operator(op_t op, value *lhs, value *rhs, type *ty, const std::string &name, instruction *next)
|
|
|
|
: instruction(ty, 2, next), op_(op){
|
|
|
|
set_operand(0, lhs);
|
|
|
|
set_operand(1, rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
binary_operator *binary_operator::create(op_t op, value *lhs, value *rhs, const std::string &name, instruction *next){
|
|
|
|
assert(lhs->get_type() == rhs->get_type() &&
|
|
|
|
"Cannot create binary operator with two operands of differing type!");
|
|
|
|
return new binary_operator(op, lhs, rhs, lhs->get_type(), name, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
binary_operator *binary_operator::create_fneg(value *arg, const std::string &name, instruction *next){
|
|
|
|
assert(arg->get_type()->is_floating_point_ty());
|
|
|
|
value *zero = constant_fp::get_zero_value_for_negation(arg->get_type());
|
|
|
|
return binary_operator::create(llvm::Instruction::FSub, zero, arg, name, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
binary_operator *binary_operator::create_neg(value *arg, const std::string &name, instruction *next){
|
|
|
|
assert(arg->get_type()->is_integer_ty());
|
|
|
|
value *zero = constant_fp::get_zero_value_for_negation(arg->get_type());
|
|
|
|
return binary_operator::create(llvm::Instruction::Sub, zero, arg, name, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
binary_operator *binary_operator::create_not(value *arg, const std::string &name, instruction *next){
|
|
|
|
assert(arg->get_type()->is_integer_ty());
|
|
|
|
constant *mask = constant::get_all_ones_value(arg->get_type());
|
|
|
|
return binary_operator::create(llvm::Instruction::Xor, arg, mask, name, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// cmp_inst classes
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
bool cmp_inst::is_fp_predicate(pred_t pred) {
|
|
|
|
return pred >= pcmp::FIRST_FCMP_PREDICATE && pred <= pcmp::LAST_FCMP_PREDICATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cmp_inst::is_int_predicate(pred_t pred) {
|
|
|
|
return pred >= pcmp::FIRST_ICMP_PREDICATE && pred <= pcmp::LAST_ICMP_PREDICATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// icmp_inst
|
|
|
|
|
|
|
|
icmp_inst* icmp_inst::create(pred_t pred, value *lhs, value *rhs, const std::string &name, instruction *next){
|
|
|
|
assert(is_int_predicate(pred));
|
|
|
|
return new icmp_inst(pred, lhs, rhs, name, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
// fcmp_inst
|
|
|
|
|
|
|
|
fcmp_inst* fcmp_inst::create(pred_t pred, value *lhs, value *rhs, const std::string &name, instruction *next){
|
|
|
|
assert(is_fp_predicate(pred));
|
|
|
|
return new fcmp_inst(pred, lhs, rhs, name, next);
|
|
|
|
}
|
2019-01-02 01:06:43 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|