Commit b3d1f9af authored by Marius Wachtler's avatar Marius Wachtler

Speedup analysis by using llvms more cache friendly map/set algorithms

Should not change the generated output.

for test/integration/django_test.py
us_compiling_analysis_definedness: 130569 --> 29087
us_compiling_analysis_liveness: 132502 --> 102092
us_compiling_analysis_phis: 229944 --> 188633
us_compiling_analysis_types: 214522 --> 36165
parent 59d38882
......@@ -17,6 +17,10 @@
#include <queue>
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "core/cfg.h"
#include "core/common.h"
#include "core/options.h"
......@@ -25,8 +29,8 @@ namespace pyston {
template <typename T> class BBAnalyzer {
public:
typedef std::unordered_map<InternedString, T> Map;
typedef std::unordered_map<CFGBlock*, Map> AllMap;
typedef llvm::DenseMap<InternedString, T> Map;
typedef llvm::DenseMap<CFGBlock*, Map> AllMap;
virtual ~BBAnalyzer() {}
......@@ -49,15 +53,15 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T>&
AllMap starting_states;
AllMap ending_states;
std::unordered_set<CFGBlock*> in_queue;
std::priority_queue<CFGBlock*, std::vector<CFGBlock*>, CFGBlockMinIndex> q;
llvm::SmallPtrSet<CFGBlock*, 32> in_queue;
std::priority_queue<CFGBlock*, llvm::SmallVector<CFGBlock*, 32>, CFGBlockMinIndex> q;
starting_states.insert(make_pair(cfg->getStartingBlock(), Map()));
q.push(cfg->getStartingBlock());
in_queue.insert(cfg->getStartingBlock());
int num_evaluations = 0;
while (q.size()) {
while (!q.empty()) {
num_evaluations++;
CFGBlock* block = q.top();
q.pop();
......@@ -65,7 +69,7 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T>&
Map& initial = starting_states[block];
if (VERBOSITY("analysis") >= 2)
printf("fpc on block %d - %ld entries\n", block->idx, initial.size());
printf("fpc on block %d - %d entries\n", block->idx, initial.size());
Map ending = Map(initial);
......
......@@ -50,10 +50,10 @@ private:
}
};
std::unordered_set<AST_Name*> kills;
std::unordered_map<InternedString, AST_Name*> last_uses;
llvm::DenseSet<AST_Name*> kills;
llvm::DenseMap<InternedString, AST_Name*> last_uses;
std::unordered_map<InternedString, Status> statuses;
llvm::DenseMap<InternedString, Status> statuses;
LivenessAnalysis* analysis;
void _doLoad(InternedString name, AST_Name* node) {
......@@ -178,7 +178,7 @@ bool LivenessAnalysis::isLiveAtEnd(InternedString name, CFGBlock* block) {
return false;
if (!result_cache.count(name)) {
std::unordered_map<CFGBlock*, bool>& map = result_cache[name];
llvm::DenseMap<CFGBlock*, bool>& map = result_cache[name];
// Approach:
// - Find all uses (blocks where the status is USED)
......@@ -376,7 +376,7 @@ DefinednessAnalysis::DefinednessAnalysis(const ParamNames& arg_names, CFG* cfg,
results = computeFixedPoint(cfg, DefinednessBBAnalyzer(cfg, scope_info, arg_names), false);
for (const auto& p : results) {
RequiredSet required;
RequiredSet& required = defined_at_end[p.first];
for (const auto& p2 : p.second) {
ScopeInfo::VarScopeType vst = scope_info->getScopeTypeOfName(p2.first);
if (vst == ScopeInfo::VarScopeType::GLOBAL || vst == ScopeInfo::VarScopeType::NAME)
......@@ -385,7 +385,6 @@ DefinednessAnalysis::DefinednessAnalysis(const ParamNames& arg_names, CFG* cfg,
// printf("%d %s %d\n", p.first->idx, p2.first.c_str(), p2.second);
required.insert(p2.first);
}
defined_at_end.insert(make_pair(p.first, required));
}
static StatCounter us_definedness("us_compiling_analysis_definedness");
......@@ -408,8 +407,7 @@ PhiAnalysis::PhiAnalysis(const ParamNames& arg_names, CFG* cfg, LivenessAnalysis
Timer _t("PhiAnalysis()", 10);
for (CFGBlock* block : cfg->blocks) {
RequiredSet required;
RequiredSet& required = required_phis[block];
if (block->predecessors.size() > 1) {
for (CFGBlock* pred : block->predecessors) {
const RequiredSet& defined = definedness.getDefinedNamesAtEnd(pred);
......@@ -422,8 +420,6 @@ PhiAnalysis::PhiAnalysis(const ParamNames& arg_names, CFG* cfg, LivenessAnalysis
}
}
}
required_phis.insert(make_pair(block, std::move(required)));
}
static StatCounter us_phis("us_compiling_analysis_phis");
......
......@@ -16,8 +16,9 @@
#define PYSTON_ANALYSIS_FUNCTIONANALYSIS_H
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "core/stringpool.h"
#include "core/types.h"
......@@ -37,10 +38,10 @@ private:
CFG* cfg;
friend class LivenessBBVisitor;
typedef std::unordered_map<CFGBlock*, std::unique_ptr<LivenessBBVisitor>> LivenessCacheMap;
typedef llvm::DenseMap<CFGBlock*, std::unique_ptr<LivenessBBVisitor>> LivenessCacheMap;
LivenessCacheMap liveness_cache;
std::unordered_map<InternedString, std::unordered_map<CFGBlock*, bool>> result_cache;
llvm::DenseMap<InternedString, llvm::DenseMap<CFGBlock*, bool>> result_cache;
public:
LivenessAnalysis(CFG* cfg);
......@@ -58,11 +59,11 @@ public:
PotentiallyDefined,
Defined,
};
typedef std::unordered_set<InternedString> RequiredSet;
typedef llvm::DenseSet<InternedString> RequiredSet;
private:
std::unordered_map<CFGBlock*, std::unordered_map<InternedString, DefinitionLevel>> results;
std::unordered_map<CFGBlock*, const RequiredSet> defined_at_end;
llvm::DenseMap<CFGBlock*, llvm::DenseMap<InternedString, DefinitionLevel>> results;
llvm::DenseMap<CFGBlock*, RequiredSet> defined_at_end;
ScopeInfo* scope_info;
public:
......@@ -73,13 +74,13 @@ public:
};
class PhiAnalysis {
public:
typedef std::unordered_set<InternedString> RequiredSet;
typedef llvm::DenseSet<InternedString> RequiredSet;
DefinednessAnalysis definedness;
private:
LivenessAnalysis* liveness;
std::unordered_map<CFGBlock*, const RequiredSet> required_phis;
llvm::DenseMap<CFGBlock*, RequiredSet> required_phis;
public:
PhiAnalysis(const ParamNames&, CFG* cfg, LivenessAnalysis* liveness, ScopeInfo* scope_info);
......
......@@ -18,6 +18,8 @@
#include <deque>
#include <unordered_set>
#include "llvm/ADT/SmallPtrSet.h"
#include "analysis/fpc.h"
#include "analysis/scoping_analysis.h"
#include "codegen/codegen.h"
......@@ -78,10 +80,10 @@ static BoxedClass* simpleCallSpeculation(AST_Call* node, CompilerType* rtn_type,
return NULL;
}
typedef std::unordered_map<InternedString, CompilerType*> TypeMap;
typedef std::unordered_map<CFGBlock*, TypeMap> AllTypeMap;
typedef std::unordered_map<AST_expr*, CompilerType*> ExprTypeMap;
typedef std::unordered_map<AST_expr*, BoxedClass*> TypeSpeculations;
typedef llvm::DenseMap<InternedString, CompilerType*> TypeMap;
typedef llvm::DenseMap<CFGBlock*, TypeMap> AllTypeMap;
typedef llvm::DenseMap<AST_expr*, CompilerType*> ExprTypeMap;
typedef llvm::DenseMap<AST_expr*, BoxedClass*> TypeSpeculations;
class BasicBlockTypePropagator : public ExprVisitor, public StmtVisitor {
private:
static const bool EXPAND_UNNEEDED = true;
......@@ -641,11 +643,12 @@ private:
}
public:
static void propagate(CFGBlock* block, const TypeMap& starting, TypeMap& ending, ExprTypeMap& expr_types,
TypeSpeculations& type_speculations, TypeAnalysis::SpeculationLevel speculation,
ScopeInfo* scope_info) {
ending.insert(starting.begin(), starting.end());
static TypeMap propagate(CFGBlock* block, const TypeMap& starting, ExprTypeMap& expr_types,
TypeSpeculations& type_speculations, TypeAnalysis::SpeculationLevel speculation,
ScopeInfo* scope_info) {
TypeMap ending = starting;
BasicBlockTypePropagator(block, ending, expr_types, type_speculations, speculation, scope_info).run();
return ending;
}
};
......@@ -711,9 +714,9 @@ public:
static bool merge(const TypeMap& ending, TypeMap& next) {
bool changed = false;
for (TypeMap::const_iterator it = ending.begin(); it != ending.end(); ++it) {
CompilerType*& prev = next[it->first];
changed = merge(it->second, prev) || changed;
for (auto&& entry : ending) {
CompilerType*& prev = next[entry.first];
changed = merge(entry.second, prev) || changed;
}
return changed;
}
......@@ -726,8 +729,8 @@ public:
ExprTypeMap expr_types;
TypeSpeculations type_speculations;
std::unordered_set<CFGBlock*> in_queue;
std::priority_queue<CFGBlock*, std::vector<CFGBlock*>, CFGBlockMinIndex> queue;
llvm::SmallPtrSet<CFGBlock*, 32> in_queue;
std::priority_queue<CFGBlock*, llvm::SmallVector<CFGBlock*, 32>, CFGBlockMinIndex> queue;
starting_types[initial_block] = std::move(initial_types);
queue.push(initial_block);
......@@ -735,13 +738,12 @@ public:
int num_evaluations = 0;
while (!queue.empty()) {
ASSERT(queue.size() == in_queue.size(), "%ld %ld", queue.size(), in_queue.size());
ASSERT(queue.size() == in_queue.size(), "%ld %d", queue.size(), in_queue.size());
num_evaluations++;
CFGBlock* block = queue.top();
queue.pop();
in_queue.erase(block);
TypeMap ending;
if (VERBOSITY("types") >= 3) {
printf("processing types for block %d\n", block->idx);
......@@ -755,8 +757,8 @@ public:
}
}
BasicBlockTypePropagator::propagate(block, starting_types[block], ending, expr_types, type_speculations,
speculation, scope_info);
TypeMap ending = BasicBlockTypePropagator::propagate(block, starting_types[block], expr_types,
type_speculations, speculation, scope_info);
if (VERBOSITY("types") >= 3) {
printf("before (after):\n");
......
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