-
Notifications
You must be signed in to change notification settings - Fork 396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Z: Short circuit mem cmp sign macro op #7220
Z: Short circuit mem cmp sign macro op #7220
Conversation
4d2e4b0
to
dea6954
Compare
generateLoop(); | ||
setInRemainder(true); | ||
generateRemainder(); | ||
|
||
_cursor = generateCmpResult(_cg, _rootNode, _dstReg, _srcReg, _resultReg, _falseLabel, _trueLabel, _doneLabel); | ||
TR::RegisterDependencyConditions * dependencies = generateDependencies(); | ||
_cursor->setDependencyConditions(dependencies); | ||
if(_startControlFlow==NULL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if is not necessary any more since the control flow always start from the short circuit instructions
Tested for JDK8 (LoZ and zOS) Axxon 63728, test level.sanity, all tests pass |
compiler/z/codegen/OpMemToMem.cpp
Outdated
if(_startControlFlow->getOpCodeValue() == TR::InstOpCode::assocreg) _startControlFlow=_startControlFlow->getNext(); | ||
} | ||
|
||
_startControlFlow=cursorBefore->getNext(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be the one place where we should be refactoring the code. Couple of things seems wrong to me.
- Internal Control Flow starts with the BRC instruction you are generating for short circuit. So it should now be simple to have startICF label generated, and we do not need to go on after generating all instructions to find startICF.
- I do not think we need to attach post dependency conditions to the start of internal control flow. Your snippet from instruction selection log suggests that we can fix that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your review. I start apply this change right now.
1780f4f
to
bec9bbf
Compare
static TR::Instruction * | ||
generateShortCircuitInstructions(TR::CodeGenerator * cg, TR::Node * node, TR::Register * result, TR::Register * src, TR::Register * dst, TR::LabelSymbol * label) | ||
{ | ||
TR::LabelSymbol * cFlowRegionStart = generateLabelSymbol(cg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Control flow always start here
_startControlFlow=cursorBefore->getNext(); | ||
if(_startControlFlow->getOpCodeValue() == TR::InstOpCode::assocreg) _startControlFlow=_startControlFlow->getNext(); | ||
} | ||
if(_startControlFlow != _cursor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is always a control flow therefore it is not needed
generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionStart, dependencies, _startControlFlow->getPrev()); | ||
cFlowRegionStart->setStartInternalControlFlow(); | ||
TR::RegisterDependencyConditions * dependencies = generateDependencies(); | ||
generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, dependencies); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Control flow ends after generating results. In case of short circuiting, we skip generating results since result reg has the desired value of zero.
@@ -1556,32 +1557,24 @@ MemCmpConstLenMacroOp::generate(TR::Register* dstReg, TR::Register* srcReg, TR:: | |||
_litReg = NULL; | |||
TR::Compilation *comp = _cg->comp(); | |||
|
|||
if (_length == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the length is zero then arrays are equal and we should return zero in result register. No other instructions needed.
Tree structure for variable length arrays:
|
Instruction for constant length array:"
For large arrays (5000 byte length):
|
@r30shah I removed dependency conditions from start of control flow and put the start of control flow right were in insert the first branch. Please let me know if it looks good to you. |
bec9bbf
to
2a0635a
Compare
Tested for JDK8 (LoZ and zOS) Axxon 64107, test level.sanity, all tests pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks @ehsankianifar for testing this through various testing pipelines and looking at the instruction selection snippet, it looks correct.
Jenkins build zos,zlinux |
@hzongaro Can I request you to merge this change based on the testing @ehsankianifar has done (#7220 (comment)) ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked over the code quickly. The changes look good to me, though I'm relying heavily on @r30shah's earlier review. I just have a couple of comments about indenting.
If addresses of two blocks of memory are equal, the content is equal too. We can jump to the end label without comparing the content. Four methods are updated to handle signed and unsigned result as well as constant and variable length. Signed-off-by: Ehsan Kiani Far <ehsan.kianifar@gmail.com>
2a0635a
to
4af016d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Thanks!
x86-64 macOS failure is due to issue #7181. Relevant testing was successful. Merging. |
If the addresses of two arrays are equal, those two arrays are considered equal and we do not need to actually compare those arrays. In this PR, we modified the instructions for x86 and there was a discussion to do the same for other architectures. On Z, it is more complicated and depending on the conditions and expected response, several methods implement array compare.
This change targets memory compare implementation. If the Array cmp asks for a signed response (-1/0/1), the memCmp implementation would be called.