From 5f43f92c69aae9837064cf08291db1b36a82789f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 27 Aug 2007 16:26:13 +0000 Subject: [PATCH] If the source and destination pointers in an llvm.memmove are known to not alias each other, it can be translated as an llvm.memcpy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41489 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGISel.h | 1 + lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 37 +++++++++++++------ test/CodeGen/X86/memmove-0.ll | 9 +++++ test/CodeGen/X86/memmove-1.ll | 9 +++++ test/CodeGen/X86/memmove-2.ll | 9 +++++ test/CodeGen/X86/memmove-3.ll | 9 +++++ 6 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 test/CodeGen/X86/memmove-0.ll create mode 100644 test/CodeGen/X86/memmove-1.ll create mode 100644 test/CodeGen/X86/memmove-2.ll create mode 100644 test/CodeGen/X86/memmove-3.ll diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index de7548596ea..c545dda0ffb 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -39,6 +39,7 @@ public: SSARegMap *RegMap; SelectionDAG *CurDAG; MachineBasicBlock *BB; + AliasAnalysis *AA; std::vector TopOrder; unsigned DAGSize; static char ID; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 12024ff6037..92e34bbc48f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -409,6 +409,7 @@ public: TargetLowering &TLI; SelectionDAG &DAG; const TargetData *TD; + AliasAnalysis &AA; /// SwitchCases - Vector of CaseBlock structures used to communicate /// SwitchInst code generation information. @@ -423,8 +424,9 @@ public: FunctionLoweringInfo &FuncInfo; SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli, + AliasAnalysis &aa, FunctionLoweringInfo &funcinfo) - : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), + : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), AA(aa), FuncInfo(funcinfo) { } @@ -4196,6 +4198,17 @@ void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { unsigned Align = (unsigned)cast(Op4)->getValue(); if (Align == 0) Align = 1; + // If the source and destination are known to not be aliases, we can + // lower memmove as memcpy. + if (Op == ISD::MEMMOVE) { + uint64_t Size = -1; + if (ConstantSDNode *C = dyn_cast(Op3)) + Size = C->getValue(); + if (AA.alias(I.getOperand(1), Size, I.getOperand(2), Size) == + AliasAnalysis::NoAlias) + Op = ISD::MEMCPY; + } + if (ConstantSDNode *Size = dyn_cast(Op3)) { std::vector MemOps; @@ -4307,6 +4320,9 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { bool SelectionDAGISel::runOnFunction(Function &Fn) { + // Get alias analysis for load/store combining. + AA = &getAnalysis(); + MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine()); RegMap = MF.getSSARegMap(); DOUT << "\n\n\n=== " << Fn.getName() << "\n"; @@ -4404,7 +4420,7 @@ static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB, void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, std::vector > &PHINodesToUpdate, FunctionLoweringInfo &FuncInfo) { - SelectionDAGLowering SDL(DAG, TLI, FuncInfo); + SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo); std::vector UnorderedChains; @@ -4581,11 +4597,8 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, } void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { - // Get alias analysis for load/store combining. - AliasAnalysis &AA = getAnalysis(); - // Run the DAG combiner in pre-legalize mode. - DAG.Combine(false, AA); + DAG.Combine(false, *AA); DOUT << "Lowered selection DAG:\n"; DEBUG(DAG.dump()); @@ -4598,7 +4611,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { DEBUG(DAG.dump()); // Run the DAG combiner in post-legalize mode. - DAG.Combine(true, AA); + DAG.Combine(true, *AA); if (ViewISelDAGs) DAG.viewGraph(); @@ -4649,7 +4662,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, if (!BitTestCases[i].Emitted) { SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &HSDAG; - SelectionDAGLowering HSDL(HSDAG, TLI, FuncInfo); + SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo); // Set the current basic block to the mbb we wish to insert the code into BB = BitTestCases[i].Parent; HSDL.setCurrentBasicBlock(BB); @@ -4662,7 +4675,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) { SelectionDAG BSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &BSDAG; - SelectionDAGLowering BSDL(BSDAG, TLI, FuncInfo); + SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo); // Set the current basic block to the mbb we wish to insert the code into BB = BitTestCases[i].Cases[j].ThisBB; BSDL.setCurrentBasicBlock(BB); @@ -4715,7 +4728,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, if (!JTCases[i].first.Emitted) { SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &HSDAG; - SelectionDAGLowering HSDL(HSDAG, TLI, FuncInfo); + SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo); // Set the current basic block to the mbb we wish to insert the code into BB = JTCases[i].first.HeaderBB; HSDL.setCurrentBasicBlock(BB); @@ -4727,7 +4740,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &JSDAG; - SelectionDAGLowering JSDL(JSDAG, TLI, FuncInfo); + SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo); // Set the current basic block to the mbb we wish to insert the code into BB = JTCases[i].second.MBB; JSDL.setCurrentBasicBlock(BB); @@ -4772,7 +4785,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) { SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &SDAG; - SelectionDAGLowering SDL(SDAG, TLI, FuncInfo); + SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo); // Set the current basic block to the mbb we wish to insert the code into BB = SwitchCases[i].ThisBB; diff --git a/test/CodeGen/X86/memmove-0.ll b/test/CodeGen/X86/memmove-0.ll new file mode 100644 index 00000000000..4632aaae72f --- /dev/null +++ b/test/CodeGen/X86/memmove-0.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {call memcpy} + +declare void @llvm.memmove.i64(i8* %d, i8* %s, i64 %l, i32 %a) + +define void @foo(i8* noalias %d, i8* noalias %s, i64 %l) +{ + call void @llvm.memmove.i64(i8* %d, i8* %s, i64 %l, i32 1) + ret void +} diff --git a/test/CodeGen/X86/memmove-1.ll b/test/CodeGen/X86/memmove-1.ll new file mode 100644 index 00000000000..e19ba6f38bc --- /dev/null +++ b/test/CodeGen/X86/memmove-1.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {call memmove} + +declare void @llvm.memmove.i64(i8* %d, i8* %s, i64 %l, i32 %a) + +define void @foo(i8* %d, i8* %s, i64 %l) +{ + call void @llvm.memmove.i64(i8* %d, i8* %s, i64 %l, i32 1) + ret void +} diff --git a/test/CodeGen/X86/memmove-2.ll b/test/CodeGen/X86/memmove-2.ll new file mode 100644 index 00000000000..bb5485ffd9a --- /dev/null +++ b/test/CodeGen/X86/memmove-2.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=x86 | not grep call + +declare void @llvm.memmove.i64(i8* %d, i8* %s, i64 %l, i32 %a) + +define void @foo(i8* noalias %d, i8* noalias %s) +{ + call void @llvm.memmove.i64(i8* %d, i8* %s, i64 32, i32 1) + ret void +} diff --git a/test/CodeGen/X86/memmove-3.ll b/test/CodeGen/X86/memmove-3.ll new file mode 100644 index 00000000000..5e07eade376 --- /dev/null +++ b/test/CodeGen/X86/memmove-3.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {call memmove} + +declare void @llvm.memmove.i64(i8* %d, i8* %s, i64 %l, i32 %a) + +define void @foo(i8* %d, i8* %s) +{ + call void @llvm.memmove.i64(i8* %d, i8* %s, i64 32, i32 1) + ret void +}