aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-02-02 17:29:57 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-02-02 18:00:18 -0800
commit91288b653d28c8fe4aeb69b06ce82d75646e72a7 (patch)
treef33a97be1b37ab2390b4a07425837c8dacce84de
parent21211f2f88d550f2b3ddbf337cf3a9ac4c7c80d1 (diff)
support llvm.used
-rw-r--r--lib/Target/JSBackend/JSBackend.cpp30
-rw-r--r--lib/Transforms/NaCl/GlobalCleanup.cpp2
2 files changed, 30 insertions, 2 deletions
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp
index 11abd21f3d..e7253115d4 100644
--- a/lib/Target/JSBackend/JSBackend.cpp
+++ b/lib/Target/JSBackend/JSBackend.cpp
@@ -107,6 +107,8 @@ namespace {
std::map<std::string, unsigned> IndexedFunctions; // name -> index
FunctionTableMap FunctionTables; // sig => list of functions
std::vector<std::string> GlobalInitializers;
+ std::vector<std::string> Exports; // additional exports
+
bool UsesSIMD;
int InvokeState; // cycles between 0, 1 after preInvoke, 2 after call, 0 again after postInvoke. hackish, no argument there.
@@ -1712,6 +1714,18 @@ void JSWriter::printModuleBody() {
}
Out << "],";
+ Out << "\"exports\": [";
+ first = true;
+ for (unsigned i = 0; i < Exports.size(); i++) {
+ if (first) {
+ first = false;
+ } else {
+ Out << ", ";
+ }
+ Out << "\"" << Exports[i] << "\"";
+ }
+ Out << "],";
+
Out << "\"simd\": ";
Out << (UsesSIMD ? "1" : "0");
Out << ",";
@@ -1796,8 +1810,20 @@ void JSWriter::parseConstant(const std::string& name, const Constant* CV, bool c
}
// FIXME: create a zero section at the end, avoid filling meminit with zeros
}
- } else if (isa<ConstantArray>(CV)) {
- assert(false);
+ } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
+ if (calculate) {
+ for (Constant::const_use_iterator UI = CV->use_begin(), UE = CV->use_end(); UI != UE; ++UI) {
+ assert((*UI)->getName() == "llvm.used"); // llvm.used is acceptable (and can be ignored)
+ }
+ // export the kept-alives
+ for (unsigned i = 0; i < CA->getNumOperands(); i++) {
+ const Constant *C = CA->getOperand(i);
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ C = CE->getOperand(0); // ignore bitcasts
+ }
+ Exports.push_back(getJSName(C));
+ }
+ }
} else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
if (name == "__init_array_start") {
// this is the global static initializer
diff --git a/lib/Transforms/NaCl/GlobalCleanup.cpp b/lib/Transforms/NaCl/GlobalCleanup.cpp
index d489fefc1d..21c3fe8b8e 100644
--- a/lib/Transforms/NaCl/GlobalCleanup.cpp
+++ b/lib/Transforms/NaCl/GlobalCleanup.cpp
@@ -76,10 +76,12 @@ bool GlobalCleanup::runOnModule(Module &M) {
GV->eraseFromParent();
Modified = true;
}
+#if 0 // XXX EMSCRIPTEN: we need dis
if (GlobalVariable *GV = M.getNamedGlobal("llvm.used")) {
GV->eraseFromParent();
Modified = true;
}
+#endif
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ) {