Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 7c70fc6

Browse files
committed
emit asmConsts as metadata
1 parent f5e20b6 commit 7c70fc6

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/Target/JSBackend/CallHandlers.h

+27
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,30 @@ DEF_CALL_HANDLER(emscripten_float32x4_storexy, {
501501
return "SIMD_float32x4_storeXY(HEAPU8, " + getValueAsStr(CI->getOperand(0)) + ", " + getValueAsStr(CI->getOperand(1)) + ")";
502502
})
503503

504+
// EM_ASM support
505+
506+
std::string handleAsmConst(const Instruction *CI, std::string suffix="") {
507+
std::string ret = "_emscripten_asm_const" + suffix + "(" + utostr(getAsmConstId(CI->getOperand(0)));
508+
unsigned Num = getNumArgOperands(CI);
509+
for (unsigned i = 1; i < Num; i++) {
510+
ret += ", " + getValueAsCastParenStr(CI->getOperand(i), ASM_NONSPECIFIC);
511+
}
512+
return ret + ")";
513+
}
514+
515+
DEF_CALL_HANDLER(emscripten_asm_const, {
516+
Declares.insert("emscripten_asm_const");
517+
return handleAsmConst(CI);
518+
})
519+
DEF_CALL_HANDLER(emscripten_asm_const_int, {
520+
Declares.insert("emscripten_asm_const_int");
521+
return getAssign(CI) + getCast(handleAsmConst(CI, "_int"), Type::getInt32Ty(CI->getContext()));
522+
})
523+
DEF_CALL_HANDLER(emscripten_asm_const_double, {
524+
Declares.insert("emscripten_asm_const_double");
525+
return getAssign(CI) + getCast(handleAsmConst(CI, "_double"), Type::getDoubleTy(CI->getContext()));
526+
})
527+
504528
#define DEF_BUILTIN_HANDLER(name, to) \
505529
DEF_CALL_HANDLER(name, { \
506530
return CH___default__(CI, #to); \
@@ -674,6 +698,9 @@ void setupCallHandlers() {
674698
SETUP_CALL_HANDLER(emscripten_float32x4_loadxy);
675699
SETUP_CALL_HANDLER(emscripten_float32x4_storex);
676700
SETUP_CALL_HANDLER(emscripten_float32x4_storexy);
701+
SETUP_CALL_HANDLER(emscripten_asm_const);
702+
SETUP_CALL_HANDLER(emscripten_asm_const_int);
703+
SETUP_CALL_HANDLER(emscripten_asm_const_double);
677704

678705
SETUP_CALL_HANDLER(abs);
679706
SETUP_CALL_HANDLER(labs);

lib/Target/JSBackend/JSBackend.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ namespace {
150150
std::vector<std::string> GlobalInitializers;
151151
std::vector<std::string> Exports; // additional exports
152152
BlockAddressMap BlockAddresses;
153+
NameIntMap AsmConsts;
153154

154155
std::string CantValidate;
155156
bool UsesSIMD;
@@ -365,6 +366,19 @@ namespace {
365366
}
366367
}
367368

369+
// Transform the string input into emscripten_asm_const_*(str, args1, arg2)
370+
// into an id. We emit a map of id => string contents, and emscripten
371+
// wraps it up so that calling that id calls that function.
372+
unsigned getAsmConstId(const Value *V) {
373+
V = resolveFully(V);
374+
const Constant *CI = cast<GlobalVariable>(V)->getInitializer();
375+
const ConstantDataSequential *CDS = cast<ConstantDataSequential>(CI);
376+
std::string code = CDS->getAsString();
377+
unsigned id = AsmConsts.size();
378+
AsmConsts[code] = id;
379+
return id;
380+
}
381+
368382
// Test whether the given value is known to be an absolute value or one we turn into an absolute value
369383
bool isAbsolute(const Value *P) {
370384
if (const IntToPtrInst *ITP = dyn_cast<IntToPtrInst>(P)) {
@@ -2653,6 +2667,18 @@ void JSWriter::printModuleBody() {
26532667
}
26542668
Out << "\"_" << I->first << "\": \"" << utostr(I->second) << "\"";
26552669
}
2670+
Out << "},";
2671+
2672+
Out << "\"asmConsts\": {";
2673+
first = true;
2674+
for (NameIntMap::const_iterator I = AsmConsts.begin(), E = AsmConsts.end(); I != E; ++I) {
2675+
if (first) {
2676+
first = false;
2677+
} else {
2678+
Out << ", ";
2679+
}
2680+
Out << "\"" << utostr(I->second) << "\": \"" << I->first.c_str() << "\"";
2681+
}
26562682
Out << "}";
26572683

26582684
Out << "\n}\n";

0 commit comments

Comments
 (0)