Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

[Arm64] Implement GT_XADD, GT_XCHG, GT_CMPXCHG ...#14329

Merged
briansull merged 3 commits intodotnet:masterfrom
sdmaclea:PR-ARM64-ATOMIC-OPS
Oct 6, 2017
Merged

[Arm64] Implement GT_XADD, GT_XCHG, GT_CMPXCHG ...#14329
briansull merged 3 commits intodotnet:masterfrom
sdmaclea:PR-ARM64-ATOMIC-OPS

Conversation

@sdmaclea
Copy link
Copy Markdown

@sdmaclea sdmaclea commented Oct 4, 2017

Fixes #14106

@dotnet/jit-contrib @dotnet/arm64-contrib PTAL

@sdmaclea sdmaclea force-pushed the PR-ARM64-ATOMIC-OPS branch from f1ef1ff to a6c542e Compare October 4, 2017 22:40
BasicBlock* labelRetry = genCreateTempLabel();
genDefineTempLabel(labelRetry);

getEmitter()->emitIns_R_R(INS_ldaxr, emitTypeSize(treeNode), loadReg, addrReg);
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acquire half barrier

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are going to add this as a comment here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened an issue an added comments

}
getEmitter()->emitInsBinary(ins, emitActualTypeSize(data), &i, data);

getEmitter()->emitIns_R_R_R(INS_stlxr, emitTypeSize(treeNode), exResultReg, storeDataReg, addrReg);
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release half barrier

BasicBlock* labelCompareFail = genCreateTempLabel();
genDefineTempLabel(labelRetry);

getEmitter()->emitIns_R_R(INS_ldaxr, emitTypeSize(treeNode), targetReg, addrReg);
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acquire half barrier

getEmitter()->emitIns_J(INS_bne, labelCompareFail);
}

getEmitter()->emitIns_R_R_R(INS_stlxr, emitTypeSize(treeNode), exResultReg, dataReg, addrReg);
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release half barriers

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Oct 4, 2017

I added barriers because I think they were implied by the existing implementation. I do not know if they are actually required

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Oct 4, 2017

test Windows_NT arm64 Cross Checked Build and Test

BasicBlock* labelRetry = genCreateTempLabel();
genDefineTempLabel(labelRetry);

getEmitter()->emitIns_R_R(INS_ldaxr, emitTypeSize(treeNode), loadReg, addrReg);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are going to add this as a comment here?


// Store exclusive unpredictable cases must be avoided
assert(exResultReg != dataReg);
assert(exResultReg != addrReg);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want some/all of these cases to be noway_asserts.
As assert() only checks things in dbg/chk builds

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed them to asserts during development because I caught them failing and setting minopts

I set most of them back to noway_assert

cmpXchgNode->gtOpLocation->gtLsraInfo.isDelayFree = true;
cmpXchgNode->gtOpValue->gtLsraInfo.isDelayFree = true;
if (!cmpXchgNode->gtOpComparand->isContained())
cmpXchgNode->gtOpComparand->gtLsraInfo.isDelayFree = true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need { } for the then stmt, as per coding conventions.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// it may be used used multiple during retries
tree->gtOp.gtOp1->gtLsraInfo.isDelayFree = true;
if (!tree->gtOp.gtOp2->isContained())
tree->gtOp.gtOp2->gtLsraInfo.isDelayFree = true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need { } for the then stmt, as per coding conventions.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Oct 5, 2017

test Windows_NT arm64 Cross Checked Build and Test

info->hasDelayFreeSrc = true;

// Internals may not collide with target
info->isInternalRegDelayFree = true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CarolEidt might want to take a look and approve this section:

the lifetime of the addr and data must be extended because
 it may be used used multiple during retries

Copy link
Copy Markdown

@CarolEidt CarolEidt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM other than a couple of comment/format issues.


#ifdef _TARGET_XARCH_
#if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
// TODO-ARM-CQ: reenable treating Interlocked operation as intrinsic
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, and below, the corresponding #endifs need to be updated.

regNumber loadReg = (targetReg != REG_NA) ? targetReg : storeDataReg;

// The register allocator should have extended the lifetime of the address
// so that it is not used as the target.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of addressing all of these requirements separately, it would be clearer, I think, to say:

// The register allocator should have extended the lifetimes of all input and internal registers so that
// none interfere with the target.

@sdmaclea
Copy link
Copy Markdown
Author

sdmaclea commented Oct 6, 2017

other than a couple of comment/format issues.

Done

test Windows_NT arm64 Cross Checked Build and Test

@briansull briansull merged commit 77b5ee4 into dotnet:master Oct 6, 2017
@sdmaclea sdmaclea deleted the PR-ARM64-ATOMIC-OPS branch December 4, 2017 16:34
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants