Commit cb1be9c4 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #454 from kmod/jit_cache_misses

Jit cache misses
parents e904625e 75e90214
...@@ -675,17 +675,10 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info, ...@@ -675,17 +675,10 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
else else
func = g.funcs.callattrN; func = g.funcs.callattrN;
union {
CallattrFlags flags;
char value;
} flags_to_int;
static_assert(sizeof(CallattrFlags) == sizeof(char), "");
flags_to_int.flags = flags;
std::vector<llvm::Value*> other_args; std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue()); other_args.push_back(var->getValue());
other_args.push_back(embedRelocatablePtr(attr, g.llvm_str_type_ptr)); other_args.push_back(embedRelocatablePtr(attr, g.llvm_str_type_ptr));
other_args.push_back(getConstantInt(flags_to_int.value, g.i8)); other_args.push_back(getConstantInt(flags.asInt(), g.i8));
llvm::Value* llvm_argspec = llvm::ConstantInt::get(g.i32, argspec.asInt(), false); llvm::Value* llvm_argspec = llvm::ConstantInt::get(g.i32, argspec.asInt(), false);
other_args.push_back(llvm_argspec); other_args.push_back(llvm_argspec);
......
...@@ -282,10 +282,12 @@ public: ...@@ -282,10 +282,12 @@ public:
M->print(sstr, 0); M->print(sstr, 0);
sstr.flush(); sstr.flush();
llvm::sys::fs::create_directories(cache_dir.str());
std::string filename = cache_dir.str().str() + "/" + module_identifier + "_first.ll"; std::string filename = cache_dir.str().str() + "/" + module_identifier + "_first.ll";
if (llvm::sys::fs::exists(filename)) if (llvm::sys::fs::exists(filename))
filename = cache_dir.str().str() + "/" + module_identifier + "_second.ll"; filename = cache_dir.str().str() + "/" + module_identifier + "_second.ll";
FILE* f = fopen(filename.c_str(), "wt"); FILE* f = fopen(filename.c_str(), "wt");
ASSERT(f, "%s", strerror(errno));
fwrite(llvm_ir.c_str(), 1, llvm_ir.size(), f); fwrite(llvm_ir.c_str(), 1, llvm_ir.size(), f);
fclose(f); fclose(f);
#endif #endif
......
...@@ -2262,57 +2262,47 @@ private: ...@@ -2262,57 +2262,47 @@ private:
SourceInfo* source = irstate->getSourceInfo(); SourceInfo* source = irstate->getSourceInfo();
ScopeInfo* scope_info = irstate->getScopeInfo(); ScopeInfo* scope_info = irstate->getScopeInfo();
// Additional names to remove; remove them after iteration is done to not mess up the iterators // Sort the names here to make the process deterministic:
std::vector<InternedString> also_remove; std::map<InternedString, CompilerVariable*> sorted_symbol_table(symbol_table.begin(), symbol_table.end());
for (auto it = symbol_table.begin(); it != symbol_table.end();) { for (const auto& p : sorted_symbol_table) {
assert(it->first.str() != FRAME_INFO_PTR_NAME); assert(p.first.str() != FRAME_INFO_PTR_NAME);
if (allowableFakeEndingSymbol(it->first)) { if (allowableFakeEndingSymbol(p.first))
++it;
continue; continue;
}
// ASSERT(it->first[0] != '!' || isIsDefinedName(it->first), "left a fake variable in the real // ASSERT(p.first[0] != '!' || isIsDefinedName(p.first), "left a fake variable in the real
// symbol table? '%s'", it->first.c_str()); // symbol table? '%s'", p.first.c_str());
if (!source->liveness->isLiveAtEnd(it->first, myblock)) { if (!source->liveness->isLiveAtEnd(p.first, myblock)) {
// printf("%s dead at end of %d; grabbed = %d, %d vrefs\n", it->first.c_str(), myblock->idx, // printf("%s dead at end of %d; grabbed = %d, %d vrefs\n", p.first.c_str(), myblock->idx,
// it->second->isGrabbed(), it->second->getVrefs()); // p.second->isGrabbed(), p.second->getVrefs());
also_remove.push_back(getIsDefinedName(it->first));
p.second->decvref(emitter);
it->second->decvref(emitter); symbol_table.erase(getIsDefinedName(p.first));
it = symbol_table.erase(it); symbol_table.erase(p.first);
} else if (source->phis->isRequiredAfter(it->first, myblock)) { } else if (source->phis->isRequiredAfter(p.first, myblock)) {
assert(scope_info->getScopeTypeOfName(it->first) != ScopeInfo::VarScopeType::GLOBAL); assert(scope_info->getScopeTypeOfName(p.first) != ScopeInfo::VarScopeType::GLOBAL);
ConcreteCompilerType* phi_type = types->getTypeAtBlockEnd(it->first, myblock); ConcreteCompilerType* phi_type = types->getTypeAtBlockEnd(p.first, myblock);
// printf("Converting %s from %s to %s\n", it->first.c_str(), // printf("Converting %s from %s to %s\n", p.first.c_str(),
// it->second->getType()->debugName().c_str(), phi_type->debugName().c_str()); // p.second->getType()->debugName().c_str(), phi_type->debugName().c_str());
// printf("have to convert %s from %s to %s\n", it->first.c_str(), // printf("have to convert %s from %s to %s\n", p.first.c_str(),
// it->second->getType()->debugName().c_str(), phi_type->debugName().c_str()); // p.second->getType()->debugName().c_str(), phi_type->debugName().c_str());
ConcreteCompilerVariable* v = it->second->makeConverted(emitter, phi_type); ConcreteCompilerVariable* v = p.second->makeConverted(emitter, phi_type);
it->second->decvref(emitter); p.second->decvref(emitter);
symbol_table[it->first] = v->split(emitter); symbol_table[p.first] = v->split(emitter);
++it;
} else { } else {
#ifndef NDEBUG #ifndef NDEBUG
if (myblock->successors.size()) { if (myblock->successors.size()) {
// TODO getTypeAtBlockEnd will automatically convert up to the concrete type, which we don't // TODO getTypeAtBlockEnd will automatically convert up to the concrete type, which we don't
// want // want
// here, but this is just for debugging so I guess let it happen for now: // here, but this is just for debugging so I guess let it happen for now:
ConcreteCompilerType* ending_type = types->getTypeAtBlockEnd(it->first, myblock); ConcreteCompilerType* ending_type = types->getTypeAtBlockEnd(p.first, myblock);
ASSERT(it->second->canConvertTo(ending_type), "%s is supposed to be %s, but somehow is %s", ASSERT(p.second->canConvertTo(ending_type), "%s is supposed to be %s, but somehow is %s",
it->first.c_str(), ending_type->debugName().c_str(), p.first.c_str(), ending_type->debugName().c_str(), p.second->getType()->debugName().c_str());
it->second->getType()->debugName().c_str());
} }
#endif #endif
++it;
} }
} }
for (const auto& s : also_remove) {
symbol_table.erase(s);
}
const PhiAnalysis::RequiredSet& all_phis = source->phis->getAllRequiredAfter(myblock); const PhiAnalysis::RequiredSet& all_phis = source->phis->getAllRequiredAfter(myblock);
for (PhiAnalysis::RequiredSet::const_iterator it = all_phis.begin(), end = all_phis.end(); it != end; ++it) { for (PhiAnalysis::RequiredSet::const_iterator it = all_phis.begin(), end = all_phis.end(); it != end; ++it) {
// printf("phi will be required for %s\n", it->c_str()); // printf("phi will be required for %s\n", it->c_str());
......
...@@ -586,6 +586,8 @@ struct FrameInfo { ...@@ -586,6 +586,8 @@ struct FrameInfo {
struct CallattrFlags { struct CallattrFlags {
bool cls_only : 1; bool cls_only : 1;
bool null_on_nonexistent : 1; bool null_on_nonexistent : 1;
char asInt() { return (cls_only << 0) + (null_on_nonexistent << 1); }
}; };
} }
......
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