mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Implement x86 support for @llvm.prefetch. It corresponds to prefetcht{0|1|2} and prefetchnta instructions.
llvm-svn: 48042
This commit is contained in:
parent
afeac8050d
commit
dba1dfe962
@ -591,6 +591,11 @@ namespace ISD {
|
||||
// TRAP - Trapping instruction
|
||||
TRAP,
|
||||
|
||||
// PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are
|
||||
// their first operand. The other operands are the address to prefetch,
|
||||
// read / write specifier, and locality specifier.
|
||||
PREFETCH,
|
||||
|
||||
// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load,
|
||||
// store-store, device)
|
||||
// This corresponds to the memory.barrier intrinsic.
|
||||
|
@ -1142,6 +1142,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::PREFETCH:
|
||||
assert(Node->getNumOperands() == 4 && "Invalid Prefetch node!");
|
||||
switch (TLI.getOperationAction(ISD::PREFETCH, MVT::Other)) {
|
||||
default: assert(0 && "This action is not supported yet!");
|
||||
case TargetLowering::Legal:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the address.
|
||||
Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the rw specifier.
|
||||
Tmp4 = LegalizeOp(Node->getOperand(3)); // Legalize locality specifier.
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4);
|
||||
break;
|
||||
case TargetLowering::Expand:
|
||||
// It's a noop.
|
||||
Result = LegalizeOp(Node->getOperand(0));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::MEMBARRIER: {
|
||||
assert(Node->getNumOperands() == 6 && "Invalid MemBarrier node!");
|
||||
switch (TLI.getOperationAction(ISD::MEMBARRIER, MVT::Other)) {
|
||||
|
@ -3788,6 +3788,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
return "<<Unknown Target Node>>";
|
||||
}
|
||||
|
||||
case ISD::PREFETCH: return "Prefetch";
|
||||
case ISD::MEMBARRIER: return "MemBarrier";
|
||||
case ISD::ATOMIC_LCS: return "AtomicLCS";
|
||||
case ISD::ATOMIC_LAS: return "AtomicLAS";
|
||||
|
@ -2996,10 +2996,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, MVT::Other, getRoot(), Tmp));
|
||||
return 0;
|
||||
}
|
||||
case Intrinsic::prefetch:
|
||||
// FIXME: Currently discarding prefetches.
|
||||
return 0;
|
||||
|
||||
case Intrinsic::var_annotation:
|
||||
// Discard annotate attributes
|
||||
return 0;
|
||||
@ -3050,6 +3046,16 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot()));
|
||||
return 0;
|
||||
}
|
||||
case Intrinsic::prefetch: {
|
||||
SDOperand Ops[4];
|
||||
Ops[0] = getRoot();
|
||||
Ops[1] = getValue(I.getOperand(1));
|
||||
Ops[2] = getValue(I.getOperand(2));
|
||||
Ops[3] = getValue(I.getOperand(3));
|
||||
DAG.setRoot(DAG.getNode(ISD::PREFETCH, MVT::Other, &Ops[0], 4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case Intrinsic::memory_barrier: {
|
||||
SDOperand Ops[6];
|
||||
Ops[0] = getRoot();
|
||||
|
@ -211,6 +211,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
|
||||
setOperationAction(ISD::MEMBARRIER , MVT::Other, Expand);
|
||||
setOperationAction(ISD::PREFETCH , MVT::Other, Expand);
|
||||
|
||||
if (!Subtarget->hasV6Ops()) {
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
|
||||
|
@ -117,6 +117,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
|
||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
|
||||
setOperationAction(ISD::PREFETCH, MVT::Other, Expand);
|
||||
|
||||
// We want to legalize GlobalAddress and ConstantPool and
|
||||
// ExternalSymbols nodes into the appropriate instructions to
|
||||
|
@ -321,6 +321,7 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
|
||||
setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64 , Expand);
|
||||
setOperationAction(ISD::PREFETCH , MVT::Other, Expand);
|
||||
|
||||
// Cell SPU has instructions for converting between i64 and fp.
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
||||
|
@ -110,6 +110,7 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
|
||||
setOperationAction(ISD::PREFETCH , MVT::Other, Expand);
|
||||
|
||||
// Thread Local Storage
|
||||
setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
|
||||
|
@ -85,6 +85,7 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
|
||||
setOperationAction(ISD::MEMSET, MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
|
||||
setOperationAction(ISD::PREFETCH, MVT::Other, Expand);
|
||||
|
||||
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
|
||||
setOperationAction(ISD::CTTZ , MVT::i32, Expand);
|
||||
|
@ -82,6 +82,7 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
|
||||
setOperationAction(ISD::MEMSET, MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
|
||||
setOperationAction(ISD::PREFETCH, MVT::Other, Expand);
|
||||
|
||||
// PowerPC has no SREM/UREM instructions
|
||||
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
||||
|
@ -197,6 +197,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::MEMSET, MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
|
||||
setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
|
||||
setOperationAction(ISD::PREFETCH, MVT::Other, Expand);
|
||||
|
||||
setOperationAction(ISD::FSIN , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FCOS , MVT::f64, Expand);
|
||||
|
@ -185,7 +185,11 @@ def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert
|
||||
SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
|
||||
]>;
|
||||
|
||||
def STDMemBarrier : SDTypeProfile<0, 5, [
|
||||
def STDPrefetch : SDTypeProfile<0, 3, [ // prefetch
|
||||
SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1>
|
||||
]>;
|
||||
|
||||
def STDMemBarrier : SDTypeProfile<0, 5, [ // memory barier
|
||||
SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>,
|
||||
SDTCisInt<0>
|
||||
]>;
|
||||
@ -340,12 +344,17 @@ def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
|
||||
def ret : SDNode<"ISD::RET" , SDTNone, [SDNPHasChain]>;
|
||||
def trap : SDNode<"ISD::TRAP" , SDTNone,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
def prefetch : SDNode<"ISD::PREFETCH" , STDPrefetch,
|
||||
[SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
|
||||
|
||||
def membarrier : SDNode<"ISD::MEMBARRIER" , STDMemBarrier,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
// Do not use atomic_* directly, use atomic_*_size (see below)
|
||||
def atomic_lcs : SDNode<"ISD::ATOMIC_LCS", STDAtomic3,
|
||||
def atomic_lcs : SDNode<"ISD::ATOMIC_LCS" , STDAtomic3,
|
||||
[SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
|
||||
def atomic_las : SDNode<"ISD::ATOMIC_LAS", STDAtomic2,
|
||||
def atomic_las : SDNode<"ISD::ATOMIC_LAS" , STDAtomic2,
|
||||
[SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
|
||||
def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", STDAtomic2,
|
||||
[SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
|
||||
|
@ -287,6 +287,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::MEMSET , MVT::Other, Custom);
|
||||
setOperationAction(ISD::MEMCPY , MVT::Other, Custom);
|
||||
|
||||
if (!Subtarget->hasSSE1())
|
||||
setOperationAction(ISD::PREFETCH , MVT::Other, Expand);
|
||||
|
||||
if (!Subtarget->hasSSE2())
|
||||
setOperationAction(ISD::MEMBARRIER , MVT::Other, Expand);
|
||||
|
||||
|
@ -939,12 +939,15 @@ def MOVMSKPDrr : PSI<0x50, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
|
||||
"movmskpd\t{$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, (int_x86_sse2_movmsk_pd VR128:$src))]>;
|
||||
|
||||
// Prefetching loads.
|
||||
// TODO: no intrinsics for these?
|
||||
def PREFETCHT0 : PSI<0x18, MRM1m, (outs), (ins i8mem:$src), "prefetcht0\t$src", []>;
|
||||
def PREFETCHT1 : PSI<0x18, MRM2m, (outs), (ins i8mem:$src), "prefetcht1\t$src", []>;
|
||||
def PREFETCHT2 : PSI<0x18, MRM3m, (outs), (ins i8mem:$src), "prefetcht2\t$src", []>;
|
||||
def PREFETCHNTA : PSI<0x18, MRM0m, (outs), (ins i8mem:$src), "prefetchnta\t$src", []>;
|
||||
// Prefetch intrinsic.
|
||||
def PREFETCHT0 : PSI<0x18, MRM1m, (outs), (ins i8mem:$src),
|
||||
"prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3))]>;
|
||||
def PREFETCHT1 : PSI<0x18, MRM2m, (outs), (ins i8mem:$src),
|
||||
"prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2))]>;
|
||||
def PREFETCHT2 : PSI<0x18, MRM3m, (outs), (ins i8mem:$src),
|
||||
"prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1))]>;
|
||||
def PREFETCHNTA : PSI<0x18, MRM0m, (outs), (ins i8mem:$src),
|
||||
"prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0))]>;
|
||||
|
||||
// Non-temporal stores
|
||||
def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
|
||||
|
15
test/CodeGen/X86/prefetch.ll
Normal file
15
test/CodeGen/X86/prefetch.ll
Normal file
@ -0,0 +1,15 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse1 | grep prefetchnta
|
||||
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse1 | grep prefetcht0
|
||||
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse1 | grep prefetcht1
|
||||
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse1 | grep prefetcht2
|
||||
|
||||
define void @t(i8* %ptr) nounwind {
|
||||
entry:
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 1 )
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 2 )
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 3 )
|
||||
tail call void @llvm.prefetch( i8* %ptr, i32 0, i32 0 )
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.prefetch(i8*, i32, i32) nounwind
|
Loading…
Reference in New Issue
Block a user