Skip to content

Commit

Permalink
Z: Short circuit memCmp methods if addresses are equal
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
ehsankianifar committed Jan 23, 2024
1 parent a2b3b25 commit 4af016d
Showing 1 changed file with 46 additions and 73 deletions.
119 changes: 46 additions & 73 deletions compiler/z/codegen/OpMemToMem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,20 @@ generateCmpResult(TR::CodeGenerator * cg, TR::Node * rootNode, TR::Register * ds
return cursor;
}

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);
// If "src" equals "dst", "result" would be zero and jumps to "label".
generateRRFInstruction(cg, TR::InstOpCode::getSubtractThreeRegOpCode(), node, result, src, dst);
// This is the first compare and branch instruction therefore control flow starts here.
generateS390LabelInstruction(cg, TR::InstOpCode::label, node, cFlowRegionStart);
cFlowRegionStart->setStartInternalControlFlow();
TR::Instruction * cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRZ, node, label);

return cursor;
}

TR::Instruction *
MemCmpVarLenMacroOp::generate(TR::Register* dstReg, TR::Register* srcReg, TR::Register* tmpReg, int32_t offset, TR::Instruction *cursor)
{
Expand All @@ -1514,32 +1528,19 @@ MemCmpVarLenMacroOp::generate(TR::Register* dstReg, TR::Register* srcReg, TR::Re
_offset = offset;
_cursor = cursor;
_litReg = NULL;
TR::Compilation *comp = _cg->comp();
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

if(cursorBefore == NULL) cursorBefore = _cg->getAppendInstruction();
generateShortCircuitInstructions(_cg, _rootNode, _resultReg, _srcReg, _dstReg, _doneLabel);
generateLoop();
setInRemainder(true);
generateRemainder();

_cursor = generateCmpResult(_cg, _rootNode, _dstReg, _srcReg, _resultReg, _falseLabel, _trueLabel, _doneLabel);
TR::RegisterDependencyConditions * dependencies = generateDependencies();
_cursor->setDependencyConditions(dependencies);
if(_startControlFlow==NULL)
{
_startControlFlow=cursorBefore->getNext();
if(_startControlFlow->getOpCodeValue() == TR::InstOpCode::assocreg) _startControlFlow=_startControlFlow->getNext();
}
if(_startControlFlow != _cursor)
{
TR::LabelSymbol * cFlowRegionStart = generateLabelSymbol(_cg);
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionStart, dependencies, _startControlFlow->getPrev());
cFlowRegionStart->setStartInternalControlFlow();
TR::RegisterDependencyConditions * dependencies = generateDependencies();
generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, dependencies);
cFlowRegionEnd->setEndInternalControlFlow();

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, _cursor->getPrev());
cFlowRegionEnd->setEndInternalControlFlow();
}
return _cursor;
}

Expand All @@ -1556,32 +1557,24 @@ MemCmpConstLenMacroOp::generate(TR::Register* dstReg, TR::Register* srcReg, TR::
_litReg = NULL;
TR::Compilation *comp = _cg->comp();

if (_length == 0)
{
_cursor = generateRRInstruction(_cg, TR::InstOpCode::getXORRegOpCode(), _rootNode, _resultReg, _resultReg);
return _cursor;
}

TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

if(cursorBefore == NULL) cursorBefore = _cg->getAppendInstruction();
generateShortCircuitInstructions(_cg, _rootNode, _resultReg, _srcReg, _dstReg, _doneLabel);
generateLoop();
setInRemainder(true);
generateRemainder();

_cursor = generateCmpResult(_cg, _rootNode, _dstReg, _srcReg, _resultReg, _falseLabel, _trueLabel, _doneLabel);

TR::RegisterDependencyConditions * dependencies = generateDependencies();
_cursor->setDependencyConditions(dependencies);
if(_startControlFlow==NULL)
{
_startControlFlow=cursorBefore->getNext();
if(_startControlFlow->getOpCodeValue() == TR::InstOpCode::assocreg) _startControlFlow=_startControlFlow->getNext();
}
if(_startControlFlow != _cursor)
{
TR::LabelSymbol * cFlowRegionStart = generateLabelSymbol(_cg);
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionStart, dependencies, _startControlFlow->getPrev());
cFlowRegionStart->setStartInternalControlFlow();

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, _cursor->getPrev());
cFlowRegionEnd->setEndInternalControlFlow();
}
generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, dependencies);
cFlowRegionEnd->setEndInternalControlFlow();

