diff --git a/core/iwasm/compilation/aot_llvm_extra.cpp b/core/iwasm/compilation/aot_llvm_extra.cpp index 1ccb2f549..898fabd8c 100644 --- a/core/iwasm/compilation/aot_llvm_extra.cpp +++ b/core/iwasm/compilation/aot_llvm_extra.cpp @@ -82,43 +82,40 @@ class ExpandMemoryOpPass : public PassInfoMixin PreservedAnalyses ExpandMemoryOpPass::run(Function &F, FunctionAnalysisManager &AM) { - Intrinsic::ID ID = F.getIntrinsicID(); - bool Changed = false; + SmallVector MemCalls; - for (auto I = F.user_begin(), E = F.user_end(); I != E;) { - Instruction *Inst = cast(*I); - ++I; + /* Iterate over all instructions in the function, looking for memcpy, + * memmove, and memset. When we find one, expand it into a loop. */ - switch (ID) { - case Intrinsic::memcpy: - { - auto *Memcpy = cast(Inst); - Function *ParentFunc = Memcpy->getParent()->getParent(); - const TargetTransformInfo &TTI = - AM.getResult(*ParentFunc); - expandMemCpyAsLoop(Memcpy, TTI); - Memcpy->eraseFromParent(); - Changed = true; - break; + for (auto &BB : F) { + for (auto &Inst : BB) { + if (auto *Memcpy = dyn_cast_or_null(&Inst)) { + MemCalls.push_back(Memcpy); } - case Intrinsic::memmove: - { - auto *Memmove = cast(Inst); - expandMemMoveAsLoop(Memmove); - Memmove->eraseFromParent(); - Changed = true; - break; + else if (auto *Memmove = dyn_cast_or_null(&Inst)) { + MemCalls.push_back(Memmove); } - case Intrinsic::memset: - { - auto *Memset = cast(Inst); - expandMemSetAsLoop(Memset); - Memset->eraseFromParent(); - Changed = true; - break; + else if (auto *Memset = dyn_cast_or_null(&Inst)) { + MemCalls.push_back(Memset); } - default: - break; + } + } + + for (MemIntrinsic *MemCall : MemCalls) { + if (MemCpyInst *Memcpy = dyn_cast(MemCall)) { + Function *ParentFunc = Memcpy->getParent()->getParent(); + const TargetTransformInfo &TTI = + AM.getResult(*ParentFunc); + expandMemCpyAsLoop(Memcpy, TTI); + Memcpy->eraseFromParent(); + } + else if (MemMoveInst *Memmove = dyn_cast(MemCall)) { + expandMemMoveAsLoop(Memmove); + Memmove->eraseFromParent(); + } + else if (MemSetInst *Memset = dyn_cast(MemCall)) { + expandMemSetAsLoop(Memset); + Memset->eraseFromParent(); } } @@ -297,13 +294,6 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module) FPM.addPass(SLPVectorizerPass()); FPM.addPass(LoadStoreVectorizerPass()); - /* Run specific passes for AOT indirect mode in last since general - optimization may create some intrinsic function calls like - llvm.memset, so let's remove these function calls here. */ - if (comp_ctx->is_indirect_mode) { - FPM.addPass(ExpandMemoryOpPass()); - } - if (comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file) { /* LICM pass: loop invariant code motion, attempting to remove as much code from the body of a loop as possible. Experiments @@ -341,6 +331,15 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module) else { MPM.addPass(PB.buildPerModuleDefaultPipeline(OL)); } + + /* Run specific passes for AOT indirect mode in last since general + optimization may create some intrinsic function calls like + llvm.memset, so let's remove these function calls here. */ + if (comp_ctx->is_indirect_mode) { + FunctionPassManager FPM1; + FPM1.addPass(ExpandMemoryOpPass()); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM1))); + } } MPM.run(*M, MAM);