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

Commit de8e104

Browse files
committed
emit the specific signatures of each asm const
1 parent 386b52e commit de8e104

File tree

2 files changed

+35
-45
lines changed

2 files changed

+35
-45
lines changed

lib/Target/JSBackend/CallHandlers.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ DEF_CALL_HANDLER(__default__, {
7575
// function pointer call
7676
ensureFunctionTable(FT);
7777
if (!Invoke) {
78-
Sig = getFunctionSignature(FT, &Name);
78+
Sig = getFunctionSignature(FT);
7979
if (!EmulatedFunctionPointers) {
8080
Name = std::string("FUNCTION_TABLE_") + Sig + "[" + Name + " & #FM_" + Sig + "#]";
8181
NeedCasts = false; // function table call, so stays in asm module
@@ -113,7 +113,7 @@ DEF_CALL_HANDLER(__default__, {
113113
}
114114

115115
if (Invoke) {
116-
Sig = getFunctionSignature(FT, &Name);
116+
Sig = getFunctionSignature(FT);
117117
Name = "invoke_" + Sig;
118118
NeedCasts = true;
119119
}
@@ -550,9 +550,13 @@ DEF_CALL_HANDLER(emscripten_float32x4_store2, {
550550

551551
std::string handleAsmConst(const Instruction *CI) {
552552
unsigned Num = getNumArgOperands(CI);
553-
unsigned Arity = Num - 1; // ignore the first argument, which is a pointer to the code
554-
std::string func = "emscripten_asm_const_" + utostr(Arity);
555-
std::string ret = "_" + func + "(" + utostr(getAsmConstId(CI->getOperand(0), Arity));
553+
std::string Sig;
554+
Sig += getFunctionSignatureLetter(CI->getType());
555+
for (unsigned i = 1; i < Num; i++) {
556+
Sig += getFunctionSignatureLetter(CI->getOperand(i)->getType());
557+
}
558+
std::string func = "emscripten_asm_const_" + Sig;
559+
std::string ret = "_" + func + "(" + utostr(getAsmConstId(CI->getOperand(0), Sig));
556560
for (unsigned i = 1; i < Num; i++) {
557561
ret += ", " + getValueAsCastParenStr(CI->getOperand(i), ASM_NONSPECIFIC);
558562
}

lib/Target/JSBackend/JSBackend.cpp

+26-40
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ namespace {
174174
typedef std::map<const BasicBlock*, unsigned> BlockIndexMap;
175175
typedef std::map<const Function*, BlockIndexMap> BlockAddressMap;
176176
typedef std::map<const BasicBlock*, Block*> LLVMToRelooperMap;
177+
struct AsmConstInfo {
178+
int Id;
179+
std::set<std::string> Sigs;
180+
};
177181

178182
/// JSWriter - This class is the main chunk of code that converts an LLVM
179183
/// module to JavaScript.
@@ -200,8 +204,7 @@ namespace {
200204
std::vector<std::string> Exports; // additional exports
201205
StringMap Aliases;
202206
BlockAddressMap BlockAddresses;
203-
NameIntMap AsmConsts;
204-
IntIntSetMap AsmConstArities;
207+
std::map<std::string, AsmConstInfo> AsmConsts; // code => { index, list of seen sigs }
205208
NameSet FuncRelocatableExterns; // which externals are accessed in this function; we load them once at the beginning (avoids a potential call in a heap access, and might be faster)
206209

207210
std::string CantValidate;
@@ -330,7 +333,7 @@ namespace {
330333
return 'i';
331334
}
332335
}
333-
std::string getFunctionSignature(const FunctionType *F, const std::string *Name=NULL) {
336+
std::string getFunctionSignature(const FunctionType *F) {
334337
std::string Ret;
335338
Ret += getFunctionSignatureLetter(F->getReturnType());
336339
for (FunctionType::param_iterator AI = F->param_begin(),
@@ -348,7 +351,7 @@ namespace {
348351
unsigned getFunctionIndex(const Function *F) {
349352
const std::string &Name = getJSName(F);
350353
if (IndexedFunctions.find(Name) != IndexedFunctions.end()) return IndexedFunctions[Name];
351-
std::string Sig = getFunctionSignature(F->getFunctionType(), &Name);
354+
std::string Sig = getFunctionSignature(F->getFunctionType());
352355
FunctionTable& Table = ensureFunctionTable(F->getFunctionType());
353356
if (NoAliasingFunctionPointers) {
354357
while (Table.size() < NextFunctionIndex) Table.push_back("0");
@@ -455,7 +458,7 @@ namespace {
455458
// Transform the string input into emscripten_asm_const_*(str, args1, arg2)
456459
// into an id. We emit a map of id => string contents, and emscripten
457460
// wraps it up so that calling that id calls that function.
458-
unsigned getAsmConstId(const Value *V, int Arity) {
461+
unsigned getAsmConstId(const Value *V, std::string Sig) {
459462
V = resolveFully(V);
460463
const Constant *CI = cast<GlobalVariable>(V)->getInitializer();
461464
std::string code;
@@ -482,15 +485,18 @@ namespace {
482485
}
483486
}
484487
}
485-
unsigned id;
488+
unsigned Id;
486489
if (AsmConsts.count(code) > 0) {
487-
id = AsmConsts[code];
490+
auto& Info = AsmConsts[code];
491+
Id = Info.Id;
492+
Info.Sigs.insert(Sig);
488493
} else {
489-
id = AsmConsts.size();
490-
AsmConsts[code] = id;
494+
AsmConstInfo Info;
495+
Info.Id = Id = AsmConsts.size();
496+
Info.Sigs.insert(Sig);
497+
AsmConsts[code] = Info;
491498
}
492-
AsmConstArities[id].insert(Arity);
493-
return id;
499+
return Id;
494500
}
495501

496502
// Test whether the given value is known to be an absolute value or one we turn into an absolute value
@@ -3301,44 +3307,24 @@ void JSWriter::printModuleBody() {
33013307

33023308
Out << "\"asmConsts\": {";
33033309
first = true;
3304-
for (NameIntMap::const_iterator I = AsmConsts.begin(), E = AsmConsts.end(); I != E; ++I) {
3310+
for (auto& I : AsmConsts) {
33053311
if (first) {
33063312
first = false;
33073313
} else {
33083314
Out << ", ";
33093315
}
3310-
Out << "\"" << utostr(I->second) << "\": \"" << I->first.c_str() << "\"";
3311-
}
3312-
Out << "},";
3313-
3314-
// Output a structure like:
3315-
// "asmConstArities": {
3316-
// "<ASM_CONST_ID_1>": [<ARITY>, <ARITY>],
3317-
// "<ASM_CONST_ID_2>": [<ARITY>]
3318-
// }
3319-
// Each ASM_CONST_ID represents a single EM_ASM_* block in the code and each
3320-
// ARITY represents the number of arguments defined in the block in compiled
3321-
// output (which may vary, if the EM_ASM_* block is used inside a template).
3322-
Out << "\"asmConstArities\": {";
3323-
first = true;
3324-
for (IntIntSetMap::const_iterator I = AsmConstArities.begin(), E = AsmConstArities.end();
3325-
I != E; ++I) {
3326-
if (!first) {
3327-
Out << ", ";
3328-
}
3329-
Out << "\"" << utostr(I->first) << "\": [";
3330-
first = true;
3331-
for (IntSet::const_iterator J = I->second.begin(), F = I->second.end();
3332-
J != F; ++J) {
3333-
if (first) {
3334-
first = false;
3316+
Out << "\"" << utostr(I.second.Id) << "\": [\"" << I.first.c_str() << "\", [";
3317+
auto& Sigs = I.second.Sigs;
3318+
bool innerFirst = true;
3319+
for (auto& Sig : Sigs) {
3320+
if (innerFirst) {
3321+
innerFirst = false;
33353322
} else {
33363323
Out << ", ";
33373324
}
3338-
Out << utostr(*J);
3325+
Out << "\"" << Sig << "\"";
33393326
}
3340-
first = false;
3341-
Out << "]";
3327+
Out << "]]";
33423328
}
33433329
Out << "}";
33443330

0 commit comments

Comments
 (0)