37 #define DEBUG_TYPE "wasm-fix-function-bitcasts" 40 class FixFunctionBitcasts final :
public ModulePass {
42 return "WebAssembly Fix Function Bitcasts";
50 bool runOnModule(
Module &M)
override;
60 "Fix mismatching bitcasts for WebAssembly",
false,
false)
63 return new FixFunctionBitcasts();
74 else if (U.get()->getType() != F.
getType()) {
83 if (isa<Constant>(U.get())) {
85 auto c = ConstantBCs.
insert(cast<Constant>(U.get()));
89 Uses.push_back(std::make_pair(&U, &F));
123 const DataLayout &DL = BB->getModule()->getDataLayout();
131 bool TypeMismatch =
false;
132 bool WrapperNeeded =
false;
139 (ExpectedRtnType != RtnType))
140 WrapperNeeded =
true;
142 for (; AI != AE && PI != PE; ++AI, ++PI) {
144 Type *ParamType = *PI;
146 if (ArgType == ParamType) {
152 BB->getInstList().push_back(PtrCast);
155 LLVM_DEBUG(
dbgs() <<
"CreateWrapper: struct param type in bitcast: " 157 WrapperNeeded =
false;
162 << *ParamType <<
" Got: " << *ArgType <<
"\n");
169 if (WrapperNeeded && !TypeMismatch) {
170 for (; PI != PE; ++PI)
173 for (; AI != AE; ++AI)
183 }
else if (ExpectedRtnType->
isVoidTy()) {
184 LLVM_DEBUG(
dbgs() <<
"Creating dummy return: " << *RtnType <<
"\n");
186 }
else if (RtnType == ExpectedRtnType) {
192 BB->getInstList().push_back(Cast);
195 LLVM_DEBUG(
dbgs() <<
"CreateWrapper: struct return type in bitcast: " 197 WrapperNeeded =
false;
199 LLVM_DEBUG(
dbgs() <<
"CreateWrapper: return type mismatch calling: " 202 <<
" Got: " << *RtnType <<
"\n");
211 F->
getName() +
"_bitcast_invalid", M);
215 }
else if (!WrapperNeeded) {
236 bool FixFunctionBitcasts::runOnModule(
Module &M) {
237 LLVM_DEBUG(
dbgs() <<
"********** Fix Function Bitcasts **********\n");
252 if (
F.getName() ==
"main") {
260 LLVM_DEBUG(
dbgs() <<
"Found `main` function with incorrect type: " 261 << *
F.getFunctionType() <<
"\n");
275 for (
auto &UseFunc : Uses) {
276 Use *U = UseFunc.first;
287 auto Pair = Wrappers.
insert(std::make_pair(std::make_pair(F, Ty),
nullptr));
295 if (isa<Constant>(U->get()))
304 Main->
setName(
"__original_main");
void setVisibility(VisibilityTypes V)
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
A parsed version of the target data layout string in and methods for querying it. ...
iterator_range< use_iterator > uses()
This class represents an incoming formal argument to a Function.
bool shouldFixMainFunction(FunctionType *FuncTy, FunctionType *MainTy)
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
void push_back(const T &Elt)
This class represents a function call, abstracting a target machine's calling convention.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
Like Internal, but omit from symbol table.
LLVMContext & getContext() const
All values hold a context through their type.
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
const Use & getOperandUse(unsigned i) const
param_iterator param_end() const
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
static bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
LLVMContext & getContext() const
Get the global data context.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void setName(const Twine &Name)
Change the name of the value.
Class to represent function types.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Type * getType() const
All values are typed, get the type of this value.
INITIALIZE_PASS(FixFunctionBitcasts, DEBUG_TYPE, "Fix mismatching bitcasts for WebAssembly", false, false) ModulePass *llvm
LinkageTypes getLinkage() const
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
amdgpu Simplify well known AMD library false Value * Callee
Class to represent pointers.
static Function * CreateWrapper(Function *F, FunctionType *Ty)
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool isVoidTy() const
Return true if this is 'void'.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
VisibilityTypes getVisibility() const
Value * getCalledValue() const
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This function has undefined behavior.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
param_iterator param_begin() const
Represent the analysis usage information of a pass.
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
ModulePass * createWebAssemblyFixFunctionBitcasts()
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type::subtype_iterator param_iterator
Type * getReturnType() const
void setPreservesCFG()
This function should be called by the pass, iff they do not:
void setLinkage(LinkageTypes LT)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
static IntegerType * getInt32Ty(LLVMContext &C)
static void FindUses(Value *V, Function &F, SmallVectorImpl< std::pair< Use *, Function *>> &Uses, SmallPtrSetImpl< Constant *> &ConstantBCs)
StringRef getName() const
Return a constant reference to the value's name.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Type * getElementType() const
PointerType * getType() const
Global values are always pointers.
bool isStructTy() const
True if this is an instance of StructType.