|
17 | 17 | //===----------------------------------------------------------------------===//
|
18 | 18 |
|
19 | 19 | #include "llvm/ADT/SmallVector.h"
|
| 20 | +#include "llvm/ADT/Triple.h" |
20 | 21 | #include "llvm/IR/Constants.h"
|
21 | 22 | #include "llvm/IR/DataLayout.h"
|
22 | 23 | #include "llvm/IR/Function.h"
|
@@ -45,7 +46,22 @@ INITIALIZE_PASS(ExpandVarArgs, "expand-varargs",
|
45 | 46 | "Expand out variable argument function definitions and calls",
|
46 | 47 | false, false)
|
47 | 48 |
|
48 |
| -static void ExpandVarArgFunc(Function *Func) { |
| 49 | +static bool isEmscriptenJSArgsFunc(Module *M, StringRef Name) { |
| 50 | + // TODO(jfb) Make these intrinsics in clang and remove the assert: these |
| 51 | + // intrinsics should only exist for Emscripten. |
| 52 | + bool isEmscriptenSpecial = Name.equals("emscripten_asm_const_int") || |
| 53 | + Name.equals("emscripten_asm_const_double") || |
| 54 | + Name.equals("emscripten_landingpad") || |
| 55 | + Name.equals("emscripten_resume"); |
| 56 | + assert(isEmscriptenSpecial ? Triple(M->getTargetTriple()).isOSEmscripten() |
| 57 | + : true); |
| 58 | + return isEmscriptenSpecial; |
| 59 | +} |
| 60 | + |
| 61 | +static bool ExpandVarArgFunc(Module *M, Function *Func) { |
| 62 | + if (isEmscriptenJSArgsFunc(M, Func->getName())) |
| 63 | + return false; |
| 64 | + |
49 | 65 | Type *PtrType = Type::getInt8PtrTy(Func->getContext());
|
50 | 66 |
|
51 | 67 | FunctionType *FTy = Func->getFunctionType();
|
@@ -84,6 +100,8 @@ static void ExpandVarArgFunc(Function *Func) {
|
84 | 100 | }
|
85 | 101 | }
|
86 | 102 | }
|
| 103 | + |
| 104 | + return true; |
87 | 105 | }
|
88 | 106 |
|
89 | 107 | static void ExpandVAArgInst(VAArgInst *Inst, DataLayout *DL) {
|
@@ -146,14 +164,16 @@ static void ExpandVACopyInst(VACopyInst *Inst) {
|
146 | 164 | // ExpandVarArgCall() converts a CallInst or InvokeInst to expand out
|
147 | 165 | // of varargs. It returns whether the module was modified.
|
148 | 166 | template <class InstType>
|
149 |
| -static bool ExpandVarArgCall(InstType *Call, DataLayout *DL) { |
| 167 | +static bool ExpandVarArgCall(Module *M, InstType *Call, DataLayout *DL) { |
150 | 168 | FunctionType *FuncType = cast<FunctionType>(
|
151 | 169 | Call->getCalledValue()->getType()->getPointerElementType());
|
152 | 170 | if (!FuncType->isFunctionVarArg())
|
153 | 171 | return false;
|
| 172 | + if (auto *F = dyn_cast<Function>(Call->getCalledValue())) |
| 173 | + if (isEmscriptenJSArgsFunc(M, F->getName())) |
| 174 | + return false; |
154 | 175 |
|
155 | 176 | Function *F = Call->getParent()->getParent();
|
156 |
| - Module *M = F->getParent(); |
157 | 177 | LLVMContext &Ctx = M->getContext();
|
158 | 178 |
|
159 | 179 | SmallVector<AttributeSet, 8> Attrs;
|
@@ -284,17 +304,15 @@ bool ExpandVarArgs::runOnModule(Module &M) {
|
284 | 304 | Changed = true;
|
285 | 305 | ExpandVACopyInst(VAC);
|
286 | 306 | } else if (auto *Call = dyn_cast<CallInst>(I)) {
|
287 |
| - Changed |= ExpandVarArgCall(Call, &DL); |
| 307 | + Changed |= ExpandVarArgCall(&M, Call, &DL); |
288 | 308 | } else if (auto *Call = dyn_cast<InvokeInst>(I)) {
|
289 |
| - Changed |= ExpandVarArgCall(Call, &DL); |
| 309 | + Changed |= ExpandVarArgCall(&M, Call, &DL); |
290 | 310 | }
|
291 | 311 | }
|
292 | 312 | }
|
293 | 313 |
|
294 |
| - if (F->isVarArg()) { |
295 |
| - Changed = true; |
296 |
| - ExpandVarArgFunc(F); |
297 |
| - } |
| 314 | + if (F->isVarArg()) |
| 315 | + Changed |= ExpandVarArgFunc(&M, F); |
298 | 316 | }
|
299 | 317 |
|
300 | 318 | return Changed;
|
|
0 commit comments