Files
triton/lib/ir/module.cpp

88 lines
2.3 KiB
C++
Raw Normal View History

#include "ir/module.h"
namespace tdl{
namespace ir{
/* Module */
module::module(const std::string &name, context *ctx)
: handle_(name.c_str(), *ctx->handle()), builder_(*ctx->handle()) {
sealed_blocks_.insert(nullptr);
}
Module* module::handle() {
return &handle_;
}
IRBuilder<>& module::builder() {
return builder_;
}
void module::set_value(const std::string& name, BasicBlock *block, Value *value){
values_[val_key_t{name, block}] = value;
}
void module::set_value(const std::string& name, Value* value){
return set_value(name, builder_.GetInsertBlock(), value);
}
PHINode* module::make_phi(Type *type, unsigned num_values, BasicBlock *block){
Instruction* instr = block->getFirstNonPHIOrDbg();
if(instr)
builder_.SetInsertPoint(instr);
PHINode *res = builder_.CreatePHI(type, num_values);
if(instr)
builder_.SetInsertPoint(block);
return res;
}
Value *module::add_phi_operands(const std::string& name, PHINode *&phi){
BasicBlock *block = phi->getParent();
for(BasicBlock *pred: predecessors(block)){
Value *value = get_value(name, pred);
phi->addIncoming(value, pred);
}
return phi;
}
Value *module::get_value_recursive(const std::string& name, BasicBlock *block) {
Value *result;
if(sealed_blocks_.find(block) == sealed_blocks_.end()){
Value *pred = get_value(name, *pred_begin(block));
incomplete_phis_[block][name] = make_phi(pred->getType(), 1, block);
result = (Value*)incomplete_phis_[block][name];
}
else if(pred_size(block) <= 1){
bool has_pred = pred_size(block);
result = get_value(name, has_pred?*pred_begin(block):nullptr);
}
else{
Value *pred = get_value(name, *pred_begin(block));
result = make_phi(pred->getType(), 1, block);
set_value(name, block, result);
add_phi_operands(name, (PHINode*&)result);
}
set_value(name, block, result);
return result;
}
Value *module::get_value(const std::string& name, BasicBlock *block) {
val_key_t key(name, block);
if(values_.find(key) != values_.end()){
return values_.at(key);
}
return get_value_recursive(name, block);
}
Value *module::get_value(const std::string& name) {
return get_value(name, builder_.GetInsertBlock());
}
Value *module::seal_block(BasicBlock *block){
for(auto &x: incomplete_phis_[block])
add_phi_operands(x.first, x.second);
sealed_blocks_.insert(block);
}
}
}