mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-13 13:11:25 +00:00
parent
1f89e446d9
commit
ae4069df41
|
@ -2617,64 +2617,6 @@ verify_module(AOTCompContext *comp_ctx)
|
||||||
return true;
|
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
|
bool
|
||||||
aot_compile_wasm(AOTCompContext *comp_ctx)
|
aot_compile_wasm(AOTCompContext *comp_ctx)
|
||||||
{
|
{
|
||||||
|
@ -2714,17 +2656,6 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
|
||||||
possible core dump. */
|
possible core dump. */
|
||||||
bh_print_time("Begin to run llvm optimization passes");
|
bh_print_time("Begin to run llvm optimization passes");
|
||||||
aot_apply_llvm_new_pass_manager(comp_ctx, comp_ctx->module);
|
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");
|
bh_print_time("Finish llvm optimization passes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <llvm/IR/Module.h>
|
#include <llvm/IR/Module.h>
|
||||||
#include <llvm/IR/Instructions.h>
|
#include <llvm/IR/Instructions.h>
|
||||||
#include <llvm/IR/IntrinsicInst.h>
|
#include <llvm/IR/IntrinsicInst.h>
|
||||||
#include <llvm/IR/LegacyPassManager.h>
|
#include <llvm/IR/PassManager.h>
|
||||||
#include <llvm/Support/CommandLine.h>
|
#include <llvm/Support/CommandLine.h>
|
||||||
#include <llvm/Support/ErrorHandling.h>
|
#include <llvm/Support/ErrorHandling.h>
|
||||||
#include <llvm/Target/CodeGenCWrappers.h>
|
#include <llvm/Target/CodeGenCWrappers.h>
|
||||||
|
@ -73,33 +73,14 @@ LLVM_C_EXTERN_C_END
|
||||||
|
|
||||||
ExitOnError ExitOnErr;
|
ExitOnError ExitOnErr;
|
||||||
|
|
||||||
class ExpandMemoryOpPass : public llvm::ModulePass
|
class ExpandMemoryOpPass : public PassInfoMixin<ExpandMemoryOpPass>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static char ID;
|
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||||
|
|
||||||
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>();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
char ExpandMemoryOpPass::ID = 0;
|
PreservedAnalyses
|
||||||
|
ExpandMemoryOpPass::run(Function &F, FunctionAnalysisManager &AM)
|
||||||
bool
|
|
||||||
ExpandMemoryOpPass::expandMemIntrinsicUses(Function &F)
|
|
||||||
{
|
{
|
||||||
Intrinsic::ID ID = F.getIntrinsicID();
|
Intrinsic::ID ID = F.getIntrinsicID();
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
@ -114,27 +95,26 @@ ExpandMemoryOpPass::expandMemIntrinsicUses(Function &F)
|
||||||
auto *Memcpy = cast<MemCpyInst>(Inst);
|
auto *Memcpy = cast<MemCpyInst>(Inst);
|
||||||
Function *ParentFunc = Memcpy->getParent()->getParent();
|
Function *ParentFunc = Memcpy->getParent()->getParent();
|
||||||
const TargetTransformInfo &TTI =
|
const TargetTransformInfo &TTI =
|
||||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
|
AM.getResult<TargetIRAnalysis>(*ParentFunc);
|
||||||
*ParentFunc);
|
|
||||||
expandMemCpyAsLoop(Memcpy, TTI);
|
expandMemCpyAsLoop(Memcpy, TTI);
|
||||||
Changed = true;
|
|
||||||
Memcpy->eraseFromParent();
|
Memcpy->eraseFromParent();
|
||||||
|
Changed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Intrinsic::memmove:
|
case Intrinsic::memmove:
|
||||||
{
|
{
|
||||||
auto *Memmove = cast<MemMoveInst>(Inst);
|
auto *Memmove = cast<MemMoveInst>(Inst);
|
||||||
expandMemMoveAsLoop(Memmove);
|
expandMemMoveAsLoop(Memmove);
|
||||||
Changed = true;
|
|
||||||
Memmove->eraseFromParent();
|
Memmove->eraseFromParent();
|
||||||
|
Changed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Intrinsic::memset:
|
case Intrinsic::memset:
|
||||||
{
|
{
|
||||||
auto *Memset = cast<MemSetInst>(Inst);
|
auto *Memset = cast<MemSetInst>(Inst);
|
||||||
expandMemSetAsLoop(Memset);
|
expandMemSetAsLoop(Memset);
|
||||||
Changed = true;
|
|
||||||
Memset->eraseFromParent();
|
Memset->eraseFromParent();
|
||||||
|
Changed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -142,46 +122,10 @@ ExpandMemoryOpPass::expandMemIntrinsicUses(Function &F)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Changed;
|
PreservedAnalyses PA;
|
||||||
}
|
PA.preserveSet<CFGAnalyses>();
|
||||||
|
|
||||||
bool
|
return PA;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -353,6 +297,13 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
|
||||||
FPM.addPass(SLPVectorizerPass());
|
FPM.addPass(SLPVectorizerPass());
|
||||||
FPM.addPass(LoadStoreVectorizerPass());
|
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) {
|
if (comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file) {
|
||||||
/* LICM pass: loop invariant code motion, attempting to remove
|
/* LICM pass: loop invariant code motion, attempting to remove
|
||||||
as much code from the body of a loop as possible. Experiments
|
as much code from the body of a loop as possible. Experiments
|
||||||
|
|
Loading…
Reference in New Issue
Block a user