Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,

for (unsigned i = 0, e = Decls.size(); i != e; ++i)
if (Decls[i]) {
if (getContext().getTargetInfo().getTriple().isCheerpWasm()) {
if (getContext().getTargetInfo().getTriple().isCheerpWasm() && !Guard.isValid()) {
llvm::GlobalVariable *GuardGV = new llvm::GlobalVariable(CGM.getModule(), Int8Ty, /*isConstant=*/false,
llvm::GlobalVariable::InternalLinkage,
llvm::ConstantInt::get(Int8Ty, 0),
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Driver/ToolChains/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,9 @@ void cheerp::Link::ConstructJob(Compilation &C, const JobAction &JA,
// Add standard libraries
if (!Args.hasArg(options::OPT_nostdlib) &&
!Args.hasArg(options::OPT_nodefaultlibs)) {
if (C.getDriver().CCCIsCXX()) {
Arg *Sanitizers = Args.getLastArg(options::OPT_fsanitize_EQ);
// Always run ASAN with libstdlibs
if (C.getDriver().CCCIsCXX() || (Sanitizers && Sanitizers->containsValue("address"))) {
AddStdLib("libstdlibs.bc");
} else {
AddStdLib("libc.bc");
Expand All @@ -602,7 +604,6 @@ void cheerp::Link::ConstructJob(Compilation &C, const JobAction &JA,
// Add wasm helper if needed
Arg *CheerpLinearOutput = Args.getLastArg(options::OPT_cheerp_linear_output_EQ);

Arg *Sanitizers = Args.getLastArg(options::OPT_fsanitize_EQ);
if (Sanitizers && Sanitizers->containsValue("address")) {
AddLateLib("asmjs/libclang_rt.asan-Cheerp.bc");
if (D.CCCIsCXX())
Expand Down
7 changes: 2 additions & 5 deletions compiler-rt/lib/asan/asan_cheerpwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,8 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) {}

static void (*tsd_destructor)(void *tsd) = nullptr;

// Cheerp: for now we've removed the initializer for tsd_key's constructor.
// It caused a crash in ASAN because the constructor for the global is run after the asan module constructor has already used and set it.
// Originally the global is meant to be a thread_local, but thread_local constructors and destructors are not yet supported.
struct tsd_key {
tsd_key() {}
tsd_key() : key(nullptr) {}
~tsd_key() {
CHECK(tsd_destructor);
if (key)
Expand All @@ -52,7 +49,7 @@ struct tsd_key {
void *key;
};

static /*thread_local*/ struct tsd_key key;
static thread_local struct tsd_key key;

void AsanTSDInit(void (*destructor)(void *tsd)) {
CHECK(!tsd_destructor);
Expand Down
2 changes: 1 addition & 1 deletion libcxxabi/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ endif()
if(CHEERP)
# Remove files which are not currently supported
list(REMOVE_ITEM LIBCXXABI_SOURCES cxa_default_handlers.cpp cxa_exception.cpp cxa_handlers.cpp cxa_exception_storage.cpp cxa_unexpected.cpp cxa_personality.cpp)
list(APPEND LIBCXXABI_SOURCES cxa_cheerp.cpp)
list(APPEND LIBCXXABI_SOURCES cxa_cheerp.cpp cxa_thread_atexit.cpp)
endif()

if (LIBCXXABI_ENABLE_THREADS AND (UNIX OR FUCHSIA) AND NOT (APPLE OR CYGWIN)
Expand Down
4 changes: 4 additions & 0 deletions libcxxabi/src/cxa_thread_atexit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,11 @@ extern "C" {
#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
#else
#ifndef __CHEERP__
if (__cxa_thread_atexit_impl) {
return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
} else {
#endif // __CHEERP__
// Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for
// one-time initialization and __cxa_atexit() for destruction)
static DtorsManager manager;
Expand All @@ -137,7 +139,9 @@ extern "C" {
dtors = head;

return 0;
#ifndef __CHEERP__
}
#endif // __CHEERP__
#endif // HAVE___CXA_THREAD_ATEXIT_IMPL
}

Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Cheerp/WasmWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ class CheerpWasmWriter final : public CheerpBaseWriter
void compileSignedInteger(WasmBuffer& code, const llvm::Value* v, bool forComparison);
void compileUnsignedInteger(WasmBuffer& code, const llvm::Value* v);
void compileTypedZero(WasmBuffer& code, const llvm::Type* t);
void compileThreadLocalLoad(WasmBuffer& code, const llvm::GlobalVariable* GV);
static void encodeInst(WasmOpcode opcode, WasmBuffer& code);
static void encodeInst(WasmS32Opcode opcode, int32_t immediate, WasmBuffer& code);
static void encodeInst(WasmS64Opcode opcode, int64_t immediate, WasmBuffer& code);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CheerpUtils/ConstantExprLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ bool ConstantExprLowering::runOnFunction(Function& F, bool& hasI64, const Target
{
// In asmjs, addresses of globals are just integers
// Ask LinearMemoryHelper for the value and cast to the pointer type
if (!WasmSharedModule && GV->GlobalValue::getSection() == StringRef("asmjs"))
if (!WasmSharedModule && GV->GlobalValue::getSection() == StringRef("asmjs") && !GV->isThreadLocal())
{
if (mapGVToInst.count(GV) == 0)
{
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CheerpUtils/TypeOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ Function* TypeOptimizer::rewriteIntrinsic(Function* F, FunctionType* FT)
{
case Intrinsic::cheerp_allocate:
case Intrinsic::cheerp_allocate_array:
case Intrinsic::threadlocal_address:
{
Type* localTys[] = { FT->getReturnType()};
newTys.insert(newTys.end(),localTys,localTys+1);
Expand Down
23 changes: 17 additions & 6 deletions llvm/lib/CheerpWriter/CheerpWasmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1366,7 +1366,7 @@ void CheerpWasmWriter::compileGEP(WasmBuffer& code, const llvm::User* gep_inst,
const llvm::Value *p = linearHelper.compileGEP(gep_inst, &gepWriter, &PA);
if(const GlobalVariable* GV = dyn_cast<GlobalVariable>(p))
{
if(WasmSharedModule)
if(WasmSharedModule || GV->isThreadLocal())
gepWriter.addValue(p, 1);
else
gepWriter.addConst(linearHelper.getGlobalVariableAddress(GV));
Expand Down Expand Up @@ -1463,6 +1463,16 @@ void CheerpWasmWriter::compileTypedZero(WasmBuffer& code, const llvm::Type* t)
}
}

void CheerpWasmWriter::compileThreadLocalLoad(WasmBuffer& code, const llvm::GlobalVariable* GV)
{
assert(GV->isThreadLocal());
int32_t offset = linearHelper.getThreadLocalOffset(GV);
encodeInst(WasmU32Opcode::GET_GLOBAL, THREAD_POINTER_GLOBAL, code);
encodeInst(WasmS32Opcode::I32_CONST, offset, code);
encodeInst(WasmOpcode::I32_ADD, code);

}

void CheerpWasmWriter::compileConstantExpr(WasmBuffer& code, const ConstantExpr* ce)
{
switch(ce->getOpcode())
Expand Down Expand Up @@ -1642,6 +1652,10 @@ void CheerpWasmWriter::compileConstant(WasmBuffer& code, const Constant* c, bool
encodeInst(WasmU32Opcode::GET_GLOBAL, it->second, code);
}
}
else if (GV->isThreadLocal())
{
compileThreadLocalLoad(code, GV);
}
else
{
uint32_t address = linearHelper.getGlobalVariableAddress(GV);
Expand Down Expand Up @@ -2077,7 +2091,7 @@ uint32_t CheerpWasmWriter::compileLoadStorePointer(WasmBuffer& code, const Value
auto p = linearHelper.compileGEP(ptrOp, &gepWriter, &PA);
if(const GlobalVariable* GV = dyn_cast<GlobalVariable>(p))
{
if(WasmSharedModule)
if(WasmSharedModule || GV->isThreadLocal())
gepWriter.addValue(p, 1);
else
gepWriter.addConst(linearHelper.getGlobalVariableAddress(GV));
Expand Down Expand Up @@ -3038,10 +3052,7 @@ bool CheerpWasmWriter::compileInlineInstruction(WasmBuffer& code, const Instruct
{
// We encode this as an offset from the thread pointer.
const GlobalVariable *GV = dyn_cast<GlobalVariable>(I.getOperand(0));
int32_t offset = linearHelper.getThreadLocalOffset(GV);
encodeInst(WasmU32Opcode::GET_GLOBAL, THREAD_POINTER_GLOBAL, code);
encodeInst(WasmS32Opcode::I32_CONST, offset, code);
encodeInst(WasmOpcode::I32_ADD, code);
compileThreadLocalLoad(code, GV);
return false;
}
case Intrinsic::cheerp_locals_stack:
Expand Down
Loading