Commit b47e2421 authored by Marius Wachtler's avatar Marius Wachtler

Emit PHI nodes in deterministic order to improve the effectiveness of the jit object cache

parent ca7765ac
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#include <set>
#include <sstream> #include <sstream>
#include <stdint.h> #include <stdint.h>
...@@ -632,7 +633,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -632,7 +633,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
} }
std::unordered_set<InternedString> names; std::set<InternedString> names;
for (const auto& s : source->phis->getAllRequiredFor(block)) { for (const auto& s : source->phis->getAllRequiredFor(block)) {
names.insert(s); names.insert(s);
if (source->phis->isPotentiallyUndefinedAfter(s, block->predecessors[0])) { if (source->phis->isPotentiallyUndefinedAfter(s, block->predecessors[0])) {
...@@ -740,9 +741,16 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -740,9 +741,16 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
// And go through and add phi nodes: // And go through and add phi nodes:
ConcreteSymbolTable* pred_st = phi_ending_symbol_tables[pred]; ConcreteSymbolTable* pred_st = phi_ending_symbol_tables[pred];
for (auto it = pred_st->begin(); it != pred_st->end(); ++it) { // We have to sort the phi table by name in order to a get a deterministic ordering for the JIT object
InternedString name = it->first; // cache.
ConcreteCompilerVariable* cv = it->second; // incoming CCV from predecessor block typedef std::pair<InternedString, ConcreteCompilerVariable*> Entry;
std::vector<Entry> sorted_pred_st(pred_st->begin(), pred_st->end());
std::sort(sorted_pred_st.begin(), sorted_pred_st.end(),
[](const Entry& lhs, const Entry& rhs) { return lhs.first < rhs.first; });
for (auto& entry : sorted_pred_st) {
InternedString name = entry.first;
ConcreteCompilerVariable* cv = entry.second; // incoming CCV from predecessor block
// printf("block %d: adding phi for %s from pred %d\n", block->idx, name.c_str(), pred->idx); // printf("block %d: adding phi for %s from pred %d\n", block->idx, name.c_str(), pred->idx);
llvm::PHINode* phi = emitter->getBuilder()->CreatePHI(cv->getType()->llvmType(), llvm::PHINode* phi = emitter->getBuilder()->CreatePHI(cv->getType()->llvmType(),
block->predecessors.size(), name.str()); block->predecessors.size(), name.str());
...@@ -750,7 +758,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -750,7 +758,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
ConcreteCompilerVariable* var = new ConcreteCompilerVariable(cv->getType(), phi, true); ConcreteCompilerVariable* var = new ConcreteCompilerVariable(cv->getType(), phi, true);
generator->giveLocalSymbol(name, var); generator->giveLocalSymbol(name, var);
(*phis)[it->first] = std::make_pair(it->second->getType(), phi); (*phis)[name] = std::make_pair(cv->getType(), phi);
} }
} }
} }
......
...@@ -73,10 +73,11 @@ public: ...@@ -73,10 +73,11 @@ public:
return this->_str == rhs._str; return this->_str == rhs._str;
} }
// This function is slow because it does a string < string comparison and should be avoided.
bool operator<(InternedString rhs) const { bool operator<(InternedString rhs) const {
assert(this->_str); assert(this->_str);
assert(this->pool == rhs.pool); assert(this->pool == rhs.pool);
return this->_str < rhs._str; return *this->_str < *rhs._str;
} }
friend class InternedStringPool; friend class InternedStringPool;
......
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