mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 04:24:37 +03:00
Minor compiler update - unreachable code remover will not remove labels.
This commit is contained in:
@@ -296,12 +296,26 @@ Error Context::removeUnreachableCode() {
|
|||||||
if (node != first) {
|
if (node != first) {
|
||||||
HLNode* end = node;
|
HLNode* end = node;
|
||||||
node = first;
|
node = first;
|
||||||
|
|
||||||
|
// NOTE: The strategy is as follows:
|
||||||
|
// 1. The algorithm removes everything until it finds a first label.
|
||||||
|
// 2. After the first label is found it removes only removable nodes.
|
||||||
|
bool removeEverything = true;
|
||||||
do {
|
do {
|
||||||
HLNode* next = node->getNext();
|
HLNode* next = node->getNext();
|
||||||
if (!node->isInformative() && node->getType() != HLNode::kTypeAlign) {
|
bool remove = node->isRemovable();
|
||||||
ASMJIT_TLOG("[%05d] Unreachable\n", node->getFlowId());
|
|
||||||
|
if (!remove) {
|
||||||
|
if (node->isLabel())
|
||||||
|
removeEverything = false;
|
||||||
|
remove = removeEverything;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove) {
|
||||||
|
ASMJIT_TLOG("[%05d] Removing unreachable node\n", node->getFlowId());
|
||||||
compiler->removeNode(node);
|
compiler->removeNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = next;
|
node = next;
|
||||||
} while (node != end);
|
} while (node != end);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,28 +105,32 @@ struct HLNode {
|
|||||||
//! is a mark that is set by scheduler after the node has been visited.
|
//! is a mark that is set by scheduler after the node has been visited.
|
||||||
kFlagIsScheduled = 0x0002,
|
kFlagIsScheduled = 0x0002,
|
||||||
|
|
||||||
|
//! Whether the node can be safely removed by the `Compiler` in case it's
|
||||||
|
//! unreachable.
|
||||||
|
kFlagIsRemovable = 0x0004,
|
||||||
|
|
||||||
//! Whether the node is informative only and can be safely removed.
|
//! Whether the node is informative only and can be safely removed.
|
||||||
kFlagIsInformative = 0x0004,
|
kFlagIsInformative = 0x0008,
|
||||||
|
|
||||||
//! Whether the `HLInst` is a jump.
|
//! Whether the `HLInst` is a jump.
|
||||||
kFlagIsJmp = 0x0008,
|
kFlagIsJmp = 0x0010,
|
||||||
//! Whether the `HLInst` is a conditional jump.
|
//! Whether the `HLInst` is a conditional jump.
|
||||||
kFlagIsJcc = 0x0010,
|
kFlagIsJcc = 0x0020,
|
||||||
|
|
||||||
//! Whether the `HLInst` is an unconditinal jump or conditional jump that is
|
//! Whether the `HLInst` is an unconditinal jump or conditional jump that is
|
||||||
//! likely to be taken.
|
//! likely to be taken.
|
||||||
kFlagIsTaken = 0x0020,
|
kFlagIsTaken = 0x0040,
|
||||||
|
|
||||||
//! Whether the `HLNode` will return from a function.
|
//! Whether the `HLNode` will return from a function.
|
||||||
//!
|
//!
|
||||||
//! This flag is used by both `HLSentinel` and `HLRet`.
|
//! This flag is used by both `HLSentinel` and `HLRet`.
|
||||||
kFlagIsRet = 0x0040,
|
kFlagIsRet = 0x0080,
|
||||||
|
|
||||||
//! Whether the instruction is special.
|
//! Whether the instruction is special.
|
||||||
kFlagIsSpecial = 0x0080,
|
kFlagIsSpecial = 0x0100,
|
||||||
|
|
||||||
//! Whether the instruction is an FPU instruction.
|
//! Whether the instruction is an FPU instruction.
|
||||||
kFlagIsFp = 0x0100
|
kFlagIsFp = 0x0200
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -187,9 +191,14 @@ struct HLNode {
|
|||||||
ASMJIT_INLINE bool isTranslated() const noexcept { return hasFlag(kFlagIsTranslated); }
|
ASMJIT_INLINE bool isTranslated() const noexcept { return hasFlag(kFlagIsTranslated); }
|
||||||
//! Get whether the node has been translated.
|
//! Get whether the node has been translated.
|
||||||
ASMJIT_INLINE bool isScheduled() const noexcept { return hasFlag(kFlagIsScheduled); }
|
ASMJIT_INLINE bool isScheduled() const noexcept { return hasFlag(kFlagIsScheduled); }
|
||||||
|
|
||||||
|
//! Get whether the node is removable if it's in unreachable code block.
|
||||||
|
ASMJIT_INLINE bool isRemovable() const noexcept { return hasFlag(kFlagIsRemovable); }
|
||||||
//! Get whether the node is informative only (comment, hint).
|
//! Get whether the node is informative only (comment, hint).
|
||||||
ASMJIT_INLINE bool isInformative() const noexcept { return hasFlag(kFlagIsInformative); }
|
ASMJIT_INLINE bool isInformative() const noexcept { return hasFlag(kFlagIsInformative); }
|
||||||
|
|
||||||
|
//! Whether the node is `HLLabel`.
|
||||||
|
ASMJIT_INLINE bool isLabel() const noexcept { return _type == kTypeLabel; }
|
||||||
//! Whether the `HLInst` node is an unconditional jump.
|
//! Whether the `HLInst` node is an unconditional jump.
|
||||||
ASMJIT_INLINE bool isJmp() const noexcept { return hasFlag(kFlagIsJmp); }
|
ASMJIT_INLINE bool isJmp() const noexcept { return hasFlag(kFlagIsJmp); }
|
||||||
//! Whether the `HLInst` node is a conditional jump.
|
//! Whether the `HLInst` node is a conditional jump.
|
||||||
@@ -326,6 +335,7 @@ struct HLInst : public HLNode {
|
|||||||
ASMJIT_INLINE HLInst(Compiler* compiler, uint32_t instId, uint32_t instOptions, Operand* opList, uint32_t opCount) noexcept
|
ASMJIT_INLINE HLInst(Compiler* compiler, uint32_t instId, uint32_t instOptions, Operand* opList, uint32_t opCount) noexcept
|
||||||
: HLNode(compiler, kTypeInst) {
|
: HLNode(compiler, kTypeInst) {
|
||||||
|
|
||||||
|
orFlags(kFlagIsRemovable);
|
||||||
_instId = static_cast<uint16_t>(instId);
|
_instId = static_cast<uint16_t>(instId);
|
||||||
_reserved = 0;
|
_reserved = 0;
|
||||||
_instOptions = instOptions;
|
_instOptions = instOptions;
|
||||||
@@ -446,8 +456,10 @@ struct HLJump : public HLInst {
|
|||||||
// [Construction / Destruction]
|
// [Construction / Destruction]
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
ASMJIT_INLINE HLJump(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) noexcept :
|
ASMJIT_INLINE HLJump(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) noexcept
|
||||||
HLInst(compiler, code, options, opList, opCount) {}
|
: HLInst(compiler, code, options, opList, opCount),
|
||||||
|
_target(nullptr),
|
||||||
|
_jumpNext(nullptr) {}
|
||||||
ASMJIT_INLINE ~HLJump() noexcept {}
|
ASMJIT_INLINE ~HLJump() noexcept {}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -657,7 +669,7 @@ struct HLComment : public HLNode {
|
|||||||
ASMJIT_INLINE HLComment(Compiler* compiler, const char* comment) noexcept
|
ASMJIT_INLINE HLComment(Compiler* compiler, const char* comment) noexcept
|
||||||
: HLNode(compiler, kTypeComment) {
|
: HLNode(compiler, kTypeComment) {
|
||||||
|
|
||||||
orFlags(kFlagIsInformative);
|
orFlags(kFlagIsRemovable | kFlagIsInformative);
|
||||||
_comment = comment;
|
_comment = comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,7 +692,7 @@ struct HLSentinel : public HLNode {
|
|||||||
//! Create a new `HLSentinel` instance.
|
//! Create a new `HLSentinel` instance.
|
||||||
ASMJIT_INLINE HLSentinel(Compiler* compiler) noexcept
|
ASMJIT_INLINE HLSentinel(Compiler* compiler) noexcept
|
||||||
: HLNode(compiler, kTypeSentinel) {
|
: HLNode(compiler, kTypeSentinel) {
|
||||||
_flags |= kFlagIsRet;
|
orFlags(kFlagIsRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Destroy the `HLSentinel` instance.
|
//! Destroy the `HLSentinel` instance.
|
||||||
@@ -703,7 +715,7 @@ struct HLHint : public HLNode {
|
|||||||
ASMJIT_INLINE HLHint(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) noexcept
|
ASMJIT_INLINE HLHint(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) noexcept
|
||||||
: HLNode(compiler, kTypeHint) {
|
: HLNode(compiler, kTypeHint) {
|
||||||
|
|
||||||
orFlags(kFlagIsInformative);
|
orFlags(kFlagIsRemovable | kFlagIsInformative);
|
||||||
_vd = vd;
|
_vd = vd;
|
||||||
_hint = hint;
|
_hint = hint;
|
||||||
_value = value;
|
_value = value;
|
||||||
@@ -977,7 +989,7 @@ struct HLRet : public HLNode {
|
|||||||
ASMJIT_INLINE HLRet(Compiler* compiler, const Operand& o0, const Operand& o1) noexcept
|
ASMJIT_INLINE HLRet(Compiler* compiler, const Operand& o0, const Operand& o1) noexcept
|
||||||
: HLNode(compiler, kTypeRet) {
|
: HLNode(compiler, kTypeRet) {
|
||||||
|
|
||||||
_flags |= kFlagIsRet;
|
orFlags(kFlagIsRet);
|
||||||
_ret[0] = o0;
|
_ret[0] = o0;
|
||||||
_ret[1] = o1;
|
_ret[1] = o1;
|
||||||
}
|
}
|
||||||
@@ -1024,7 +1036,9 @@ struct HLCall : public HLNode {
|
|||||||
: HLNode(compiler, kTypeCall),
|
: HLNode(compiler, kTypeCall),
|
||||||
_decl(nullptr),
|
_decl(nullptr),
|
||||||
_target(target),
|
_target(target),
|
||||||
_args(nullptr) {}
|
_args(nullptr) {
|
||||||
|
orFlags(kFlagIsRemovable);
|
||||||
|
}
|
||||||
|
|
||||||
//! Destroy the `HLCall` instance.
|
//! Destroy the `HLCall` instance.
|
||||||
ASMJIT_INLINE ~HLCall() noexcept {}
|
ASMJIT_INLINE ~HLCall() noexcept {}
|
||||||
@@ -1096,7 +1110,9 @@ struct HLCallArg : public HLNode {
|
|||||||
_call(call),
|
_call(call),
|
||||||
_sVd(sVd),
|
_sVd(sVd),
|
||||||
_cVd(cVd),
|
_cVd(cVd),
|
||||||
_args(0) {}
|
_args(0) {
|
||||||
|
orFlags(kFlagIsRemovable);
|
||||||
|
}
|
||||||
|
|
||||||
//! Destroy the `HLCallArg` instance.
|
//! Destroy the `HLCallArg` instance.
|
||||||
ASMJIT_INLINE ~HLCallArg() noexcept {}
|
ASMJIT_INLINE ~HLCallArg() noexcept {}
|
||||||
|
|||||||
Reference in New Issue
Block a user