2021-07-27 12:38:38 -07:00
|
|
|
#include <climits>
|
|
|
|
#include <iostream>
|
|
|
|
#include "triton/codegen/analysis/liveness.h"
|
|
|
|
#include "triton/codegen/analysis/layout.h"
|
|
|
|
#include "triton/ir/function.h"
|
|
|
|
#include "triton/ir/module.h"
|
|
|
|
#include "triton/ir/utils.h"
|
|
|
|
|
|
|
|
namespace triton{
|
|
|
|
namespace codegen{
|
|
|
|
namespace analysis{
|
|
|
|
|
|
|
|
|
|
|
|
void liveness::run(ir::module &mod) {
|
|
|
|
intervals_.clear();
|
|
|
|
|
2022-06-27 11:49:19 -07:00
|
|
|
std::map<ir::value*, std::set<shared_layout*>> layouts_map;
|
|
|
|
for(auto &x: layouts_->get_all()){
|
|
|
|
shared_layout* layout = x.second->to_shared();
|
|
|
|
if(!layout || layout->is_tmp())
|
|
|
|
continue;
|
|
|
|
for(ir::value* v:layout->get_values()){
|
|
|
|
layouts_map[v].insert(layout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::map<ir::user*, std::set<shared_layout*>> live_in;
|
|
|
|
while(true){
|
|
|
|
bool changed = false;
|
|
|
|
ir::instruction* last_inst = nullptr;
|
|
|
|
ir::for_each_instruction_backward(mod, [&](ir::instruction* i){
|
|
|
|
// gen
|
|
|
|
std::set<shared_layout*> gen;
|
|
|
|
for(ir::value* v: i->ops())
|
|
|
|
for(shared_layout* layout: layouts_map[v])
|
|
|
|
gen.insert(layout);
|
|
|
|
// kill
|
|
|
|
std::set<shared_layout*> kill;
|
|
|
|
for(shared_layout* layout: layouts_map[i])
|
|
|
|
kill.insert(layout);
|
|
|
|
// temporaries are handled separately
|
|
|
|
if(layouts_->has_tmp(i)){
|
|
|
|
gen.insert(layouts_->get(layouts_->tmp(i))->to_shared());
|
|
|
|
kill.insert(layouts_->get(layouts_->tmp(i))->to_shared());
|
|
|
|
}
|
|
|
|
if(layouts_->has_tmp_index(i)){
|
|
|
|
gen.insert(layouts_->get(layouts_->tmp_index(i))->to_shared());
|
|
|
|
kill.insert(layouts_->get(layouts_->tmp_index(i))->to_shared());
|
|
|
|
}
|
|
|
|
// live-out
|
|
|
|
std::set<shared_layout*> live_out;
|
|
|
|
std::vector<ir::instruction*> succs = {last_inst};
|
|
|
|
if(i == i->get_parent()->get_inst_list().back())
|
|
|
|
for(ir::basic_block* succ: i->get_parent()->get_successors())
|
|
|
|
succs.push_back(succ->get_inst_list().front());
|
|
|
|
for(ir::instruction* succ: succs)
|
|
|
|
for(shared_layout* layout: live_in[succ])
|
|
|
|
if(!layout->is_tmp())
|
|
|
|
live_out.insert(layout);
|
|
|
|
|
|
|
|
// new sets
|
|
|
|
std::set<shared_layout*> live_out_minus_kill;
|
|
|
|
std::set_difference(live_out.begin(), live_out.end(), kill.begin(), kill.end(),
|
|
|
|
std::inserter(live_out_minus_kill, live_out_minus_kill.end()));
|
|
|
|
std::set<shared_layout*> new_live_in;
|
|
|
|
std::set_union(gen.begin(), gen.end(), live_out_minus_kill.begin(), live_out_minus_kill.end(),
|
|
|
|
std::inserter(new_live_in, new_live_in.end()));
|
|
|
|
|
|
|
|
changed = changed || (new_live_in != live_in[i]);
|
|
|
|
live_in[i] = new_live_in;
|
|
|
|
last_inst = i;
|
|
|
|
});
|
|
|
|
if(!changed)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ir::for_each_instruction(mod, [&](ir::instruction* i){
|
|
|
|
// i->print(std::cout);
|
|
|
|
// std::cout << " live_in: " << live_in[i].size() << std::endl;
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-07-27 12:38:38 -07:00
|
|
|
// Assigns index to each instruction
|
|
|
|
std::map<ir::value*, slot_index> indices;
|
2022-06-27 11:49:19 -07:00
|
|
|
slot_index index = 0;
|
|
|
|
ir::for_each_instruction(mod, [&](ir::instruction* instr){
|
2021-07-27 12:38:38 -07:00
|
|
|
index += 1;
|
|
|
|
indices.insert({instr, index});
|
2022-06-27 11:49:19 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
for(auto &x: layouts_->get_all()){
|
|
|
|
shared_layout* layout = x.second->to_shared();
|
|
|
|
if(layout)
|
|
|
|
intervals_[layout] = segment{INT32_MAX, 0};
|
2021-07-27 12:38:38 -07:00
|
|
|
}
|
|
|
|
|
2022-06-27 11:49:19 -07:00
|
|
|
for(auto& x: live_in)
|
|
|
|
for(shared_layout* layout: x.second)
|
|
|
|
intervals_[layout].start = std::min<int>(intervals_[layout].start, indices[x.first]);
|
|
|
|
|
|
|
|
for(auto& x: live_in)
|
|
|
|
for(shared_layout* layout: x.second){
|
|
|
|
intervals_[layout].end = std::max<int>(intervals_[layout].end, indices[x.first] + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-07-27 12:38:38 -07:00
|
|
|
for(auto &x: layouts_->get_all()) {
|
|
|
|
shared_layout* layout = x.second->to_shared();
|
|
|
|
if(!layout)
|
|
|
|
continue;
|
2022-06-27 11:49:19 -07:00
|
|
|
// std::cout << intervals_[layout].start << " " << intervals_[layout].end << std::endl;
|
2021-07-27 12:38:38 -07:00
|
|
|
}
|
|
|
|
|
2022-06-27 11:49:19 -07:00
|
|
|
|
2021-07-27 12:38:38 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|