From a4ebfbfc0c529f12d0ec672653c23f9cd98ab6d0 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 1 Dec 2015 09:59:15 -0800 Subject: [PATCH 01/10] stop emitting Atomics.fence which is no longer in the SAB spec --- lib/Target/JSBackend/CallHandlers.h | 4 +++- lib/Target/JSBackend/JSBackend.cpp | 6 +----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index 3105af7cee9..9825047f936 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -888,7 +888,9 @@ DEF_BUILTIN_HANDLER(emscripten_int32x4_not, SIMD_Int32x4_not); DEF_BUILTIN_HANDLER(emscripten_int32x4_and, SIMD_Int32x4_and); DEF_BUILTIN_HANDLER(emscripten_int32x4_or, SIMD_Int32x4_or); DEF_BUILTIN_HANDLER(emscripten_int32x4_xor, SIMD_Int32x4_xor); -DEF_BUILTIN_HANDLER(emscripten_atomic_fence, Atomics_fence); +DEF_CALL_HANDLER(emscripten_atomic_fence, { + return "/* fence */"; +}) DEF_CALL_HANDLER(emscripten_float32x4_select, { // FIXME: We really need a more general way of handling boolean types, diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index bb48ce7003c..273337e2d5d 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -2662,11 +2662,7 @@ void JSWriter::generateExpression(const User *I, raw_string_ostream& Code) { break; } case Instruction::Fence: - if (EnablePthreads) { - Code << "Atomics_fence()"; - } else { - Code << "/* fence */"; // no threads, so nothing to do here - } + Code << "/* fence */"; // not in the spec currently, so nothing to do here break; } From a7975f1a6493c8eb867f57366b5b1a4dfc122a81 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 2 Dec 2015 20:32:21 -0800 Subject: [PATCH 02/10] support replacing functions in SimplifyStructRegSignatures whose address is taken --- lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp index b9cccbdb5fa..192386a68eb 100644 --- a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp +++ b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp @@ -513,6 +513,13 @@ bool SimplifyStructRegSignatures::runOnModule(Module &M) { fixCallSite(Ctx, InvokeToFix, PreferredAlignment); } + // Update taking of a function's address + for (auto &Old : FunctionsToDelete) { + Function *New = FunctionMap[Old]; + assert(New); + Old->replaceAllUsesWith(New); + } + // Delete leftover functions - the ones with old signatures. for (auto &ToDelete : FunctionsToDelete) { ToDelete->eraseFromParent(); From 07e9d11b6ed3655bf72195ef0bcac6db80022d2f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 3 Dec 2015 11:07:00 -0800 Subject: [PATCH 03/10] be more careful when fixing function pointers in SimplifyStructRegSignatures, we need the types to always be consistent, so llvm assertions are not triggered --- .../NaCl/SimplifyStructRegSignatures.cpp | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp index 192386a68eb..3159df5a37f 100644 --- a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp +++ b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp @@ -128,6 +128,13 @@ class SimplifyStructRegSignatures : public ModulePass { SetVector InvokesToPatch; DenseMap FunctionMap; + struct FunctionAddressing { + Value *Temp; + Function *Old; + FunctionAddressing(Value *Temp, Function *Old) : Temp(Temp), Old(Old) {} + }; + std::vector FunctionAddressings; + bool simplifyFunction(LLVMContext &Ctx, Function *OldFunc); @@ -355,7 +362,7 @@ TCall *SimplifyStructRegSignatures::fixCallTargetAndArguments( Value *OldArg = OldArgUse; Type *OldArgType = OldArg->getType(); unsigned NewArgPos = OldArgUse.getOperandNo() + argOffset; - Type *NewArgType = NewType->getFunctionParamType(NewArgPos); + Type *NewArgType = NewArgPos < VarargMark ? NewType->getFunctionParamType(NewArgPos) : nullptr; if (OldArgType != NewArgType && OldArgType->isAggregateType()) { if (NewArgPos >= VarargMark) { @@ -369,6 +376,13 @@ TCall *SimplifyStructRegSignatures::fixCallTargetAndArguments( Builder.CreateStore(OldArg, Alloca); ByRefPlaces.insert(NewArgPos); NewArgs.push_back(Alloca); + } else if (NewArgType && OldArgType != NewArgType && isa(OldArg)) { + // If a function pointer has a changed type due to struct reg changes, it will still have + // the wrong type here, since we may have not changed that method yet. We'll fix it up + // later, and meanwhile place an undef of the right type in that slot. + Value *Temp = UndefValue::get(NewArgType); + FunctionAddressings.emplace_back(Temp, cast(OldArg)); + NewArgs.push_back(Temp); } else { NewArgs.push_back(OldArg); } @@ -514,10 +528,12 @@ bool SimplifyStructRegSignatures::runOnModule(Module &M) { } // Update taking of a function's address - for (auto &Old : FunctionsToDelete) { + for (auto &Addressing : FunctionAddressings) { + Value *Temp = Addressing.Temp; + Function *Old = Addressing.Old; Function *New = FunctionMap[Old]; assert(New); - Old->replaceAllUsesWith(New); + Temp->replaceAllUsesWith(New); } // Delete leftover functions - the ones with old signatures. From adba5d12eaa6c9e3fa1e11562c4247d4bc657f17 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 3 Dec 2015 12:40:01 -0800 Subject: [PATCH 04/10] handle function pointers in SimplifyStructRegSignatures --- .../JSBackend/NaCl/SimplifyStructRegSignatures.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp index 3159df5a37f..664383e89fa 100644 --- a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp +++ b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp @@ -388,6 +388,16 @@ TCall *SimplifyStructRegSignatures::fixCallTargetAndArguments( } } + if (isa(NewTarget)) { + Type* NewPointerType = PointerType::get(NewType, 0); + if (NewPointerType != OldCall->getType()) { + // This is a function pointer, and it has the wrong type after our + // changes. Bitcast it. + NewTarget = Builder.CreateBitCast(NewTarget, NewPointerType, ".casttarget"); + } + } + + ArrayRef ArrRef = NewArgs; TCall *NewCall = CreateCallFrom(OldCall, NewTarget, ArrRef, Builder); @@ -527,7 +537,7 @@ bool SimplifyStructRegSignatures::runOnModule(Module &M) { fixCallSite(Ctx, InvokeToFix, PreferredAlignment); } - // Update taking of a function's address + // Update taking of a function's address from a parameter for (auto &Addressing : FunctionAddressings) { Value *Temp = Addressing.Temp; Function *Old = Addressing.Old; From b077029fbe537bad576fcbf226ddacbe009e4683 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 3 Dec 2015 13:06:34 -0800 Subject: [PATCH 05/10] handle bitcasts of a function that is changed in SimplifyStructRegSignatures --- .../NaCl/SimplifyStructRegSignatures.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp index 664383e89fa..7113041fcc3 100644 --- a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp +++ b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp @@ -126,6 +126,7 @@ class SimplifyStructRegSignatures : public ModulePass { DenseSet FunctionsToDelete; SetVector CallsToPatch; SetVector InvokesToPatch; + SetVector BitCastsToPatch; DenseMap FunctionMap; struct FunctionAddressing { @@ -436,6 +437,10 @@ void SimplifyStructRegSignatures::scheduleInstructionsForCleanup( CallsToPatch.insert(Call); } else if (InvokeInst *Invoke = dyn_cast(&IIter)) { InvokesToPatch.insert(Invoke); + } else if (BitCastInst *BitCast = dyn_cast(&IIter)) { + if (isa(BitCast->getOperand(0))) { + BitCastsToPatch.insert(BitCast); + } } } } @@ -537,6 +542,16 @@ bool SimplifyStructRegSignatures::runOnModule(Module &M) { fixCallSite(Ctx, InvokeToFix, PreferredAlignment); } + // BitCasts of a function we are modifying must be corrected + for (auto &BitCastToFix : BitCastsToPatch) { + auto *Old = cast(BitCastToFix->getOperand(0)); + if (FunctionMap.find(Old) != FunctionMap.end()) { + auto *New = FunctionMap[Old]; + IRBuilder<> Builder(BitCastToFix); + BitCastToFix->setOperand(0, Builder.CreateBitCast(New, Old->getType(), "bitcastfixcast")); + } + } + // Update taking of a function's address from a parameter for (auto &Addressing : FunctionAddressings) { Value *Temp = Addressing.Temp; From 19de8377965d85850ff86593ec6016659d8a3123 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 3 Dec 2015 13:30:14 -0800 Subject: [PATCH 06/10] handle uses of changed functions in globals in SimplifyStructRegSignatures --- lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp index 7113041fcc3..c0ab8383a9d 100644 --- a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp +++ b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp @@ -561,6 +561,14 @@ bool SimplifyStructRegSignatures::runOnModule(Module &M) { Temp->replaceAllUsesWith(New); } + // Remaining uses of functions we modified (like in a global vtable) + // can be handled via a constantexpr bitcast + for (auto &Old : FunctionsToDelete) { + Function *New = FunctionMap[Old]; + assert(New); + Old->replaceAllUsesWith(ConstantExpr::getBitCast(New, Old->getType())); + } + // Delete leftover functions - the ones with old signatures. for (auto &ToDelete : FunctionsToDelete) { ToDelete->eraseFromParent(); From a14b776f65a894d2983cbb7a13c24562c918e70a Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 3 Dec 2015 13:34:06 -0800 Subject: [PATCH 07/10] clean up no longer needed code, we can use constantexpr bitcasts for more things in SimplifyStructRegSignatures --- .../NaCl/SimplifyStructRegSignatures.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp index c0ab8383a9d..650eb6029c6 100644 --- a/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp +++ b/lib/Target/JSBackend/NaCl/SimplifyStructRegSignatures.cpp @@ -126,7 +126,6 @@ class SimplifyStructRegSignatures : public ModulePass { DenseSet FunctionsToDelete; SetVector CallsToPatch; SetVector InvokesToPatch; - SetVector BitCastsToPatch; DenseMap FunctionMap; struct FunctionAddressing { @@ -437,10 +436,6 @@ void SimplifyStructRegSignatures::scheduleInstructionsForCleanup( CallsToPatch.insert(Call); } else if (InvokeInst *Invoke = dyn_cast(&IIter)) { InvokesToPatch.insert(Invoke); - } else if (BitCastInst *BitCast = dyn_cast(&IIter)) { - if (isa(BitCast->getOperand(0))) { - BitCastsToPatch.insert(BitCast); - } } } } @@ -542,16 +537,6 @@ bool SimplifyStructRegSignatures::runOnModule(Module &M) { fixCallSite(Ctx, InvokeToFix, PreferredAlignment); } - // BitCasts of a function we are modifying must be corrected - for (auto &BitCastToFix : BitCastsToPatch) { - auto *Old = cast(BitCastToFix->getOperand(0)); - if (FunctionMap.find(Old) != FunctionMap.end()) { - auto *New = FunctionMap[Old]; - IRBuilder<> Builder(BitCastToFix); - BitCastToFix->setOperand(0, Builder.CreateBitCast(New, Old->getType(), "bitcastfixcast")); - } - } - // Update taking of a function's address from a parameter for (auto &Addressing : FunctionAddressings) { Value *Temp = Addressing.Temp; From 2ab9913cd56dfdfbc35cd86c50e0047039360367 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 3 Dec 2015 13:49:54 -0800 Subject: [PATCH 08/10] support llvm.debugtrap --- lib/Target/JSBackend/CallHandlers.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index 9825047f936..0160f921c49 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -254,6 +254,10 @@ DEF_CALL_HANDLER(emscripten_debugger, { CantValidate = "emscripten_debugger is used"; return "debugger"; }) +DEF_CALL_HANDLER(llvm_debugtrap, { + CantValidate = "llvm.debugtrap is used"; + return "debugger"; +}) // i64 support @@ -940,6 +944,7 @@ void setupCallHandlers() { SETUP_CALL_HANDLER(emscripten_do_not_unwind_async); SETUP_CALL_HANDLER(emscripten_get_async_return_value_addr); SETUP_CALL_HANDLER(emscripten_debugger); + SETUP_CALL_HANDLER(llvm_debugtrap); SETUP_CALL_HANDLER(getHigh32); SETUP_CALL_HANDLER(setHigh32); SETUP_CALL_HANDLER(FtoILow); From ccb6f1f2d4a9aa63b9c60e5d052eaa7c7345b550 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Thu, 3 Dec 2015 16:43:50 -0800 Subject: [PATCH 09/10] support llvm.expect.i1 --- lib/Target/JSBackend/CallHandlers.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index 0160f921c49..880451d364b 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -456,6 +456,9 @@ DEF_CALL_HANDLER(llvm_memmove_p0i8_p0i8_i32, { DEF_CALL_HANDLER(llvm_expect_i32, { return getAssign(CI) + getValueAsStr(CI->getOperand(0)); }) +DEF_CALL_HANDLER(llvm_expect_i1, { + return getAssign(CI) + getValueAsStr(CI->getOperand(0)); +}) DEF_CALL_HANDLER(llvm_dbg_declare, { return ""; @@ -966,6 +969,7 @@ void setupCallHandlers() { SETUP_CALL_HANDLER(llvm_memset_p0i8_i32); SETUP_CALL_HANDLER(llvm_memmove_p0i8_p0i8_i32); SETUP_CALL_HANDLER(llvm_expect_i32); + SETUP_CALL_HANDLER(llvm_expect_i1); SETUP_CALL_HANDLER(llvm_dbg_declare); SETUP_CALL_HANDLER(llvm_dbg_value); SETUP_CALL_HANDLER(llvm_lifetime_start); From b283f9e3e71529dfd113109e46f17ad805725219 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 15 Dec 2015 12:23:35 -0800 Subject: [PATCH 10/10] 1.35.13 --- emscripten-version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emscripten-version.txt b/emscripten-version.txt index 9afe4cb4f0e..b54ea689d09 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -"1.35.12" +"1.35.13"