88 lines
2.3 KiB
C++
88 lines
2.3 KiB
C++
#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);
|
|
}
|
|
|
|
}
|
|
}
|