mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 15:05:19 +00:00
parent
1f89e446d9
commit
ae4069df41
|
@ -2617,64 +2617,6 @@ verify_module(AOTCompContext *comp_ctx)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Check whether the target supports hardware atomic instructions */
|
||||
static bool
|
||||
aot_require_lower_atomic_pass(AOTCompContext *comp_ctx)
|
||||
{
|
||||
bool ret = false;
|
||||
if (!strncmp(comp_ctx->target_arch, "riscv", 5)) {
|
||||
char *feature =
|
||||
LLVMGetTargetMachineFeatureString(comp_ctx->target_machine);
|
||||
|
||||
if (feature) {
|
||||
if (!strstr(feature, "+a")) {
|
||||
ret = true;
|
||||
}
|
||||
LLVMDisposeMessage(feature);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check whether the target needs to expand switch to if/else */
|
||||
static bool
|
||||
aot_require_lower_switch_pass(AOTCompContext *comp_ctx)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
/* IR switch/case will cause .rodata relocation on riscv/xtensa */
|
||||
if (!strncmp(comp_ctx->target_arch, "riscv", 5)
|
||||
|| !strncmp(comp_ctx->target_arch, "xtensa", 6)) {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
apply_passes_for_indirect_mode(AOTCompContext *comp_ctx)
|
||||
{
|
||||
LLVMPassManagerRef common_pass_mgr;
|
||||
|
||||
if (!(common_pass_mgr = LLVMCreatePassManager())) {
|
||||
aot_set_last_error("create pass manager failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
aot_add_expand_memory_op_pass(common_pass_mgr);
|
||||
|
||||
if (aot_require_lower_atomic_pass(comp_ctx))
|
||||
LLVMAddLowerAtomicPass(common_pass_mgr);
|
||||
|
||||
if (aot_require_lower_switch_pass(comp_ctx))
|
||||
LLVMAddLowerSwitchPass(common_pass_mgr);
|
||||
|
||||
LLVMRunPassManager(common_pass_mgr, comp_ctx->module);
|
||||
|
||||
LLVMDisposePassManager(common_pass_mgr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_wasm(AOTCompContext *comp_ctx)
|
||||
{
|
||||
|
@ -2714,17 +2656,6 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
|
|||
possible core dump. */
|
||||
bh_print_time("Begin to run llvm optimization passes");
|
||||
aot_apply_llvm_new_pass_manager(comp_ctx, comp_ctx->module);
|
||||
|
||||
/* 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_jit_mode && comp_ctx->is_indirect_mode) {
|
||||
bh_print_time("Begin to run optimization passes "
|
||||
"for indirect mode");
|
||||
if (!apply_passes_for_indirect_mode(comp_ctx)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bh_print_time("Finish llvm optimization passes");
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/Instructions.h>
|
||||
#include <llvm/IR/IntrinsicInst.h>
|
||||
#include <llvm/IR/LegacyPassManager.h>
|
||||
#include <llvm/IR/PassManager.h>
|
||||
#include <llvm/Support/CommandLine.h>
|
||||
#include <llvm/Support/ErrorHandling.h>
|
||||
#include <llvm/Target/CodeGenCWrappers.h>
|
||||
|
@ -73,33 +73,14 @@ LLVM_C_EXTERN_C_END
|
|||
|
||||
ExitOnError ExitOnErr;
|
||||
|
||||
class ExpandMemoryOpPass : public llvm::ModulePass
|
||||
class ExpandMemoryOpPass : public PassInfoMixin<ExpandMemoryOpPass>
|
||||
{
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ExpandMemoryOpPass()
|
||||
: ModulePass(ID)
|
||||
{}
|
||||
|
||||
bool runOnModule(Module &M) override;
|
||||
|
||||
bool expandMemIntrinsicUses(Function &F);
|
||||
StringRef getPassName() const override
|
||||
{
|
||||
return "Expand memory operation intrinsics";
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override
|
||||
{
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
}
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
char ExpandMemoryOpPass::ID = 0;
|
||||
|
||||
bool
|
||||
ExpandMemoryOpPass::expandMemIntrinsicUses(Function &F)
|
||||
PreservedAnalyses
|
||||
ExpandMemoryOpPass::run(Function &F, FunctionAnalysisManager &AM)
|
||||
{
|
||||
Intrinsic::ID ID = F.getIntrinsicID();
|
||||
bool Changed = false;
|
||||
|
@ -114,74 +95,37 @@ ExpandMemoryOpPass::expandMemIntrinsicUses(Function &F)
|
|||
auto *Memcpy = cast<MemCpyInst>(Inst);
|
||||
Function *ParentFunc = Memcpy->getParent()->getParent();
|
||||
const TargetTransformInfo &TTI =
|
||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
|
||||
*ParentFunc);
|
||||
AM.getResult<TargetIRAnalysis>(*ParentFunc);
|
||||
expandMemCpyAsLoop(Memcpy, TTI);
|
||||
Changed = true;
|
||||
Memcpy->eraseFromParent();
|
||||
Changed = true;
|
||||
break;
|
||||
}
|
||||
case Intrinsic::memmove:
|
||||
{
|
||||
auto *Memmove = cast<MemMoveInst>(Inst);
|
||||
expandMemMoveAsLoop(Memmove);
|
||||
Changed = true;
|
||||
Memmove->eraseFromParent();
|
||||
Changed = true;
|
||||
break;
|
||||
}
|
||||
case Intrinsic::memset:
|
||||
{
|
||||
auto *Memset = cast<MemSetInst>(Inst);
|
||||
expandMemSetAsLoop(Memset);
|
||||
Changed = true;
|
||||
Memset->eraseFromParent();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
bool
|
||||
ExpandMemoryOpPass::runOnModule(Module &M)
|
||||
{
|
||||
bool Changed = false;
|
||||
|
||||
for (Function &F : M) {
|
||||
if (!F.isDeclaration())
|
||||
continue;
|
||||
|
||||
switch (F.getIntrinsicID()) {
|
||||
case Intrinsic::memcpy:
|
||||
case Intrinsic::memmove:
|
||||
case Intrinsic::memset:
|
||||
if (expandMemIntrinsicUses(F))
|
||||
Changed = true;
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
PreservedAnalyses PA;
|
||||
PA.preserveSet<CFGAnalyses>();
|
||||
|
||||
void
|
||||
aot_add_expand_memory_op_pass(LLVMPassManagerRef pass)
|
||||
{
|
||||
reinterpret_cast<legacy::PassManager *>(pass)->add(
|
||||
new ExpandMemoryOpPass());
|
||||
}
|
||||
|
||||
void
|
||||
aot_add_simple_loop_unswitch_pass(LLVMPassManagerRef pass)
|
||||
{
|
||||
reinterpret_cast<legacy::PassManager *>(pass)->add(
|
||||
createSimpleLoopUnswitchLegacyPass());
|
||||
return PA;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -353,6 +297,13 @@ 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
|
||||
|
|
Loading…
Reference in New Issue
Block a user