mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-24 23:28:41 +00:00
Misc optimizer+codegen work for 'cmpxchg' and 'atomicrmw'. They appear to be
working on x86 (at least for trivial testcases); other architectures will need more work so that they actually emit the appropriate instructions for orderings stricter than 'monotonic'. (As far as I can tell, the ARM, PPC, Mips, and Alpha backends need such changes.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136457 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -155,7 +155,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
|
||||
SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
|
||||
N->getMemoryVT(),
|
||||
N->getChain(), N->getBasePtr(),
|
||||
Op2, N->getMemOperand());
|
||||
Op2, N->getMemOperand(), N->getOrdering(),
|
||||
N->getSynchScope());
|
||||
// Legalized the chain result - switch anything that used the old chain to
|
||||
// use the new one.
|
||||
ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
|
||||
@@ -167,7 +168,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) {
|
||||
SDValue Op3 = GetPromotedInteger(N->getOperand(3));
|
||||
SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
|
||||
N->getMemoryVT(), N->getChain(), N->getBasePtr(),
|
||||
Op2, Op3, N->getMemOperand());
|
||||
Op2, Op3, N->getMemOperand(), N->getOrdering(),
|
||||
N->getSynchScope());
|
||||
// Legalized the chain result - switch anything that used the old chain to
|
||||
// use the new one.
|
||||
ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
|
||||
|
@@ -3815,7 +3815,9 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
|
||||
SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
SDValue Chain, SDValue Ptr, SDValue Cmp,
|
||||
SDValue Swp, MachinePointerInfo PtrInfo,
|
||||
unsigned Alignment) {
|
||||
unsigned Alignment,
|
||||
AtomicOrdering Ordering,
|
||||
SynchronizationScope SynchScope) {
|
||||
if (Alignment == 0) // Ensure that codegen never sees alignment 0
|
||||
Alignment = getEVTAlignment(MemVT);
|
||||
|
||||
@@ -3828,13 +3830,16 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
MachineMemOperand *MMO =
|
||||
MF.getMachineMemOperand(PtrInfo, Flags, MemVT.getStoreSize(), Alignment);
|
||||
|
||||
return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Cmp, Swp, MMO);
|
||||
return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Cmp, Swp, MMO,
|
||||
Ordering, SynchScope);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
SDValue Chain,
|
||||
SDValue Ptr, SDValue Cmp,
|
||||
SDValue Swp, MachineMemOperand *MMO) {
|
||||
SDValue Swp, MachineMemOperand *MMO,
|
||||
AtomicOrdering Ordering,
|
||||
SynchronizationScope SynchScope) {
|
||||
assert(Opcode == ISD::ATOMIC_CMP_SWAP && "Invalid Atomic Op");
|
||||
assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types");
|
||||
|
||||
@@ -3851,7 +3856,8 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
return SDValue(E, 0);
|
||||
}
|
||||
SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain,
|
||||
Ptr, Cmp, Swp, MMO);
|
||||
Ptr, Cmp, Swp, MMO, Ordering,
|
||||
SynchScope);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
return SDValue(N, 0);
|
||||
@@ -3861,7 +3867,9 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
SDValue Chain,
|
||||
SDValue Ptr, SDValue Val,
|
||||
const Value* PtrVal,
|
||||
unsigned Alignment) {
|
||||
unsigned Alignment,
|
||||
AtomicOrdering Ordering,
|
||||
SynchronizationScope SynchScope) {
|
||||
if (Alignment == 0) // Ensure that codegen never sees alignment 0
|
||||
Alignment = getEVTAlignment(MemVT);
|
||||
|
||||
@@ -3875,13 +3883,16 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
MF.getMachineMemOperand(MachinePointerInfo(PtrVal), Flags,
|
||||
MemVT.getStoreSize(), Alignment);
|
||||
|
||||
return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Val, MMO);
|
||||
return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Val, MMO,
|
||||
Ordering, SynchScope);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
SDValue Chain,
|
||||
SDValue Ptr, SDValue Val,
|
||||
MachineMemOperand *MMO) {
|
||||
MachineMemOperand *MMO,
|
||||
AtomicOrdering Ordering,
|
||||
SynchronizationScope SynchScope) {
|
||||
assert((Opcode == ISD::ATOMIC_LOAD_ADD ||
|
||||
Opcode == ISD::ATOMIC_LOAD_SUB ||
|
||||
Opcode == ISD::ATOMIC_LOAD_AND ||
|
||||
@@ -3908,7 +3919,8 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
|
||||
return SDValue(E, 0);
|
||||
}
|
||||
SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain,
|
||||
Ptr, Val, MMO);
|
||||
Ptr, Val, MMO,
|
||||
Ordering, SynchScope);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
return SDValue(N, 0);
|
||||
|
@@ -3257,9 +3257,46 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitAtomicCmpXchg(const AtomicCmpXchgInst &I) {
|
||||
SDValue Root = getRoot();
|
||||
SDValue L =
|
||||
DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, getCurDebugLoc(),
|
||||
getValue(I.getCompareOperand()).getValueType().getSimpleVT(),
|
||||
Root,
|
||||
getValue(I.getPointerOperand()),
|
||||
getValue(I.getCompareOperand()),
|
||||
getValue(I.getNewValOperand()),
|
||||
MachinePointerInfo(I.getPointerOperand()), 0 /* Alignment */,
|
||||
I.getOrdering(), I.getSynchScope());
|
||||
setValue(&I, L);
|
||||
DAG.setRoot(L.getValue(1));
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitAtomicRMW(const AtomicRMWInst &I) {
|
||||
ISD::NodeType NT;
|
||||
switch (I.getOperation()) {
|
||||
default: llvm_unreachable("Unknown atomicrmw operation"); return;
|
||||
case AtomicRMWInst::Xchg: NT = ISD::ATOMIC_SWAP; break;
|
||||
case AtomicRMWInst::Add: NT = ISD::ATOMIC_LOAD_ADD; break;
|
||||
case AtomicRMWInst::Sub: NT = ISD::ATOMIC_LOAD_SUB; break;
|
||||
case AtomicRMWInst::And: NT = ISD::ATOMIC_LOAD_AND; break;
|
||||
case AtomicRMWInst::Nand: NT = ISD::ATOMIC_LOAD_NAND; break;
|
||||
case AtomicRMWInst::Or: NT = ISD::ATOMIC_LOAD_OR; break;
|
||||
case AtomicRMWInst::Xor: NT = ISD::ATOMIC_LOAD_XOR; break;
|
||||
case AtomicRMWInst::Max: NT = ISD::ATOMIC_LOAD_MAX; break;
|
||||
case AtomicRMWInst::Min: NT = ISD::ATOMIC_LOAD_MIN; break;
|
||||
case AtomicRMWInst::UMax: NT = ISD::ATOMIC_LOAD_UMAX; break;
|
||||
case AtomicRMWInst::UMin: NT = ISD::ATOMIC_LOAD_UMIN; break;
|
||||
}
|
||||
SDValue L =
|
||||
DAG.getAtomic(NT, getCurDebugLoc(),
|
||||
getValue(I.getValOperand()).getValueType().getSimpleVT(),
|
||||
getRoot(),
|
||||
getValue(I.getPointerOperand()),
|
||||
getValue(I.getValOperand()),
|
||||
I.getPointerOperand(), 0 /* Alignment */,
|
||||
I.getOrdering(), I.getSynchScope());
|
||||
setValue(&I, L);
|
||||
DAG.setRoot(L.getValue(1));
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitFence(const FenceInst &I) {
|
||||
@@ -3410,7 +3447,8 @@ SelectionDAGBuilder::implVisitBinaryAtomic(const CallInst& I,
|
||||
Root,
|
||||
getValue(I.getArgOperand(0)),
|
||||
getValue(I.getArgOperand(1)),
|
||||
I.getArgOperand(0));
|
||||
I.getArgOperand(0), 0 /* Alignment */,
|
||||
Monotonic, CrossThread);
|
||||
setValue(&I, L);
|
||||
DAG.setRoot(L.getValue(1));
|
||||
return 0;
|
||||
@@ -4935,7 +4973,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
getValue(I.getArgOperand(0)),
|
||||
getValue(I.getArgOperand(1)),
|
||||
getValue(I.getArgOperand(2)),
|
||||
MachinePointerInfo(I.getArgOperand(0)));
|
||||
MachinePointerInfo(I.getArgOperand(0)), 0 /* Alignment */,
|
||||
Monotonic, CrossThread);
|
||||
setValue(&I, L);
|
||||
DAG.setRoot(L.getValue(1));
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user