return _cursor;
}
Expand Down Expand Up @@ -1651,31 +1644,18 @@ MemCmpVarLenSignMacroOp::generate(TR::Register* dstReg, TR::Register* srcReg, TR
_offset = offset;
_cursor = cursor;
_litReg = NULL;
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

if(cursorBefore == NULL) cursorBefore = _cg->getAppendInstruction();
generateShortCircuitInstructions(_cg, _rootNode, _resultReg, _srcReg, _dstReg, _doneLabel);
generateLoop();
setInRemainder(true);
generateRemainder();

_cursor = generateCmpSignResult(_cg, _rootNode, _dstReg, _srcReg, _resultReg, _falseLabel, _gtLabel, _trueLabel, _doneLabel);
TR::RegisterDependencyConditions * dependencies = generateDependencies();
_cursor->setDependencyConditions(dependencies);
if(_startControlFlow==NULL)
{
_startControlFlow=cursorBefore->getNext();
if(_startControlFlow->getOpCodeValue() == TR::InstOpCode::assocreg) _startControlFlow=_startControlFlow->getNext();
}
if(_startControlFlow != _cursor)
{
TR::LabelSymbol * cFlowRegionStart = generateLabelSymbol(_cg);
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionStart, dependencies, _startControlFlow->getPrev());
cFlowRegionStart->setStartInternalControlFlow();

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, _cursor->getPrev());
cFlowRegionEnd->setEndInternalControlFlow();
}
TR::RegisterDependencyConditions * dependencies = generateDependencies();
generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, dependencies);
cFlowRegionEnd->setEndInternalControlFlow();

return _cursor;
}
Expand All @@ -1699,32 +1679,25 @@ MemCmpConstLenSignMacroOp::generate(TR::Register* dstReg, TR::Register* srcReg,
_offset = offset;
_cursor = cursor;
_litReg = NULL;
TR::Compilation *comp = _cg->comp();

if(cursorBefore == NULL) cursorBefore = _cg->getAppendInstruction();
if (_length == 0)
{
_cursor = generateRRInstruction(_cg, TR::InstOpCode::getXORRegOpCode(), _rootNode, _resultReg, _resultReg);
return _cursor;
}

TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

generateShortCircuitInstructions(_cg, _rootNode, _resultReg, _srcReg, _dstReg, _doneLabel);
generateLoop();
setInRemainder(true);
generateRemainder();

_cursor = generateCmpSignResult(_cg, _rootNode, _dstReg, _srcReg, _resultReg, _falseLabel, _gtLabel, _trueLabel, _doneLabel);
TR::RegisterDependencyConditions * dependencies = generateDependencies();
_cursor->setDependencyConditions(dependencies);
if(_startControlFlow==NULL)
{
_startControlFlow=cursorBefore->getNext();
if(_startControlFlow->getOpCodeValue() == TR::InstOpCode::assocreg) _startControlFlow=_startControlFlow->getNext();
}
if(_startControlFlow != _cursor)
{
TR::LabelSymbol * cFlowRegionStart = generateLabelSymbol(_cg);
TR::LabelSymbol * cFlowRegionEnd = generateLabelSymbol(_cg);

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionStart, dependencies, _startControlFlow->getPrev());
cFlowRegionStart->setStartInternalControlFlow();

generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, _cursor->getPrev());
cFlowRegionEnd->setEndInternalControlFlow();
}
TR::RegisterDependencyConditions * dependencies = generateDependencies();
generateS390LabelInstruction(_cg, TR::InstOpCode::label, _rootNode, cFlowRegionEnd, dependencies);
cFlowRegionEnd->setEndInternalControlFlow();

return _cursor;
}
Expand Down

0 comments on commit 4af016d

Please sign in to comment.