forked from OSchip/llvm-project
Allocate AtomicSDNode operands in SelectionDAG's allocator to stop leakage.
SDNode destructors are never called. As an optimization use AtomicSDNode's internal storage if we have a small number of operands. llvm-svn: 191636
This commit is contained in:
parent
fbf4a54a43
commit
c3c807b3bf
|
@ -1073,7 +1073,6 @@ public:
|
|||
///
|
||||
class AtomicSDNode : public MemSDNode {
|
||||
SDUse Ops[4];
|
||||
SDUse* DynOps;
|
||||
|
||||
void InitAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope) {
|
||||
// This must match encodeMemSDNodeFlags() in SelectionDAG.cpp.
|
||||
|
@ -1101,7 +1100,7 @@ public:
|
|||
SDValue Chain, SDValue Ptr,
|
||||
SDValue Cmp, SDValue Swp, MachineMemOperand *MMO,
|
||||
AtomicOrdering Ordering, SynchronizationScope SynchScope)
|
||||
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO), DynOps(NULL) {
|
||||
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
|
||||
InitAtomic(Ordering, SynchScope);
|
||||
InitOperands(Ops, Chain, Ptr, Cmp, Swp);
|
||||
}
|
||||
|
@ -1110,7 +1109,7 @@ public:
|
|||
SDValue Chain, SDValue Ptr,
|
||||
SDValue Val, MachineMemOperand *MMO,
|
||||
AtomicOrdering Ordering, SynchronizationScope SynchScope)
|
||||
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO), DynOps(NULL) {
|
||||
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
|
||||
InitAtomic(Ordering, SynchScope);
|
||||
InitOperands(Ops, Chain, Ptr, Val);
|
||||
}
|
||||
|
@ -1119,21 +1118,19 @@ public:
|
|||
SDValue Chain, SDValue Ptr,
|
||||
MachineMemOperand *MMO,
|
||||
AtomicOrdering Ordering, SynchronizationScope SynchScope)
|
||||
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO), DynOps(NULL) {
|
||||
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
|
||||
InitAtomic(Ordering, SynchScope);
|
||||
InitOperands(Ops, Chain, Ptr);
|
||||
}
|
||||
AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT,
|
||||
SDValue* AllOps, unsigned NumOps,
|
||||
SDValue* AllOps, SDUse *DynOps, unsigned NumOps,
|
||||
MachineMemOperand *MMO,
|
||||
AtomicOrdering Ordering, SynchronizationScope SynchScope)
|
||||
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
|
||||
DynOps = new SDUse[NumOps];
|
||||
InitAtomic(Ordering, SynchScope);
|
||||
InitOperands(DynOps, AllOps, NumOps);
|
||||
}
|
||||
~AtomicSDNode() {
|
||||
delete[] DynOps;
|
||||
assert((DynOps || NumOps <= array_lengthof(Ops)) &&
|
||||
"Too many ops for internal storage!");
|
||||
InitOperands(DynOps ? DynOps : Ops, AllOps, NumOps);
|
||||
}
|
||||
|
||||
const SDValue &getBasePtr() const { return getOperand(1); }
|
||||
|
|
|
@ -4125,10 +4125,18 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT,
|
|||
cast<AtomicSDNode>(E)->refineAlignment(MMO);
|
||||
return SDValue(E, 0);
|
||||
}
|
||||
|
||||
// Allocate the operands array for the node out of the BumpPtrAllocator, since
|
||||
// SDNode doesn't have access to it. This memory will be "leaked" when
|
||||
// the node is deallocated, but recovered when the allocator is released.
|
||||
// If the number of operands is less than 5 we use AtomicSDNode's internal
|
||||
// storage.
|
||||
SDUse *DynOps = NumOps > 4 ? OperandAllocator.Allocate<SDUse>(NumOps) : 0;
|
||||
|
||||
SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl.getIROrder(),
|
||||
dl.getDebugLoc(), VTList, MemVT,
|
||||
Ops, NumOps, MMO, Ordering,
|
||||
SynchScope);
|
||||
Ops, DynOps, NumOps, MMO,
|
||||
Ordering, SynchScope);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
return SDValue(N, 0);
|
||||
|
|
Loading…
Reference in New Issue