Commit e904625e authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #453 from undingen/speedup_analysis

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