Minor improvements of CodeCompiler

This commit is contained in:
kobalicek
2017-02-02 15:14:07 +01:00
parent ef44e5a2f9
commit ff2bf109fc
5 changed files with 29 additions and 31 deletions

View File

@@ -116,9 +116,11 @@ CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept {
}
// Create helper nodes.
func->_end = newNodeT<CBSentinel>();
func->_exitNode = newLabelNode();
if (!func->_exitNode || !func->_end) goto _NoMemory;
func->_end = newNodeT<CBSentinel>();
if (!func->_exitNode || !func->_end)
goto _NoMemory;
// Function prototype.
err = func->getDetail().init(sign);
@@ -179,9 +181,8 @@ CBSentinel* CodeCompiler::endFunc() {
}
// Add the local constant pool at the end of the function (if exists).
setCursor(func->getExitNode());
if (_localConstPool) {
setCursor(func->getEnd()->getPrev());
addNode(_localConstPool);
_localConstPool = nullptr;
}
@@ -190,8 +191,9 @@ CBSentinel* CodeCompiler::endFunc() {
func->_isFinished = true;
_func = nullptr;
setCursor(func->getEnd());
return func->getEnd();
CBSentinel* end = func->getEnd();
setCursor(end);
return end;
}
// ============================================================================

View File

@@ -292,7 +292,7 @@ public:
//! Get function exit label.
ASMJIT_INLINE Label getExitLabel() const noexcept { return _exitNode->getLabel(); }
//! Get the function end sentinel.
//! Get "End of Func" sentinel.
ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
//! Get function declaration.

View File

@@ -100,7 +100,6 @@ Error RAPass::prepare(CCFunc* func) noexcept {
_func = func;
_stop = end->getNext();
_extraBlock = end;
_unreachableList.reset();
_returningList.reset();
@@ -139,7 +138,6 @@ void RAPass::cleanup() noexcept {
}
_contextVd.reset();
_extraBlock = nullptr;
}
// ============================================================================

View File

@@ -360,11 +360,6 @@ public:
//! Get stop node.
ASMJIT_INLINE CBNode* getStop() const noexcept { return _stop; }
//! Get extra block.
ASMJIT_INLINE CBNode* getExtraBlock() const noexcept { return _extraBlock; }
//! Set extra block.
ASMJIT_INLINE void setExtraBlock(CBNode* node) noexcept { _extraBlock = node; }
// --------------------------------------------------------------------------
// [State]
// --------------------------------------------------------------------------
@@ -524,7 +519,6 @@ public:
CCFunc* _func; //!< Function being processed.
CBNode* _stop; //!< Stop node.
CBNode* _extraBlock; //!< Node that is used to insert extra code after the function body.
//! \internal
//!

View File

@@ -2072,7 +2072,7 @@ _NextGroup:
_Done:
// Mark exit label and end node as fetched, otherwise they can be removed by
// `removeUnreachableCode()`, which would lead to a crash in some later step.
// `removeUnreachableCode()`, which could lead to a crash in some later step.
node_ = func->getEnd();
if (!node_->hasPassData()) {
CBLabel* fExit = func->getExitNode();
@@ -2107,7 +2107,7 @@ Error X86RAPass::annotate() {
StringBuilderTmp<256> sb;
uint32_t maxLen = 0;
while (node_ != end) {
while (node_ && node_ != end) {
if (!node_->hasInlineComment()) {
if (node_->getType() == CBNode::kNodeInst) {
CBInst* node = static_cast<CBInst*>(node_);
@@ -3727,32 +3727,33 @@ static Error X86RAPass_patchFuncMem(X86RAPass* self, CCFunc* func, CBNode* stop,
//! \internal
static void X86RAPass_translateJump(X86RAPass* self, CBJump* jNode, CBLabel* jTarget) {
X86Compiler* cc = self->cc();
CBNode* extNode = self->getExtraBlock();
cc->_setCursor(extNode);
CBNode* injectRef = self->getFunc()->getEnd()->getPrev();
CBNode* prevCursor = cc->setCursor(injectRef);
self->switchState(jTarget->getPassData<RAData>()->state);
// If one or more instruction has been added during switchState() it will be
// moved at the end of the function body.
if (cc->getCursor() != extNode) {
// Any code necessary to `switchState()` will be added at the end of the function.
if (cc->getCursor() != injectRef) {
// TODO: Can fail.
CBLabel* jTrampolineTarget = cc->newLabelNode();
CBLabel* injectLabel = cc->newLabelNode();
// Add the jump to the target.
cc->jmp(jTarget->getLabel());
// Add the trampoline-label we jump to change the state.
extNode = cc->setCursor(extNode);
cc->addNode(jTrampolineTarget);
// Inject the label.
cc->_setCursor(injectRef);
cc->addNode(injectLabel);
// Finally, patch the jump target.
// Finally, patch `jNode` target.
ASMJIT_ASSERT(jNode->getOpCount() > 0);
jNode->_opArray[0] = jTrampolineTarget->getLabel();
jNode->_target = jTrampolineTarget;
jNode->_opArray[jNode->getOpCount() - 1] = injectLabel->getLabel();
jNode->_target = injectLabel;
// If we injected any code it may not satisfy short form anymore.
jNode->delOptions(X86Inst::kOptionShortForm);
}
// Store the `extNode` and load the state back.
self->setExtraBlock(extNode);
cc->_setCursor(prevCursor);
self->loadState(jNode->getPassData<RAData>()->state);
}
@@ -3904,6 +3905,9 @@ _NextGroup:
CBLabel* node = static_cast<CBLabel*>(node_);
ASMJIT_ASSERT(node->getPassData<RAData>()->state == nullptr);
node->getPassData<RAData>()->state = saveState();
if (node == func->getExitNode())
goto _NextGroup;
break;
}