diff --git a/emscripten-version.txt b/emscripten-version.txt index 7b4009ac531..3f5f9c3ae64 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.32.0 +1.32.1 diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index 1fade5ea929..018f4181387 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -160,9 +160,11 @@ namespace { FunctionTableMap FunctionTables; // sig => list of functions std::vector<std::string> GlobalInitializers; std::vector<std::string> Exports; // additional exports + StringMap Aliases; BlockAddressMap BlockAddresses; NameIntMap AsmConsts; IntSet AsmConstArities; + NameSet BlockRelocatableExterns; // which externals are accessed in this block; we load them once at the beginning (avoids a potential call in a heap access, and might be faster) std::string CantValidate; bool UsesSIMD; @@ -382,6 +384,7 @@ namespace { // All postsets are of external values, so they are pointers, hence 32-bit std::string Name = getOpName(V); Externals.insert(Name); + if (Relocatable) Name = "g$" + Name + "() | 0"; // we access linked externs through calls PostSets += "\n HEAP32[" + relocateGlobal(utostr(AbsoluteTarget)) + " >> 2] = " + Name + ';'; return 0; // emit zero in there for now, until the postSet } else if (Relocatable) { @@ -1093,6 +1096,11 @@ std::string JSWriter::getConstant(const Constant* CV, AsmCast sign) { if (GV->isDeclaration()) { std::string Name = getOpName(GV); Externals.insert(Name); + if (Relocatable) { + // we access linked externs through calls, which we load at the beginning of basic blocks + BlockRelocatableExterns.insert(Name); + Name = "t$" + Name; + } return Name; } if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(CV)) { @@ -2283,6 +2291,18 @@ void JSWriter::addBlock(const BasicBlock *BB, Relooper& R, LLVMToRelooperMap& LL } } CodeStream.flush(); + if (Relocatable) { + // add code to load externals once at the beginning + if (BlockRelocatableExterns.size() > 0) { + for (auto& RE : BlockRelocatableExterns) { + std::string Temp = "t$" + RE; + std::string Call = "g$" + RE; + UsedVars[Temp] = Type::getInt32Ty(BB->getContext()); + Code = Temp + " = " + Call + "() | 0; " + Code; + } + BlockRelocatableExterns.clear(); + } + } const Value* Condition = considerConditionVar(BB->getTerminator()); Block *Curr = new Block(Code.c_str(), Condition ? getValueAsCastStr(Condition).c_str() : NULL); LLVMToRelooper[BB] = Curr; @@ -2565,6 +2585,16 @@ void JSWriter::printFunction(const Function *F) { void JSWriter::printModuleBody() { processConstants(); + if (Relocatable) { + for (Module::const_alias_iterator I = TheModule->alias_begin(), E = TheModule->alias_end(); + I != E; ++I) { + if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(I)) { + const Value* Target = resolveFully(GA); + Aliases[getJSName(GA)] = getJSName(Target); + } + } + } + // Emit function bodies. nl(Out) << "// EMSCRIPTEN_START_FUNCTIONS"; nl(Out); for (Module::const_iterator I = TheModule->begin(), E = TheModule->end(); @@ -2726,6 +2756,19 @@ void JSWriter::printModuleBody() { } Out << "],"; + Out << "\"aliases\": {"; + first = true; + for (StringMap::const_iterator I = Aliases.begin(), E = Aliases.end(); + I != E; ++I) { + if (first) { + first = false; + } else { + Out << ", "; + } + Out << "\"" << I->first << "\": \"" << I->second << "\""; + } + Out << "},"; + Out << "\"cantValidate\": \"" << CantValidate << "\","; Out << "\"simd\": ";