Commit 08704150 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Only allow getName for vregs that we will give names

ie don't allow calling it for ones where multiple names
will reuse the same vreg
parent 31f263f2
...@@ -397,9 +397,11 @@ void DefinednessAnalysis::run(VRegMap<DefinednessAnalysis::DefinitionLevel> init ...@@ -397,9 +397,11 @@ void DefinednessAnalysis::run(VRegMap<DefinednessAnalysis::DefinitionLevel> init
for (int vreg = 0; vreg < nvregs; vreg++) { for (int vreg = 0; vreg < nvregs; vreg++) {
#ifndef NDEBUG #ifndef NDEBUG
ScopeInfo::VarScopeType vst = scope_info->getScopeTypeOfName(vreg_info.getName(vreg)); if (vreg_info.vregHasName(vreg)) {
ASSERT(vst != ScopeInfo::VarScopeType::GLOBAL && vst != ScopeInfo::VarScopeType::NAME, "%s", ScopeInfo::VarScopeType vst = scope_info->getScopeTypeOfName(vreg_info.getName(vreg));
vreg_info.getName(vreg).c_str()); ASSERT(vst != ScopeInfo::VarScopeType::GLOBAL && vst != ScopeInfo::VarScopeType::NAME, "%s",
vreg_info.getName(vreg).c_str());
}
#endif #endif
auto status = p.second[vreg]; auto status = p.second[vreg];
......
...@@ -2679,8 +2679,9 @@ private: ...@@ -2679,8 +2679,9 @@ private:
popDefinedVar(vreg, true); popDefinedVar(vreg, true);
symbol_table[vreg] = NULL; symbol_table[vreg] = NULL;
} else if (irstate->getPhis()->isRequiredAfter(vreg, myblock)) { } else if (irstate->getPhis()->isRequiredAfter(vreg, myblock)) {
assert(scope_info->getScopeTypeOfName(cfg->getVRegInfo().getName(vreg)) assert(!cfg->getVRegInfo().vregHasName(vreg)
!= ScopeInfo::VarScopeType::GLOBAL); || scope_info->getScopeTypeOfName(cfg->getVRegInfo().getName(vreg))
!= ScopeInfo::VarScopeType::GLOBAL);
ConcreteCompilerType* phi_type = types->getTypeAtBlockEnd(vreg, myblock); ConcreteCompilerType* phi_type = types->getTypeAtBlockEnd(vreg, myblock);
assert(phi_type->isUsable()); assert(phi_type->isUsable());
// printf("Converting %s from %s to %s\n", p.first.c_str(), // printf("Converting %s from %s to %s\n", p.first.c_str(),
...@@ -3024,8 +3025,12 @@ public: ...@@ -3024,8 +3025,12 @@ public:
auto&& vregs = block->cfg->getVRegInfo(); auto&& vregs = block->cfg->getVRegInfo();
if (VERBOSITY("irgenerator") >= 2) { // print starting symbol table if (VERBOSITY("irgenerator") >= 2) { // print starting symbol table
printf(" %d init:", block->idx); printf(" %d init:", block->idx);
for (auto it = symbol_table.begin(); it != symbol_table.end(); ++it) for (auto it = symbol_table.begin(); it != symbol_table.end(); ++it) {
printf(" %s", vregs.getName(it.first()).c_str()); if (vregs.vregHasName(it.first()))
printf(" %s", vregs.getName(it.first()).c_str());
else
printf(" <v%d>", it.first());
}
printf("\n"); printf("\n");
} }
for (int i = 0; i < block->body.size(); i++) { for (int i = 0; i < block->body.size(); i++) {
...@@ -3044,7 +3049,10 @@ public: ...@@ -3044,7 +3049,10 @@ public:
if (VERBOSITY("irgenerator") >= 2) { // print ending symbol table if (VERBOSITY("irgenerator") >= 2) { // print ending symbol table
printf(" %d fini:", block->idx); printf(" %d fini:", block->idx);
for (auto it = symbol_table.begin(); it != symbol_table.end(); ++it) for (auto it = symbol_table.begin(); it != symbol_table.end(); ++it)
printf(" %s", vregs.getName(it.first()).c_str()); if (vregs.vregHasName(it.first()))
printf(" %s", vregs.getName(it.first()).c_str());
else
printf(" <v%d>", it.first());
printf("\n"); printf("\n");
} }
} }
......
...@@ -2756,20 +2756,18 @@ public: ...@@ -2756,20 +2756,18 @@ public:
auto it = sym_vreg_map.find(id); auto it = sym_vreg_map.find(id);
if (sym_vreg_map.end() == it) { if (sym_vreg_map.end() == it) {
ASSERT(next_vreg == sym_vreg_map.size(), "%d %d", next_vreg, sym_vreg_map.size()); ASSERT(next_vreg == sym_vreg_map.size(), "%d %d", next_vreg, sym_vreg_map.size());
assert(next_vreg == vreg_sym_map.size());
sym_vreg_map[id] = next_vreg; sym_vreg_map[id] = next_vreg;
vreg_sym_map.push_back(id);
if (!REUSE_VREGS || step == UserVisible || step == CrossBlock) {
assert(next_vreg == vreg_sym_map.size());
vreg_sym_map.push_back(id);
}
return next_vreg++; return next_vreg++;
} }
return it->second; return it->second;
} }
}; };
// XXX temporarily disable vreg reuse, since for the transition we want to make it very
// easy to convert between vregs and names.
#define REUSE_VREGS 0
void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names, ScopeInfo* scope_info) { void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names, ScopeInfo* scope_info) {
assert(!hasVRegsAssigned()); assert(!hasVRegsAssigned());
...@@ -2813,6 +2811,9 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names, ScopeInfo* s ...@@ -2813,6 +2811,9 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names, ScopeInfo* s
sym_vreg_map = std::move(visitor.sym_vreg_map); sym_vreg_map = std::move(visitor.sym_vreg_map);
vreg_sym_map = std::move(visitor.vreg_sym_map); vreg_sym_map = std::move(visitor.vreg_sym_map);
assert(hasVRegsAssigned()); assert(hasVRegsAssigned());
#if REUSE_VREGS
assert(vreg_sym_map.size() == num_vregs_cross_block);
#endif
} }
CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body, const ParamNames& param_names) { CFG* computeCFG(SourceInfo* source, std::vector<AST_stmt*> body, const ParamNames& param_names) {
......
...@@ -109,6 +109,7 @@ private: ...@@ -109,6 +109,7 @@ private:
llvm::DenseMap<InternedString, DefaultedInt<-1>> sym_vreg_map; llvm::DenseMap<InternedString, DefaultedInt<-1>> sym_vreg_map;
// Reverse map, from vreg->symbol name. // Reverse map, from vreg->symbol name.
// Entries won't exist for all vregs
std::vector<InternedString> vreg_sym_map; std::vector<InternedString> vreg_sym_map;
int num_vregs_cross_block = -1; int num_vregs_cross_block = -1;
...@@ -131,9 +132,19 @@ public: ...@@ -131,9 +132,19 @@ public:
return it->second; return it->second;
} }
// Not all vregs correspond to a name; many are our compiler-generated variables.
bool vregHasName(int vreg) const { return vreg < num_vregs_cross_block; }
// XXX temporarily disable vreg reuse, since for the transition we want to make it very
// easy to convert between vregs and names.
#define REUSE_VREGS 0
InternedString getName(int vreg) const { InternedString getName(int vreg) const {
assert(hasVRegsAssigned()); assert(hasVRegsAssigned());
assert(vreg >= 0 && vreg < num_vregs); assert(vreg >= 0 && vreg < num_vregs);
#if REUSE_VREGS
assert(vregHasName(vreg));
#endif
return vreg_sym_map[vreg]; return vreg_sym_map[vreg];
} }
......
# skip-if: '-O' in EXTRA_JIT_ARGS or '-n' in EXTRA_JIT_ARGS
# statcheck: noninit_count('num_deopt') == 2
try:
import __pyston__
__pyston__.setOption("OSR_THRESHOLD_BASELINE", 50)
__pyston__.setOption("REOPT_THRESHOLD_BASELINE", 50)
__pyston__.setOption("SPECULATION_THRESHOLD", 10)
except ImportError:
pass
def triggers_deopt(x):
if x < 90:
return ""
return unicode("")
class C():
def f(self, x, b):
if b and x < 90:
y = 1
triggers_deopt(x).isalnum
try:
print y
assert b
except UnboundLocalError as e:
print e
c = C()
for i in range(91):
c.f(i, True)
c = C()
for i in range(91):
c.f(i, False)
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