Lines Matching +full:auto +full:- +full:detects
1 //===-- WebAssemblyFixFunctionBitcasts.cpp - Fix function bitcasts --------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
23 //===----------------------------------------------------------------------===//
35 #define DEBUG_TYPE "wasm-fix-function-bitcasts"
64 // Recursively descend the def-use lists from V to find non-bitcast users of
68 for (User *U : V->users()) { in findUses()
69 if (auto *BC = dyn_cast<BitCastOperator>(U)) in findUses()
71 else if (auto *A = dyn_cast<GlobalAlias>(U)) in findUses()
73 else if (auto *CB = dyn_cast<CallBase>(U)) { in findUses()
74 Value *Callee = CB->getCalledOperand(); in findUses()
78 if (CB->getFunctionType() == F.getValueType()) in findUses()
88 // - Call with more arguments than needed: arguments are dropped
89 // - Call with fewer arguments than needed: arguments are filled in with undef
90 // - Return value is not needed: drop it
91 // - Return value needed but not present: supply an undef
104 // CMake detects the existence of a function in a toolchain).
110 Module *M = F->getParent(); in createWrapper()
113 F->getName() + "_bitcast", M); in createWrapper()
114 BasicBlock *BB = BasicBlock::Create(M->getContext(), "body", Wrapper); in createWrapper()
115 const DataLayout &DL = BB->getDataLayout(); in createWrapper()
119 Function::arg_iterator AI = Wrapper->arg_begin(); in createWrapper()
120 Function::arg_iterator AE = Wrapper->arg_end(); in createWrapper()
121 FunctionType::param_iterator PI = F->getFunctionType()->param_begin(); in createWrapper()
122 FunctionType::param_iterator PE = F->getFunctionType()->param_end(); in createWrapper()
126 Type *ExpectedRtnType = F->getFunctionType()->getReturnType(); in createWrapper()
127 Type *RtnType = Ty->getReturnType(); in createWrapper()
129 if ((F->getFunctionType()->getNumParams() != Ty->getNumParams()) || in createWrapper()
130 (F->getFunctionType()->isVarArg() != Ty->isVarArg()) || in createWrapper()
135 Type *ArgType = AI->getType(); in createWrapper()
144 PtrCast->insertInto(BB, BB->end()); in createWrapper()
146 } else if (ArgType->isStructTy() || ParamType->isStructTy()) { in createWrapper()
148 << F->getName() << "\n"); in createWrapper()
152 << F->getName() << "\n"); in createWrapper()
164 if (F->isVarArg()) in createWrapper()
170 Type *ExpectedRtnType = F->getFunctionType()->getReturnType(); in createWrapper()
171 Type *RtnType = Ty->getReturnType(); in createWrapper()
173 if (RtnType->isVoidTy()) { in createWrapper()
174 ReturnInst::Create(M->getContext(), BB); in createWrapper()
175 } else if (ExpectedRtnType->isVoidTy()) { in createWrapper()
177 ReturnInst::Create(M->getContext(), UndefValue::get(RtnType), BB); in createWrapper()
179 ReturnInst::Create(M->getContext(), Call, BB); in createWrapper()
184 Cast->insertInto(BB, BB->end()); in createWrapper()
185 ReturnInst::Create(M->getContext(), Cast, BB); in createWrapper()
186 } else if (RtnType->isStructTy() || ExpectedRtnType->isStructTy()) { in createWrapper()
188 << F->getName() << "\n"); in createWrapper()
192 << F->getName() << "\n"); in createWrapper()
201 Wrapper->eraseFromParent(); in createWrapper()
203 F->getName() + "_bitcast_invalid", M); in createWrapper()
204 BasicBlock *BB = BasicBlock::Create(M->getContext(), "body", Wrapper); in createWrapper()
205 new UnreachableInst(M->getContext(), BB); in createWrapper()
206 Wrapper->setName(F->getName() + "_bitcast_invalid"); in createWrapper()
208 LLVM_DEBUG(dbgs() << "createWrapper: no wrapper needed: " << F->getName() in createWrapper()
210 Wrapper->eraseFromParent(); in createWrapper()
213 LLVM_DEBUG(dbgs() << "createWrapper: " << F->getName() << "\n"); in createWrapper()
220 // Only fix the main function if it's the standard zero-arg form. That way, in shouldFixMainFunction()
222 // mismatches from the linker for non-standard cases. in shouldFixMainFunction()
223 return FuncTy->getReturnType() == MainTy->getReturnType() && in shouldFixMainFunction()
224 FuncTy->getNumParams() == 0 && in shouldFixMainFunction()
225 !FuncTy->isVarArg(); in shouldFixMainFunction()
266 for (auto &UseFunc : Uses) { in runOnModule()
269 FunctionType *Ty = CB->getFunctionType(); in runOnModule()
271 auto Pair = Wrappers.insert(std::make_pair(std::make_pair(F, Ty), nullptr)); in runOnModule()
273 Pair.first->second = createWrapper(F, Ty); in runOnModule()
275 Function *Wrapper = Pair.first->second; in runOnModule()
279 CB->setCalledOperand(Wrapper); in runOnModule()
285 Main->setName("__original_main"); in runOnModule()
286 auto *MainWrapper = in runOnModule()
287 cast<Function>(CallMain->getCalledOperand()->stripPointerCasts()); in runOnModule()
289 if (Main->isDeclaration()) { in runOnModule()
292 MainWrapper->eraseFromParent(); in runOnModule()
296 MainWrapper->setName("main"); in runOnModule()
297 MainWrapper->setLinkage(Main->getLinkage()); in runOnModule()
298 MainWrapper->setVisibility(Main->getVisibility()); in runOnModule()