Commit 26421a71 authored by Matthias Braun's avatar Matthias Braun
Browse files

add unknown_jump opflag for the special case of a jump where we can't directly...

add unknown_jump opflag for the special case of a jump where we can't directly influence the destination and can't predict/change them
parent c038690a
......@@ -591,6 +591,9 @@ FIRM_API ir_node *skip_HighLevel_ops(ir_node *node);
/** Returns true if the operation manipulates control flow:
Start, End, Jmp, Cond, Return, Raise, Bad */
FIRM_API int is_cfop(const ir_node *node);
/** returns true if the operation jumps to an unknown destination.
* See irop_flag_unknown_jump for a detailed explanation */
FIRM_API int is_unknown_jump(const ir_node *node);
/** Returns true if the operation can change the control flow because
of an exception: Call, Div, Mod, Load, Store, Alloc,
......
......@@ -76,7 +76,11 @@ typedef enum {
irop_flag_machine = 1U << 13, /**< This operation is a machine operation. */
irop_flag_machine_op = 1U << 14, /**< This operation is a machine operand. */
irop_flag_cse_neutral = 1U << 15, /**< This operation is CSE neutral to its users. */
irop_flag_user = 1U << 16, /**< This flag and all higher ones are free for machine user. */
/** This operation jumps to an unknown destination. The CFG is a
* conservative aproximation in this case. You cannot change the destination
* of an unknown_jump */
irop_flag_unknown_jump = 1U << 16,
irop_flag_user = 1U << 17, /**< This flag and all higher ones are free for machine user. */
} irop_flags;
/** Returns the ident for the opcode name */
......
......@@ -1096,7 +1096,7 @@ Jmp => {
IJmp => {
state => "pinned",
op_flags => [ "cfopcode" ],
op_flags => [ "cfopcode", "unknown_jump" ],
reg_req => { in => [ "gp", "gp", "none", "gp" ] },
ins => [ "base", "index", "mem", "target" ],
am => "source,unary",
......
......@@ -670,10 +670,10 @@ EOF
}
my %known_flags = map { $_ => 1 } (
"none", "labeled", "commutative", "cfopcode", "op_cfopcode",
"fragile", "forking", "highlevel", "constlike", "always_opt",
"keep", "start_block", "uses_memory", "dump_noblock",
"dump_noinput", "machine", "machine_op", "cse_neutral"
"none", "labeled", "commutative", "cfopcode", "unknown_jump", "fragile",
"forking", "highlevel", "constlike", "always_opt", "keep",
"start_block", "uses_memory", "dump_noblock", "dump_noinput",
"machine", "machine_op", "cse_neutral"
);
foreach my $flag (@{$n{"op_flags"}}) {
if (not defined($known_flags{$flag})) {
......
......@@ -1491,6 +1491,11 @@ int is_cfop(const ir_node *node)
return is_op_cfopcode(get_irn_op(node));
}
int is_unknown_jump(const ir_node *node)
{
return is_op_unknown_jump(get_irn_op(node));
}
/* Returns true if the operation can change the control flow because
of an exception. */
int is_fragile_op(const ir_node *node)
......
......@@ -72,6 +72,11 @@ static inline bool is_op_cfopcode(const ir_op *op)
return op->flags & irop_flag_cfopcode;
}
static inline bool is_op_unknown_jump(const ir_op *op)
{
return op->flags & irop_flag_unknown_jump;
}
/** Returns non-zero if operation is commutative */
static inline bool is_op_commutative(const ir_op *op)
{
......
......@@ -73,7 +73,7 @@ static void walk_critical_cf_edges(ir_node *n, void *env)
continue;
goto insert;
}
if (is_IJmp(pre)) {
if (is_unknown_jump(pre)) {
/* we can't add blocks in between ijmp and its destinations
* TODO: What now, we can't split all critical edges because of this... */
fprintf(stderr, "libfirm warning: Couldn't split all critical edges (compiler will probably fail now)\n");
......
......@@ -535,7 +535,7 @@ class IJmp(Op):
ins = [
("target", "target address of the jump"),
]
flags = [ "cfopcode", "forking", "keep" ]
flags = [ "cfopcode", "forking", "keep", "unknown_jump" ]
class InstOf(Op):
"""Tests whether an object is an instance of a class-type"""
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment