diff --git a/emscripten-version.txt b/emscripten-version.txt index f2c16746929..1a90c51133d 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.23.1 +1.23.2 diff --git a/lib/Target/JSBackend/AllocaManager.cpp b/lib/Target/JSBackend/AllocaManager.cpp index 2218732a25f..267f2e7db5c 100644 --- a/lib/Target/JSBackend/AllocaManager.cpp +++ b/lib/Target/JSBackend/AllocaManager.cpp @@ -40,8 +40,10 @@ uint64_t AllocaManager::getSize(const AllocaInst *AI) { // Return the alignment of the given alloca. unsigned AllocaManager::getAlignment(const AllocaInst *AI) { assert(AI->isStaticAlloca()); - return std::max(AI->getAlignment(), - DL->getABITypeAlignment(AI->getAllocatedType())); + unsigned Alignment = std::max(AI->getAlignment(), + DL->getABITypeAlignment(AI->getAllocatedType())); + MaxAlignment = std::max(Alignment, MaxAlignment); + return Alignment; } AllocaManager::AllocaInfo AllocaManager::getInfo(const AllocaInst *AI) { @@ -452,7 +454,7 @@ void AllocaManager::computeFrameOffsets() { "Statically allocated frame size is " << FrameSize << "\n"); } -AllocaManager::AllocaManager() { +AllocaManager::AllocaManager() : MaxAlignment(0) { } void AllocaManager::analyze(const Function &Func, const DataLayout &Layout, diff --git a/lib/Target/JSBackend/AllocaManager.h b/lib/Target/JSBackend/AllocaManager.h index fc2a7998a2e..e85a96f8767 100644 --- a/lib/Target/JSBackend/AllocaManager.h +++ b/lib/Target/JSBackend/AllocaManager.h @@ -142,6 +142,8 @@ class AllocaManager { void computeRepresentatives(); void computeFrameOffsets(); + unsigned MaxAlignment; + public: AllocaManager(); @@ -166,6 +168,9 @@ class AllocaManager { /// Return the total frame size for all static allocas and associated padding. uint64_t getFrameSize() const { return FrameSize; } + + /// Return the largest alignment seen. + unsigned getMaxAlignment() const { return MaxAlignment; } }; } // namespace llvm diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index bcfadc8e231..098d8372627 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -212,7 +212,7 @@ DEF_CALL_HANDLER(emscripten_get_async_return_value_addr, { // emscripten instrinsics DEF_CALL_HANDLER(emscripten_debugger, { - CanValidate = false; + CantValidate = "emscripten_debugger is used"; return "debugger"; }) diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index 97b7d5f193f..90b973063ac 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -149,7 +149,7 @@ namespace { std::vector Exports; // additional exports BlockAddressMap BlockAddresses; - bool CanValidate; + std::string CantValidate; bool UsesSIMD; int InvokeState; // cycles between 0, 1 after preInvoke, 2 after call, 0 again after postInvoke. hackish, no argument there. CodeGenOpt::Level OptLevel; @@ -160,7 +160,7 @@ namespace { public: static char ID; JSWriter(formatted_raw_ostream &o, CodeGenOpt::Level OptLevel) - : ModulePass(ID), Out(o), UniqueNum(0), NextFunctionIndex(0), CanValidate(true), UsesSIMD(false), InvokeState(0), + : ModulePass(ID), Out(o), UniqueNum(0), NextFunctionIndex(0), CantValidate(""), UsesSIMD(false), InvokeState(0), OptLevel(OptLevel) {} virtual const char *getPassName() const { return "JavaScript backend"; } @@ -371,7 +371,7 @@ namespace { assert(VT->getElementType()->getPrimitiveSizeInBits() == 32); assert(VT->getNumElements() == 4); UsesSIMD = true; - CanValidate = false; + CantValidate = "SIMD types in use"; } std::string ensureCast(std::string S, Type *T, AsmCast sign) { @@ -1456,10 +1456,14 @@ void JSWriter::generateExpression(const User *I, raw_string_ostream& Code) { if (AI->isStaticAlloca()) { uint64_t Offset; if (Allocas.getFrameOffset(AI, &Offset)) { - if (Offset != 0) { - Code << getAssign(AI) << "sp + " << Offset << "|0"; + Code << getAssign(AI); + if (Allocas.getMaxAlignment() <= STACK_ALIGN) { + Code << "sp"; } else { - Code << getAssign(AI) << "sp"; + Code << "sp_a"; // aligned base of stack is different, use that + } + if (Offset != 0) { + Code << " + " << Offset << "|0"; } break; } @@ -1468,6 +1472,8 @@ void JSWriter::generateExpression(const User *I, raw_string_ostream& Code) { return; } + assert(AI->getAlignment() <= STACK_ALIGN); // TODO + Type *T = AI->getAllocatedType(); std::string Size; uint64_t BaseSize = DL->getTypeAllocSize(T); @@ -1822,6 +1828,10 @@ void JSWriter::printFunctionBody(const Function *F) { // Emit local variables UsedVars["sp"] = Type::IntegerTyID; + unsigned MaxAlignment = Allocas.getMaxAlignment(); + if (MaxAlignment > STACK_ALIGN) { + UsedVars["sp_a"] = Type::IntegerTyID; + } UsedVars["label"] = Type::IntegerTyID; if (!UsedVars.empty()) { unsigned Count = 0; @@ -1864,6 +1874,11 @@ void JSWriter::printFunctionBody(const Function *F) { // Emit stack entry Out << " " << getAdHocAssign("sp", Type::getInt32Ty(F->getContext())) << "STACKTOP;"; if (uint64_t FrameSize = Allocas.getFrameSize()) { + if (MaxAlignment > STACK_ALIGN) { + // We must align this entire stack frame to something higher than the default + Out << "\n "; + Out << "sp_a = STACKTOP = (STACKTOP + " << utostr(MaxAlignment-1) << ")&-" << utostr(MaxAlignment) << ";"; + } Out << "\n "; Out << getStackBump(FrameSize); } @@ -2104,9 +2119,7 @@ void JSWriter::printModuleBody() { } Out << "],"; - Out << "\"canValidate\": "; - Out << (CanValidate ? "1" : "0"); - Out << ","; + Out << "\"cantValidate\": \"" << CantValidate << "\","; Out << "\"simd\": "; Out << (UsesSIMD ? "1" : "0");