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

View File

@@ -292,7 +292,7 @@ public:
//! Get function exit label. //! Get function exit label.
ASMJIT_INLINE Label getExitLabel() const noexcept { return _exitNode->getLabel(); } 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; } ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
//! Get function declaration. //! Get function declaration.

View File

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

View File

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

View File

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