llvm.org GIT mirror llvm / 4eddf94
[FastISel][X86] Add MachineMemOperand to load/store instructions. This commit adds MachineMemOperands to load and store instructions. This allows the peephole optimizer to fold load instructions. Unfortunatelly the peephole optimizer currently doesn't run at -O0. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210858 91177308-0d34-0410-b5e6-96231b3b80d8 Juergen Ributzka 5 years ago
4 changed file(s) with 132 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
376376 /// Test whether the given value has exactly one use.
377377 bool hasTrivialKill(const Value *V) const;
378378
379 /// \brief Create a machine mem operand from the given instruction.
380 MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
381
379382 private:
380383 bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
381384
17361736 return isa(cast(Add)->getOperand(1));
17371737 }
17381738
1739 MachineMemOperand *
1740 FastISel::createMachineMemOperandFor(const Instruction *I) const {
1741 const Value *Ptr;
1742 Type *ValTy;
1743 unsigned Alignment;
1744 unsigned Flags;
1745 bool IsVolatile;
1746
1747 if (const auto *LI = dyn_cast(I)) {
1748 Alignment = LI->getAlignment();
1749 IsVolatile = LI->isVolatile();
1750 Flags = MachineMemOperand::MOLoad;
1751 Ptr = LI->getPointerOperand();
1752 ValTy = LI->getType();
1753 } else if (const auto *SI = dyn_cast(I)) {
1754 Alignment = SI->getAlignment();
1755 IsVolatile = SI->isVolatile();
1756 Flags = MachineMemOperand::MOStore;
1757 Ptr = SI->getPointerOperand();
1758 ValTy = SI->getValueOperand()->getType();
1759 } else {
1760 return nullptr;
1761 }
1762
1763 bool IsNonTemporal = I->getMetadata("nontemporal") != nullptr;
1764 bool IsInvariant = I->getMetadata("invariant.load") != nullptr;
1765 const MDNode *TBAAInfo = I->getMetadata(LLVMContext::MD_tbaa);
1766 const MDNode *Ranges = I->getMetadata(LLVMContext::MD_range);
1767
1768 if (Alignment == 0) // Ensure that codegen never sees alignment 0.
1769 Alignment = DL.getABITypeAlignment(ValTy);
1770
1771 unsigned Size = TM.getDataLayout()->getTypeStoreSize(ValTy);
1772
1773 if (IsVolatile)
1774 Flags |= MachineMemOperand::MOVolatile;
1775 if (IsNonTemporal)
1776 Flags |= MachineMemOperand::MONonTemporal;
1777 if (IsInvariant)
1778 Flags |= MachineMemOperand::MOInvariant;
1779
1780 return FuncInfo.MF->getMachineMemOperand(MachinePointerInfo(Ptr), Flags, Size,
1781 Alignment, TBAAInfo, Ranges);
1782 }
7777 private:
7878 bool X86FastEmitCompare(const Value *LHS, const Value *RHS, EVT VT);
7979
80 bool X86FastEmitLoad(EVT VT, const X86AddressMode &AM, unsigned &RR);
80 bool X86FastEmitLoad(EVT VT, const X86AddressMode &AM, MachineMemOperand *MMO,
81 unsigned &ResultReg);
8182
8283 bool X86FastEmitStore(EVT VT, const Value *Val, const X86AddressMode &AM,
83 bool Aligned = false);
84 bool X86FastEmitStore(EVT VT, unsigned ValReg, const X86AddressMode &AM,
85 bool Aligned = false);
84 MachineMemOperand *MMO = nullptr, bool Aligned = false);
85 bool X86FastEmitStore(EVT VT, unsigned ValReg, bool ValIsKill,
86 const X86AddressMode &AM,
87 MachineMemOperand *MMO = nullptr, bool Aligned = false);
8688
8789 bool X86FastEmitExtend(ISD::NodeType Opc, EVT DstVT, unsigned Src, EVT SrcVT,
8890 unsigned &ResultReg);
179181 /// The address is either pre-computed, i.e. Ptr, or a GlobalAddress, i.e. GV.
180182 /// Return true and the result register by reference if it is possible.
181183 bool X86FastISel::X86FastEmitLoad(EVT VT, const X86AddressMode &AM,
182 unsigned &ResultReg) {
184 MachineMemOperand *MMO, unsigned &ResultReg) {
183185 // Get opcode and regclass of the output for the given load instruction.
184186 unsigned Opc = 0;
185187 const TargetRegisterClass *RC = nullptr;
227229 }
228230
229231 ResultReg = createResultReg(RC);
230 addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
231 DbgLoc, TII.get(Opc), ResultReg), AM);
232 MachineInstrBuilder MIB =
233 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg);
234 addFullAddress(MIB, AM);
235 if (MMO)
236 MIB->addMemOperand(*FuncInfo.MF, MMO);
232237 return true;
233238 }
234239
236241 /// type VT. The address is either pre-computed, consisted of a base ptr, Ptr
237242 /// and a displacement offset, or a GlobalAddress,
238243 /// i.e. V. Return true if it is possible.
239 bool
240 X86FastISel::X86FastEmitStore(EVT VT, unsigned ValReg,
241 const X86AddressMode &AM, bool Aligned) {
244 bool X86FastISel::X86FastEmitStore(EVT VT, unsigned ValReg, bool ValIsKill,
245 const X86AddressMode &AM,
246 MachineMemOperand *MMO, bool Aligned) {
242247 // Get opcode and regclass of the output for the given store instruction.
243248 unsigned Opc = 0;
244249 switch (VT.getSimpleVT().SimpleTy) {
248253 // Mask out all but lowest bit.
249254 unsigned AndResult = createResultReg(&X86::GR8RegClass);
250255 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
251 TII.get(X86::AND8ri), AndResult).addReg(ValReg).addImm(1);
256 TII.get(X86::AND8ri), AndResult)
257 .addReg(ValReg, getKillRegState(ValIsKill)).addImm(1);
252258 ValReg = AndResult;
253259 }
254260 // FALLTHROUGH, handling i1 as i8.
287293 break;
288294 }
289295
290 addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
291 DbgLoc, TII.get(Opc)), AM).addReg(ValReg);
296 MachineInstrBuilder MIB =
297 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
298 addFullAddress(MIB, AM).addReg(ValReg, getKillRegState(ValIsKill));
299 if (MMO)
300 MIB->addMemOperand(*FuncInfo.MF, MMO);
301
292302 return true;
293303 }
294304
295305 bool X86FastISel::X86FastEmitStore(EVT VT, const Value *Val,
296 const X86AddressMode &AM, bool Aligned) {
306 const X86AddressMode &AM,
307 MachineMemOperand *MMO, bool Aligned) {
297308 // Handle 'null' like i32/i64 0.
298309 if (isa(Val))
299310 Val = Constant::getNullValue(DL.getIntPtrType(Val->getContext()));
316327 }
317328
318329 if (Opc) {
319 addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
320 DbgLoc, TII.get(Opc)), AM)
321 .addImm(Signed ? (uint64_t) CI->getSExtValue() :
322 CI->getZExtValue());
330 MachineInstrBuilder MIB =
331 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
332 addFullAddress(MIB, AM).addImm(Signed ? (uint64_t) CI->getSExtValue()
333 : CI->getZExtValue());
334 if (MMO)
335 MIB->addMemOperand(*FuncInfo.MF, MMO);
323336 return true;
324337 }
325338 }
328341 if (ValReg == 0)
329342 return false;
330343
331 return X86FastEmitStore(VT, ValReg, AM, Aligned);
344 bool ValKill = hasTrivialKill(Val);
345 return X86FastEmitStore(VT, ValReg, ValKill, AM, MMO, Aligned);
332346 }
333347
334348 /// X86FastEmitExtend - Emit a machine instruction to extend a value Src of
739753 if (S->isAtomic())
740754 return false;
741755
742 unsigned SABIAlignment =
743 DL.getABITypeAlignment(S->getValueOperand()->getType());
744 bool Aligned = S->getAlignment() == 0 || S->getAlignment() >= SABIAlignment;
756 const Value *Val = S->getValueOperand();
757 const Value *Ptr = S->getPointerOperand();
745758
746759 MVT VT;
747 if (!isTypeLegal(I->getOperand(0)->getType(), VT, /*AllowI1=*/true))
748 return false;
760 if (!isTypeLegal(Val->getType(), VT, /*AllowI1=*/true))
761 return false;
762
763 unsigned Alignment = S->getAlignment();
764 unsigned ABIAlignment = DL.getABITypeAlignment(Val->getType());
765 if (Alignment == 0) // Ensure that codegen never sees alignment 0
766 Alignment = ABIAlignment;
767 bool Aligned = Alignment >= ABIAlignment;
749768
750769 X86AddressMode AM;
751 if (!X86SelectAddress(I->getOperand(1), AM))
752 return false;
753
754 return X86FastEmitStore(VT, I->getOperand(0), AM, Aligned);
770 if (!X86SelectAddress(Ptr, AM))
771 return false;
772
773 return X86FastEmitStore(VT, Val, AM, createMachineMemOperandFor(I), Aligned);
755774 }
756775
757776 /// X86SelectRet - Select and emit code to implement ret instructions.
886905
887906 /// X86SelectLoad - Select and emit code to implement load instructions.
888907 ///
889 bool X86FastISel::X86SelectLoad(const Instruction *I) {
908 bool X86FastISel::X86SelectLoad(const Instruction *I) {
909 const LoadInst *LI = cast(I);
910
890911 // Atomic loads need special handling.
891 if (cast(I)->isAtomic())
912 if (LI->isAtomic())
892913 return false;
893914
894915 MVT VT;
895 if (!isTypeLegal(I->getType(), VT, /*AllowI1=*/true))
896 return false;
916 if (!isTypeLegal(LI->getType(), VT, /*AllowI1=*/true))
917 return false;
918
919 const Value *Ptr = LI->getPointerOperand();
897920
898921 X86AddressMode AM;
899 if (!X86SelectAddress(I->getOperand(0), AM))
922 if (!X86SelectAddress(Ptr, AM))
900923 return false;
901924
902925 unsigned ResultReg = 0;
903 if (X86FastEmitLoad(VT, AM, ResultReg)) {
904 UpdateValueMap(I, ResultReg);
905 return true;
906 }
907 return false;
926 if (!X86FastEmitLoad(VT, AM, createMachineMemOperandFor(LI), ResultReg))
927 return false;
928
929 UpdateValueMap(I, ResultReg);
930 return true;
908931 }
909932
910933 static unsigned X86ChooseCmpOpcode(EVT VT, const X86Subtarget *Subtarget) {
16231646 }
16241647
16251648 unsigned Reg;
1626 bool RV = X86FastEmitLoad(VT, SrcAM, Reg);
1627 RV &= X86FastEmitStore(VT, Reg, DestAM);
1649 bool RV = X86FastEmitLoad(VT, SrcAM, nullptr, Reg);
1650 RV &= X86FastEmitStore(VT, Reg, /*Kill=*/true, DestAM);
16281651 assert(RV && "Failed to emit load or store??");
16291652
16301653 unsigned Size = VT.getSizeInBits()/8;
23212344 if (!X86FastEmitStore(ArgVT, ArgVal, AM))
23222345 return false;
23232346 } else {
2324 if (!X86FastEmitStore(ArgVT, Arg, AM))
2347 if (!X86FastEmitStore(ArgVT, Arg, /*ValIsKill=*/false, AM))
23252348 return false;
23262349 }
23272350 }
27182741
27192742 bool X86FastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
27202743 const LoadInst *LI) {
2744 const Value *Ptr = LI->getPointerOperand();
27212745 X86AddressMode AM;
2722 if (!X86SelectAddress(LI->getOperand(0), AM))
2746 if (!X86SelectAddress(Ptr, AM))
27232747 return false;
27242748
27252749 const X86InstrInfo &XII = (const X86InstrInfo&)TII;
27272751 unsigned Size = DL.getTypeAllocSize(LI->getType());
27282752 unsigned Alignment = LI->getAlignment();
27292753
2754 if (Alignment == 0) // Ensure that codegen never sees alignment 0
2755 Alignment = DL.getABITypeAlignment(LI->getType());
2756
27302757 SmallVector AddrOps;
27312758 AM.getFullAddress(AddrOps);
27322759
27332760 MachineInstr *Result =
27342761 XII.foldMemoryOperandImpl(*FuncInfo.MF, MI, OpNo, AddrOps, Size, Alignment);
2735 if (!Result) return false;
2736
2762 if (!Result)
2763 return false;
2764
2765 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
27372766 FuncInfo.MBB->insert(FuncInfo.InsertPt, Result);
27382767 MI->eraseFromParent();
27392768 return true;
0 ; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s
1 ; RUN: llc < %s -fast-isel -fast-isel-abort -mtriple=x86_64-apple-darwin | FileCheck %s
2
3 define i64 @fold_load(i64* %a, i64 %b) {
4 ; CHECK-LABEL: fold_load
5 ; CHECK: addq (%rdi), %rsi
6 ; CHECK-NEXT: movq %rsi, %rax
7 %1 = load i64* %a, align 8
8 %2 = add i64 %1, %b
9 ret i64 %2
10 }
11