Implement atomic and memset/memmove/memcpy intrinsic for riscv (#841)
- Lower aotmic instruction to non-atomic form on some platforms - Lower memset/memmove/memcpy for XIP - Disable rtti in cmake
This commit is contained in:
@ -6,20 +6,29 @@
|
||||
#include <llvm/ADT/SmallVector.h>
|
||||
#include <llvm/ADT/Twine.h>
|
||||
#include <llvm/ADT/Triple.h>
|
||||
#include <llvm/Analysis/TargetTransformInfo.h>
|
||||
#include <llvm/CodeGen/TargetPassConfig.h>
|
||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <llvm/MC/MCSubtargetInfo.h>
|
||||
#include <llvm/Support/TargetSelect.h>
|
||||
#include <llvm/Target/TargetMachine.h>
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/ExecutionEngine.h>
|
||||
#include <llvm-c/Initialization.h>
|
||||
#include <llvm/ExecutionEngine/GenericValue.h>
|
||||
#include <llvm/ExecutionEngine/JITEventListener.h>
|
||||
#include <llvm/ExecutionEngine/RTDyldMemoryManager.h>
|
||||
#include <llvm/IR/DerivedTypes.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/Instructions.h>
|
||||
#include <llvm/IR/IntrinsicInst.h>
|
||||
#include <llvm/IR/LegacyPassManager.h>
|
||||
#include <llvm/Support/CommandLine.h>
|
||||
#include <llvm/Support/ErrorHandling.h>
|
||||
#include <llvm/Target/CodeGenCWrappers.h>
|
||||
#include <llvm/Target/TargetMachine.h>
|
||||
#include <llvm/Target/TargetOptions.h>
|
||||
#include <llvm/Transforms/Utils/LowerMemIntrinsics.h>
|
||||
#include <cstring>
|
||||
|
||||
using namespace llvm;
|
||||
@ -33,6 +42,9 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
||||
extern "C" bool
|
||||
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str);
|
||||
|
||||
extern "C" void
|
||||
aot_add_expand_memory_op_pass(LLVMPassManagerRef pass);
|
||||
|
||||
extern "C" void
|
||||
aot_func_disable_tce(LLVMValueRef func);
|
||||
|
||||
@ -106,6 +118,109 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
||||
return 1;
|
||||
}
|
||||
|
||||
class ExpandMemoryOpPass : public llvm::ModulePass
|
||||
{
|
||||
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>();
|
||||
}
|
||||
};
|
||||
|
||||
char ExpandMemoryOpPass::ID = 0;
|
||||
|
||||
bool
|
||||
ExpandMemoryOpPass::expandMemIntrinsicUses(Function &F)
|
||||
{
|
||||
Intrinsic::ID ID = F.getIntrinsicID();
|
||||
bool Changed = false;
|
||||
|
||||
for (auto I = F.user_begin(), E = F.user_end(); I != E;) {
|
||||
Instruction *Inst = cast<Instruction>(*I);
|
||||
++I;
|
||||
|
||||
switch (ID) {
|
||||
case Intrinsic::memcpy:
|
||||
{
|
||||
auto *Memcpy = cast<MemCpyInst>(Inst);
|
||||
Function *ParentFunc = Memcpy->getParent()->getParent();
|
||||
const TargetTransformInfo &TTI =
|
||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
|
||||
*ParentFunc);
|
||||
expandMemCpyAsLoop(Memcpy, TTI);
|
||||
Changed = true;
|
||||
Memcpy->eraseFromParent();
|
||||
break;
|
||||
}
|
||||
case Intrinsic::memmove:
|
||||
{
|
||||
auto *Memmove = cast<MemMoveInst>(Inst);
|
||||
expandMemMoveAsLoop(Memmove);
|
||||
Changed = true;
|
||||
Memmove->eraseFromParent();
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
aot_add_expand_memory_op_pass(LLVMPassManagerRef pass)
|
||||
{
|
||||
unwrap(pass)->add(new ExpandMemoryOpPass());
|
||||
}
|
||||
|
||||
bool
|
||||
aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user