summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ir.h45
-rw-r--r--ir_constant_expression.cpp9
-rw-r--r--ir_constant_folding.cpp7
-rw-r--r--ir_constant_folding.h1
-rw-r--r--ir_print_visitor.cpp7
-rw-r--r--ir_print_visitor.h1
-rw-r--r--ir_visitor.h1
7 files changed, 71 insertions, 0 deletions
diff --git a/ir.h b/ir.h
index 8c533c308a..4266dbc17a 100644
--- a/ir.h
+++ b/ir.h
@@ -532,6 +532,51 @@ public:
private:
ir_rvalue *value;
};
+
+
+/**
+ * Jump instructions used inside loops
+ *
+ * These include \c break and \c continue. The \c break within a loop is
+ * different from the \c break within a switch-statement.
+ *
+ * \sa ir_switch_jump
+ */
+class ir_loop_jump : public ir_jump {
+public:
+ enum jump_mode {
+ jump_break,
+ jump_continue
+ };
+
+ ir_loop_jump(ir_loop *loop, jump_mode mode)
+ : loop(loop), mode(mode)
+ {
+ /* empty */
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ bool is_break() const
+ {
+ return mode == jump_break;
+ }
+
+ bool is_continue() const
+ {
+ return mode == jump_continue;
+ }
+
+private:
+ /** Loop containing this break instruction. */
+ ir_loop *loop;
+
+ /** Mode selector for the jump instruction. */
+ enum jump_mode mode;
+};
/*@}*/
diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp
index a94b0fc9e2..7e1bb030f5 100644
--- a/ir_constant_expression.cpp
+++ b/ir_constant_expression.cpp
@@ -75,6 +75,7 @@ public:
virtual void visit(ir_return *);
virtual void visit(ir_if *);
virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
/*@}*/
/**
@@ -473,3 +474,11 @@ ir_constant_visitor::visit(ir_loop *ir)
(void) ir;
value = NULL;
}
+
+
+void
+ir_constant_visitor::visit(ir_loop_jump *ir)
+{
+ (void) ir;
+ value = NULL;
+}
diff --git a/ir_constant_folding.cpp b/ir_constant_folding.cpp
index d7efdecc45..e43f6f0ea4 100644
--- a/ir_constant_folding.cpp
+++ b/ir_constant_folding.cpp
@@ -152,3 +152,10 @@ ir_constant_folding_visitor::visit(ir_loop *ir)
{
(void) ir;
}
+
+
+void
+ir_constant_folding_visitor::visit(ir_loop_jump *ir)
+{
+ (void) ir;
+}
diff --git a/ir_constant_folding.h b/ir_constant_folding.h
index 382f57c7e5..843b3ad0b7 100644
--- a/ir_constant_folding.h
+++ b/ir_constant_folding.h
@@ -59,5 +59,6 @@ public:
virtual void visit(ir_return *);
virtual void visit(ir_if *);
virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
/*@}*/
};
diff --git a/ir_print_visitor.cpp b/ir_print_visitor.cpp
index 76524261ec..996beaf290 100644
--- a/ir_print_visitor.cpp
+++ b/ir_print_visitor.cpp
@@ -319,3 +319,10 @@ ir_print_visitor::visit(ir_loop *ir)
}
printf("))\n");
}
+
+
+void
+ir_print_visitor::visit(ir_loop_jump *ir)
+{
+ printf("%s", ir->is_break() ? "break" : "continue");
+}
diff --git a/ir_print_visitor.h b/ir_print_visitor.h
index a6365bec7e..82ebbac81f 100644
--- a/ir_print_visitor.h
+++ b/ir_print_visitor.h
@@ -66,6 +66,7 @@ public:
virtual void visit(ir_return *);
virtual void visit(ir_if *);
virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
/*@}*/
private:
diff --git a/ir_visitor.h b/ir_visitor.h
index fab1a75d53..323720e93e 100644
--- a/ir_visitor.h
+++ b/ir_visitor.h
@@ -57,6 +57,7 @@ public:
virtual void visit(class ir_return *) = 0;
virtual void visit(class ir_if *) = 0;
virtual void visit(class ir_loop *) = 0;
+ virtual void visit(class ir_loop_jump *) = 0;
/*@}*/
};