Commit d4aaa88a authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fixes

parent 4ae8f9b7
...@@ -863,9 +863,12 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -863,9 +863,12 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
llvm::Value* val = v->getValue(); llvm::Value* val = v->getValue();
llvm_phi->addIncoming(v->getValue(), llvm_exit_blocks[b->predecessors[j]]); llvm_phi->addIncoming(v->getValue(), llvm_exit_blocks[b->predecessors[j]]);
llvm::outs() << *v->getValue() << " is getting consumed by phi " << *llvm_phi << '\n'; if (v->getType()->getBoxType() == v->getType()) {
irstate->getRefcounts()->setType(llvm_phi, RefType::OWNED); llvm::outs() << *v->getValue() << " is getting consumed by phi " << *llvm_phi << '\n';
irstate->getRefcounts()->refConsumed(v->getValue(), llvm_exit_blocks[b->predecessors[j]]->getTerminator()); irstate->getRefcounts()->setType(llvm_phi, RefType::OWNED);
assert(llvm::isa<llvm::BranchInst>(llvm_exit_blocks[b->predecessors[j]]->getTerminator()));
irstate->getRefcounts()->refConsumed(v->getValue(), llvm_exit_blocks[b->predecessors[j]]->getTerminator());
}
} }
if (this_is_osr_entry) { if (this_is_osr_entry) {
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
namespace pyston { namespace pyston {
llvm::Value* RefcountTracker::setType(llvm::Value* v, RefType reftype) { llvm::Value* RefcountTracker::setType(llvm::Value* v, RefType reftype) {
assert(!llvm::isa<llvm::UndefValue>(v));
auto& var = this->vars[v]; auto& var = this->vars[v];
assert(var.reftype == reftype || var.reftype == RefType::UNKNOWN); assert(var.reftype == reftype || var.reftype == RefType::UNKNOWN);
...@@ -245,14 +247,15 @@ class BlockOrderer { ...@@ -245,14 +247,15 @@ class BlockOrderer {
private: private:
llvm::DenseMap<llvm::BasicBlock*, int> priority; // lower goes first llvm::DenseMap<llvm::BasicBlock*, int> priority; // lower goes first
class BlockComparer { struct BlockComparer {
bool operator()(std::pair<llvm::BasicBlock*, int> lhs, std::pair<llvm::BasicBlock*, int> rhs) { bool operator()(std::pair<llvm::BasicBlock*, int> lhs, std::pair<llvm::BasicBlock*, int> rhs) {
return lhs.second < rhs.second; return lhs.second > rhs.second;
} }
}; };
llvm::DenseSet<llvm::BasicBlock*> in_queue; llvm::DenseSet<llvm::BasicBlock*> in_queue;
std::priority_queue<std::pair<llvm::BasicBlock*, int>> queue; std::priority_queue<std::pair<llvm::BasicBlock*, int>, std::vector<std::pair<llvm::BasicBlock*, int>>,
BlockComparer> queue;
public: public:
BlockOrderer(std::vector<llvm::BasicBlock*> order) { BlockOrderer(std::vector<llvm::BasicBlock*> order) {
...@@ -262,6 +265,7 @@ public: ...@@ -262,6 +265,7 @@ public:
} }
void add(llvm::BasicBlock* b) { void add(llvm::BasicBlock* b) {
assert(in_queue.size() == queue.size());
if (in_queue.count(b)) if (in_queue.count(b))
return; return;
assert(priority.count(b)); assert(priority.count(b));
...@@ -416,6 +420,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -416,6 +420,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
} }
#endif #endif
llvm::outs() << '\n';
llvm::outs() << "Processing " << BB.getName() << '\n'; llvm::outs() << "Processing " << BB.getName() << '\n';
RefState& state = states[&BB]; RefState& state = states[&BB];
...@@ -484,6 +489,13 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -484,6 +489,13 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
// Then, iterate backwards through the instructions in this BB, updating the ref states // Then, iterate backwards through the instructions in this BB, updating the ref states
for (auto &I : llvm::iterator_range<llvm::BasicBlock::reverse_iterator>(BB.rbegin(), BB.rend())) { for (auto &I : llvm::iterator_range<llvm::BasicBlock::reverse_iterator>(BB.rbegin(), BB.rend())) {
// Phis get special handling:
// - we only use one of the operands to the phi node (based on the block we came from)
// - the phi-node-generator is supposed to handle that by putting a refConsumed on the terminator of the previous block
// - that refConsumed will caus a use as well.
if (llvm::isa<llvm::PHINode>(&I))
continue;
llvm::DenseMap<llvm::Value*, int> num_consumed_by_inst; llvm::DenseMap<llvm::Value*, int> num_consumed_by_inst;
llvm::DenseMap<llvm::Value*, int> num_times_as_op; llvm::DenseMap<llvm::Value*, int> num_times_as_op;
...@@ -536,6 +548,8 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -536,6 +548,8 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
} }
} }
llvm::outs() << "End of " << BB.getName() << '\n';
// Handle variables that were defined in this BB: // Handle variables that were defined in this BB:
for (auto&& p : rt->vars) { for (auto&& p : rt->vars) {
llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(p.first); llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(p.first);
...@@ -568,9 +582,9 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -568,9 +582,9 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
for (auto&& p : state.ending_refs) { for (auto&& p : state.ending_refs) {
assert(p.second); assert(p.second);
// Anything left should either be an argument or a global variable // Anything left should either be an argument, constant or global variable
#ifndef NDEBUG #ifndef NDEBUG
if (!llvm::isa<llvm::GlobalVariable>(p.first)) { if (!llvm::isa<llvm::GlobalVariable>(p.first) && !llvm::isa<llvm::Constant>(p.first)) {
bool found = false; bool found = false;
for (auto&& arg : f->args()) { for (auto&& arg : f->args()) {
if (&arg == p.first) { if (&arg == p.first) {
...@@ -578,6 +592,8 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -578,6 +592,8 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
break; break;
} }
} }
if (!found)
llvm::outs() << "Couldn't find " << *p.first << '\n';
assert(found); assert(found);
} }
#endif #endif
...@@ -590,7 +606,8 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -590,7 +606,8 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
if (endingRefsDifferent(orig_ending_refs, state.ending_refs)) { if (endingRefsDifferent(orig_ending_refs, state.ending_refs)) {
llvm::outs() << "changed!\n"; llvm::outs() << "changed!\n";
for (auto&& SBB : llvm::successors(&BB)) { for (auto&& SBB : llvm::predecessors(&BB)) {
// llvm::outs() << "reconsidering: " << SBB->getName() << '\n';
orderer.add(SBB); orderer.add(SBB);
} }
} else { } else {
......
...@@ -245,6 +245,9 @@ public: ...@@ -245,6 +245,9 @@ public:
}; };
void dumpPrettyIR(llvm::Function* f) { void dumpPrettyIR(llvm::Function* f) {
//f->getParent()->dump();
//return;
std::unique_ptr<llvm::Module> tmp_module(llvm::CloneModule(f->getParent())); std::unique_ptr<llvm::Module> tmp_module(llvm::CloneModule(f->getParent()));
// std::unique_ptr<llvm::Module> tmp_module(new llvm::Module("tmp", g.context)); // std::unique_ptr<llvm::Module> tmp_module(new llvm::Module("tmp", g.context));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment