Go to the documentation of this file.
35 #define DEBUG_TYPE "wasm-fix-function-bitcasts"
38 class FixFunctionBitcasts final :
public ModulePass {
40 return "WebAssembly Fix Function Bitcasts";
48 bool runOnModule(
Module &
M)
override;
58 "Fix mismatching bitcasts for WebAssembly",
false,
false)
61 return new FixFunctionBitcasts();
69 if (
auto *BC = dyn_cast<BitCastOperator>(U))
71 else if (
auto *A = dyn_cast<GlobalAlias>(U))
73 else if (
auto *CB = dyn_cast<CallBase>(U)) {
78 if (CB->getFunctionType() ==
F.getValueType())
81 Uses.push_back(std::make_pair(CB, &
F));
113 F->getName() +
"_bitcast",
M);
123 bool TypeMismatch =
false;
124 bool WrapperNeeded =
false;
126 Type *ExpectedRtnType =
F->getFunctionType()->getReturnType();
129 if ((
F->getFunctionType()->getNumParams() != Ty->
getNumParams()) ||
130 (
F->getFunctionType()->isVarArg() != Ty->
isVarArg()) ||
131 (ExpectedRtnType != RtnType))
132 WrapperNeeded =
true;
134 for (; AI != AE && PI != PE; ++AI, ++PI) {
136 Type *ParamType = *PI;
138 if (ArgType == ParamType) {
139 Args.push_back(&*AI);
144 BB->getInstList().push_back(PtrCast);
145 Args.push_back(PtrCast);
147 LLVM_DEBUG(
dbgs() <<
"createWrapper: struct param type in bitcast: "
148 <<
F->getName() <<
"\n");
149 WrapperNeeded =
false;
152 <<
F->getName() <<
"\n");
154 << *ParamType <<
" Got: " << *ArgType <<
"\n");
161 if (WrapperNeeded && !TypeMismatch) {
162 for (; PI != PE; ++PI)
165 for (; AI != AE; ++AI)
166 Args.push_back(&*AI);
170 Type *ExpectedRtnType =
F->getFunctionType()->getReturnType();
175 }
else if (ExpectedRtnType->
isVoidTy()) {
176 LLVM_DEBUG(
dbgs() <<
"Creating dummy return: " << *RtnType <<
"\n");
178 }
else if (RtnType == ExpectedRtnType) {
184 BB->getInstList().push_back(Cast);
187 LLVM_DEBUG(
dbgs() <<
"createWrapper: struct return type in bitcast: "
188 <<
F->getName() <<
"\n");
189 WrapperNeeded =
false;
191 LLVM_DEBUG(
dbgs() <<
"createWrapper: return type mismatch calling: "
192 <<
F->getName() <<
"\n");
194 <<
" Got: " << *RtnType <<
"\n");
203 F->getName() +
"_bitcast_invalid",
M);
206 Wrapper->setName(
F->getName() +
"_bitcast_invalid");
207 }
else if (!WrapperNeeded) {
208 LLVM_DEBUG(
dbgs() <<
"createWrapper: no wrapper needed: " <<
F->getName()
228 bool FixFunctionBitcasts::runOnModule(
Module &M) {
229 LLVM_DEBUG(
dbgs() <<
"********** Fix Function Bitcasts **********\n");
247 if (
F.getName() ==
"main") {
255 LLVM_DEBUG(
dbgs() <<
"Found `main` function with incorrect type: "
256 << *
F.getFunctionType() <<
"\n");
262 Uses.push_back(std::make_pair(CallMain, &
F));
269 for (
auto &UseFunc :
Uses) {
274 auto Pair = Wrappers.
insert(std::make_pair(std::make_pair(
F, Ty),
nullptr));
288 Main->
setName(
"__original_main");
299 MainWrapper->setName(
"main");
static bool shouldFixMainFunction(FunctionType *FuncTy, FunctionType *MainTy)
This class represents an incoming formal argument to a Function.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
A parsed version of the target data layout string in and methods for querying it.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
LinkageTypes getLinkage() const
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
The instances of the Type class are immutable: once they are created, they are never changed.
FunctionType * getFunctionType() const
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
static IntegerType * getInt32Ty(LLVMContext &C)
SmallPtrSet< MachineInstr *, 2 > Uses
LLVM Basic Block Representation.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void findUses(Value *V, Function &F, SmallVectorImpl< std::pair< CallBase *, Function * >> &Uses)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static Function * createWrapper(Function *F, FunctionType *Ty)
(vector float) vec_cmpeq(*A, *B) C
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Represent the analysis usage information of a pass.
void setName(const Twine &Name)
Change the name of the value.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Type::subtype_iterator param_iterator
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
VisibilityTypes getVisibility() const
This is an important class for using LLVM in a threaded context.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
bool isVoidTy() const
Return true if this is 'void'.
A Module instance is used to store all the information related to an LLVM module.
INITIALIZE_PASS(FixFunctionBitcasts, DEBUG_TYPE, "Fix mismatching bitcasts for WebAssembly", false, false) ModulePass *llvm
void setPreservesCFG()
This function should be called by the pass, iff they do not:
StringRef - Represent a constant reference to a string, i.e.
Type * getType() const
All values are typed, get the type of this value.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
amdgpu Simplify well known AMD library false FunctionCallee Callee
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Value * getCalledOperand() const
void setCalledOperand(Value *V)
@ PrivateLinkage
Like Internal, but omit from symbol table.
bool isStructTy() const
True if this is an instance of StructType.
ModulePass * createWebAssemblyFixFunctionBitcasts()
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
This function has undefined behavior.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Type * getReturnType() const
LLVM Value Representation.
iterator_range< user_iterator > users()
Class to represent function types.