src/share/vm/c1/c1_Instruction.hpp
Print this page
@@ -114,10 +114,17 @@
public:
virtual void block_do(BlockBegin* block) = 0;
};
+// A simple closure class for visiting the values of an Instruction
+class ValueVisitor: public StackObj {
+ public:
+ virtual void visit(Value* v) = 0;
+};
+
+
// Some array and list classes
define_array(BlockBeginArray, BlockBegin*)
define_stack(_BlockList, BlockBeginArray)
class BlockList: public _BlockList {
@@ -127,11 +134,11 @@
BlockList(const int size, BlockBegin* init): _BlockList(size, init) {}
void iterate_forward(BlockClosure* closure);
void iterate_backward(BlockClosure* closure);
void blocks_do(void f(BlockBegin*));
- void values_do(void f(Value*));
+ void values_do(ValueVisitor* f);
void print(bool cfg_only = false, bool live_only = false) PRODUCT_RETURN;
};
// InstructionVisitors provide type-based dispatch for instructions.
@@ -262,12 +269,10 @@
// The mother of all instructions...
class Instruction: public CompilationResourceObj {
private:
- static int _next_id; // the node counter
-
int _id; // the unique instruction id
int _bci; // the instruction bci
int _use_count; // the number of instructions refering to this value (w/o prev/next); only roots can have use count = 0 or > 1
int _pin_state; // set of PinReason describing the reason for pinning
ValueType* _type; // the instruction value type
@@ -281,19 +286,27 @@
#ifdef ASSERT
HiWord* _hi_word;
#endif
friend class UseCountComputer;
+ friend class BlockBegin;
protected:
void set_bci(int bci) { assert(bci == SynchronizationEntryBCI || bci >= 0, "illegal bci"); _bci = bci; }
void set_type(ValueType* type) {
assert(type != NULL, "type must exist");
_type = type;
}
public:
+ void* operator new(size_t size) {
+ Compilation* c = Compilation::current();
+ void* res = c->arena()->Amalloc(size);
+ ((Instruction*)res)->_id = c->get_next_id();
+ return res;
+ }
+
enum InstructionFlag {
NeedsNullCheckFlag = 0,
CanTrapFlag,
DirectCompareFlag,
IsEliminatedFlag,
@@ -336,17 +349,17 @@
static Condition mirror(Condition cond);
static Condition negate(Condition cond);
// initialization
- static void initialize() { _next_id = 0; }
- static int number_of_instructions() { return _next_id; }
+ static int number_of_instructions() {
+ return Compilation::current()->number_of_instructions();
+ }
// creation
Instruction(ValueType* type, bool type_is_constant = false, bool create_hi = true)
- : _id(_next_id++)
- , _bci(-99)
+ : _bci(-99)
, _use_count(0)
, _pin_state(0)
, _type(type)
, _next(NULL)
, _subst(NULL)
@@ -477,14 +490,14 @@
virtual void visit(InstructionVisitor* v) = 0;
virtual bool can_trap() const { return false; }
- virtual void input_values_do(void f(Value*)) = 0;
- virtual void state_values_do(void f(Value*)) { /* usually no state - override on demand */ }
- virtual void other_values_do(void f(Value*)) { /* usually no other - override on demand */ }
- void values_do(void f(Value*)) { input_values_do(f); state_values_do(f); other_values_do(f); }
+ virtual void input_values_do(ValueVisitor* f) = 0;
+ virtual void state_values_do(ValueVisitor* f) { /* usually no state - override on demand */ }
+ virtual void other_values_do(ValueVisitor* f) { /* usually no other - override on demand */ }
+ void values_do(ValueVisitor* f) { input_values_do(f); state_values_do(f); other_values_do(f); }
virtual ciType* exact_type() const { return NULL; }
virtual ciType* declared_type() const { return NULL; }
// hashing
@@ -515,13 +528,16 @@
virtual void visit(InstructionVisitor* v) { v->do_##class_name(this); } \
// Debugging support
+
#ifdef ASSERT
- static void assert_value(Value* x) { assert((*x) != NULL, "value must exist"); }
- #define ASSERT_VALUES values_do(assert_value);
+class AssertValues: public ValueVisitor {
+ void visit(Value* x) { assert((*x) != NULL, "value must exist"); }
+};
+ #define ASSERT_VALUES { AssertValues assert_value; values_do(&assert_value); }
#else
#define ASSERT_VALUES
#endif // ASSERT
@@ -553,11 +569,11 @@
// for invalidating of HiWords
void make_illegal() { set_type(illegalType); }
// generic
- virtual void input_values_do(void f(Value*)) { ShouldNotReachHere(); }
+ virtual void input_values_do(ValueVisitor* f) { ShouldNotReachHere(); }
};
// A Phi is a phi function in the sense of SSA form. It stands for
// the value of a local variable at the beginning of a join block.
@@ -613,11 +629,11 @@
bool is_illegal() const {
return type()->is_illegal();
}
// generic
- virtual void input_values_do(void f(Value*)) {
+ virtual void input_values_do(ValueVisitor* f) {
}
};
// A local is a placeholder for an incoming argument to a function call.
@@ -633,11 +649,11 @@
// accessors
int java_index() const { return _java_index; }
// generic
- virtual void input_values_do(void f(Value*)) { /* no values */ }
+ virtual void input_values_do(ValueVisitor* f) { /* no values */ }
};
LEAF(Constant, Instruction)
ValueStack* _state;
@@ -661,12 +677,12 @@
ValueStack* state() const { return _state; }
// generic
virtual bool can_trap() const { return state() != NULL; }
- virtual void input_values_do(void f(Value*)) { /* no values */ }
- virtual void other_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { /* no values */ }
+ virtual void other_values_do(ValueVisitor* f);
virtual intx hash() const;
virtual bool is_equal(Value v) const;
virtual BlockBegin* compare(Instruction::Condition condition, Value right,
@@ -732,12 +748,12 @@
// if needs_null_check() is true.
void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; }
// generic
virtual bool can_trap() const { return needs_null_check() || needs_patching(); }
- virtual void input_values_do(void f(Value*)) { f(&_obj); }
- virtual void other_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_obj); }
+ virtual void other_values_do(ValueVisitor* f);
};
LEAF(LoadField, AccessField)
public:
@@ -774,11 +790,11 @@
// accessors
Value value() const { return _value; }
bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); }
// generic
- virtual void input_values_do(void f(Value*)) { AccessField::input_values_do(f); f(&_value); }
+ virtual void input_values_do(ValueVisitor* f) { AccessField::input_values_do(f); f->visit(&_value); }
};
BASE(AccessArray, Instruction)
private:
@@ -802,12 +818,12 @@
// setters
void set_lock_stack(ValueStack* l) { _lock_stack = l; }
// generic
virtual bool can_trap() const { return needs_null_check(); }
- virtual void input_values_do(void f(Value*)) { f(&_array); }
- virtual void other_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_array); }
+ virtual void other_values_do(ValueVisitor* f);
};
LEAF(ArrayLength, AccessArray)
private:
@@ -855,11 +871,11 @@
// perform elimination of range checks involving constants
bool compute_needs_range_check();
// generic
- virtual void input_values_do(void f(Value*)) { AccessArray::input_values_do(f); f(&_index); if (_length != NULL) f(&_length); }
+ virtual void input_values_do(ValueVisitor* f) { AccessArray::input_values_do(f); f->visit(&_index); if (_length != NULL) f->visit(&_length); }
};
LEAF(LoadIndexed, AccessIndexed)
private:
@@ -907,11 +923,11 @@
IRScope* scope() const; // the state's scope
bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); }
bool needs_store_check() const { return check_flag(NeedsStoreCheckFlag); }
// generic
- virtual void input_values_do(void f(Value*)) { AccessIndexed::input_values_do(f); f(&_value); }
+ virtual void input_values_do(ValueVisitor* f) { AccessIndexed::input_values_do(f); f->visit(&_value); }
};
LEAF(NegateOp, Instruction)
private:
@@ -925,11 +941,11 @@
// accessors
Value x() const { return _x; }
// generic
- virtual void input_values_do(void f(Value*)) { f(&_x); }
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_x); }
};
BASE(Op2, Instruction)
private:
@@ -954,11 +970,11 @@
Value t = _x; _x = _y; _y = t;
}
// generic
virtual bool is_commutative() const { return false; }
- virtual void input_values_do(void f(Value*)) { f(&_x); f(&_y); }
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_x); f->visit(&_y); }
};
LEAF(ArithmeticOp, Op2)
private:
@@ -980,11 +996,11 @@
void set_lock_stack(ValueStack* l) { _lock_stack = l; }
// generic
virtual bool is_commutative() const;
virtual bool can_trap() const;
- virtual void other_values_do(void f(Value*));
+ virtual void other_values_do(ValueVisitor* f);
HASHING3(Op2, true, op(), x()->subst(), y()->subst())
};
LEAF(ShiftOp, Op2)
@@ -1021,11 +1037,11 @@
// accessors
ValueStack* state_before() const { return _state_before; }
// generic
HASHING3(Op2, true, op(), x()->subst(), y()->subst())
- virtual void other_values_do(void f(Value*));
+ virtual void other_values_do(ValueVisitor* f);
};
LEAF(IfOp, Op2)
private:
@@ -1049,11 +1065,11 @@
Condition cond() const { return (Condition)Op2::op(); }
Value tval() const { return _tval; }
Value fval() const { return _fval; }
// generic
- virtual void input_values_do(void f(Value*)) { Op2::input_values_do(f); f(&_tval); f(&_fval); }
+ virtual void input_values_do(ValueVisitor* f) { Op2::input_values_do(f); f->visit(&_tval); f->visit(&_fval); }
};
LEAF(Convert, Instruction)
private:
@@ -1069,11 +1085,11 @@
// accessors
Bytecodes::Code op() const { return _op; }
Value value() const { return _value; }
// generic
- virtual void input_values_do(void f(Value*)) { f(&_value); }
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_value); }
HASHING2(Convert, true, op(), value()->subst())
};
LEAF(NullCheck, Instruction)
@@ -1098,12 +1114,12 @@
void set_lock_stack(ValueStack* l) { _lock_stack = l; }
void set_can_trap(bool can_trap) { set_flag(CanTrapFlag, can_trap); }
// generic
virtual bool can_trap() const { return check_flag(CanTrapFlag); /* null-check elimination sets to false */ }
- virtual void input_values_do(void f(Value*)) { f(&_obj); }
- virtual void other_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_obj); }
+ virtual void other_values_do(ValueVisitor* f);
HASHING1(NullCheck, true, obj()->subst())
};
BASE(StateSplit, Instruction)
@@ -1125,12 +1141,12 @@
// manipulation
void set_state(ValueStack* state) { _state = state; }
// generic
- virtual void input_values_do(void f(Value*)) { /* no values */ }
- virtual void state_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { /* no values */ }
+ virtual void state_values_do(ValueVisitor* f);
};
LEAF(Invoke, StateSplit)
private:
@@ -1167,16 +1183,16 @@
// JSR 292 support
bool is_invokedynamic() const { return code() == Bytecodes::_invokedynamic; }
// generic
virtual bool can_trap() const { return true; }
- virtual void input_values_do(void f(Value*)) {
+ virtual void input_values_do(ValueVisitor* f) {
StateSplit::input_values_do(f);
- if (has_receiver()) f(&_recv);
- for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i));
+ if (has_receiver()) f->visit(&_recv);
+ for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i));
}
- virtual void state_values_do(void f(Value*));
+ virtual void state_values_do(ValueVisitor *f);
};
LEAF(NewInstance, StateSplit)
private:
@@ -1210,12 +1226,12 @@
ValueStack* state_before() const { return _state_before; }
Value length() const { return _length; }
// generic
virtual bool can_trap() const { return true; }
- virtual void input_values_do(void f(Value*)) { StateSplit::input_values_do(f); f(&_length); }
- virtual void other_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_length); }
+ virtual void other_values_do(ValueVisitor* f);
};
LEAF(NewTypeArray, NewArray)
private:
@@ -1260,19 +1276,19 @@
ciKlass* klass() const { return _klass; }
Values* dims() const { return _dims; }
int rank() const { return dims()->length(); }
// generic
- virtual void input_values_do(void f(Value*)) {
+ virtual void input_values_do(ValueVisitor* f) {
// NOTE: we do not call NewArray::input_values_do since "length"
// is meaningless for a multi-dimensional array; passing the
// zeroth element down to NewArray as its length is a bad idea
// since there will be a copy in the "dims" array which doesn't
// get updated, and the value must not be traversed twice. Was bug
// - kbr 4/10/2001
StateSplit::input_values_do(f);
- for (int i = 0; i < _dims->length(); i++) f(_dims->adr_at(i));
+ for (int i = 0; i < _dims->length(); i++) f->visit(_dims->adr_at(i));
}
};
BASE(TypeCheck, StateSplit)
@@ -1298,12 +1314,12 @@
// manipulation
void set_direct_compare(bool flag) { set_flag(DirectCompareFlag, flag); }
// generic
virtual bool can_trap() const { return true; }
- virtual void input_values_do(void f(Value*)) { StateSplit::input_values_do(f); f(&_obj); }
- virtual void other_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_obj); }
+ virtual void other_values_do(ValueVisitor* f);
};
LEAF(CheckCast, TypeCheck)
private:
@@ -1364,11 +1380,11 @@
// accessors
Value obj() const { return _obj; }
int monitor_no() const { return _monitor_no; }
// generic
- virtual void input_values_do(void f(Value*)) { StateSplit::input_values_do(f); f(&_obj); }
+ virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_obj); }
};
LEAF(MonitorEnter, AccessMonitor)
private:
@@ -1383,11 +1399,11 @@
ASSERT_VALUES
}
// accessors
ValueStack* lock_stack_before() const { return _lock_stack_before; }
- virtual void state_values_do(void f(Value*));
+ virtual void state_values_do(ValueVisitor* f);
// generic
virtual bool can_trap() const { return true; }
};
@@ -1452,25 +1468,23 @@
Value receiver() const { assert(has_receiver(), "must have receiver"); return _recv; }
bool preserves_state() const { return check_flag(PreservesStateFlag); }
// generic
virtual bool can_trap() const { return check_flag(CanTrapFlag); }
- virtual void input_values_do(void f(Value*)) {
+ virtual void input_values_do(ValueVisitor* f) {
StateSplit::input_values_do(f);
- for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i));
+ for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i));
}
- virtual void state_values_do(void f(Value*));
+ virtual void state_values_do(ValueVisitor* f);
};
class LIR_List;
LEAF(BlockBegin, StateSplit)
private:
- static int _next_block_id; // the block counter
-
int _block_id; // the unique block id
int _depth_first_number; // number of this block in a depth-first ordering
int _linear_scan_number; // number of this block in linear-scan ordering
int _loop_depth; // the loop nesting level of this block
int _loop_index; // number of the innermost loop of this block
@@ -1508,18 +1522,26 @@
void iterate_postorder(boolArray& mark, BlockClosure* closure);
friend class SuxAndWeightAdjuster;
public:
+ void* operator new(size_t size) {
+ Compilation* c = Compilation::current();
+ void* res = c->arena()->Amalloc(size);
+ ((BlockBegin*)res)->_id = c->get_next_id();
+ ((BlockBegin*)res)->_block_id = c->get_next_block_id();
+ return res;
+ }
+
// initialization/counting
- static void initialize() { _next_block_id = 0; }
- static int number_of_blocks() { return _next_block_id; }
+ static int number_of_blocks() {
+ return Compilation::current()->number_of_blocks();
+ }
// creation
BlockBegin(int bci)
: StateSplit(illegalType)
- , _block_id(_next_block_id++)
, _depth_first_number(-1)
, _linear_scan_number(-1)
, _loop_depth(0)
, _flags(0)
, _dominator(NULL)
@@ -1590,11 +1612,11 @@
void set_last_lir_instruction_id(int id) { _last_lir_instruction_id = id; }
void increment_total_preds(int n = 1) { _total_preds += n; }
void init_stores_to_locals(int locals_count) { _stores_to_locals = BitMap(locals_count); _stores_to_locals.clear(); }
// generic
- virtual void state_values_do(void f(Value*));
+ virtual void state_values_do(ValueVisitor* f);
// successors and predecessors
int number_of_sux() const;
BlockBegin* sux_at(int i) const;
void add_successor(BlockBegin* sux);
@@ -1644,11 +1666,11 @@
// iteration
void iterate_preorder (BlockClosure* closure);
void iterate_postorder (BlockClosure* closure);
- void block_values_do(void f(Value*));
+ void block_values_do(ValueVisitor* f);
// loops
void set_loop_index(int ix) { _loop_index = ix; }
int loop_index() const { return _loop_index; }
@@ -1696,11 +1718,11 @@
// manipulation
void set_begin(BlockBegin* begin);
// generic
- virtual void other_values_do(void f(Value*));
+ virtual void other_values_do(ValueVisitor* f);
// successors
int number_of_sux() const { return _sux != NULL ? _sux->length() : 0; }
BlockBegin* sux_at(int i) const { return _sux->at(i); }
BlockBegin* default_sux() const { return sux_at(number_of_sux() - 1); }
@@ -1785,11 +1807,11 @@
void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); }
void set_profiled_method(ciMethod* method) { _profiled_method = method; }
void set_profiled_bci(int bci) { _profiled_bci = bci; }
// generic
- virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_x); f(&_y); }
+ virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_x); f->visit(&_y); }
};
LEAF(IfInstanceOf, BlockEnd)
private:
@@ -1839,11 +1861,11 @@
BlockBegin* t = s->at(0); s->at_put(0, s->at(1)); s->at_put(1, t);
_test_is_instance = !_test_is_instance;
}
// generic
- virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_obj); }
+ virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_obj); }
};
BASE(Switch, BlockEnd)
private:
@@ -1861,11 +1883,11 @@
// accessors
Value tag() const { return _tag; }
int length() const { return number_of_sux() - 1; }
// generic
- virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_tag); }
+ virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_tag); }
};
LEAF(TableSwitch, Switch)
private:
@@ -1914,13 +1936,13 @@
// accessors
Value result() const { return _result; }
bool has_result() const { return result() != NULL; }
// generic
- virtual void input_values_do(void f(Value*)) {
+ virtual void input_values_do(ValueVisitor* f) {
BlockEnd::input_values_do(f);
- if (has_result()) f(&_result);
+ if (has_result()) f->visit(&_result);
}
};
LEAF(Throw, BlockEnd)
@@ -1936,12 +1958,12 @@
// accessors
Value exception() const { return _exception; }
// generic
virtual bool can_trap() const { return true; }
- virtual void input_values_do(void f(Value*)) { BlockEnd::input_values_do(f); f(&_exception); }
- virtual void state_values_do(void f(Value*));
+ virtual void input_values_do(ValueVisitor* f) { BlockEnd::input_values_do(f); f->visit(&_exception); }
+ virtual void state_values_do(ValueVisitor* f);
};
LEAF(Base, BlockEnd)
public:
@@ -1969,11 +1991,11 @@
#else
OsrEntry() : Instruction(intType, false) { pin(); }
#endif
// generic
- virtual void input_values_do(void f(Value*)) { }
+ virtual void input_values_do(ValueVisitor* f) { }
};
// Models the incoming exception at a catch site
LEAF(ExceptionObject, Instruction)
@@ -1982,11 +2004,11 @@
ExceptionObject() : Instruction(objectType, false) {
pin();
}
// generic
- virtual void input_values_do(void f(Value*)) { }
+ virtual void input_values_do(ValueVisitor* f) { }
};
// Models needed rounding for floating-point values on Intel.
// Currently only used to represent rounding of double-precision
@@ -2006,11 +2028,11 @@
// accessors
Value input() const { return _input; }
// generic
- virtual void input_values_do(void f(Value*)) { f(&_input); }
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_input); }
};
BASE(UnsafeOp, Instruction)
private:
@@ -2031,12 +2053,12 @@
public:
// accessors
BasicType basic_type() { return _basic_type; }
// generic
- virtual void input_values_do(void f(Value*)) { }
- virtual void other_values_do(void f(Value*)) { }
+ virtual void input_values_do(ValueVisitor* f) { }
+ virtual void other_values_do(ValueVisitor* f) { }
};
BASE(UnsafeRawOp, UnsafeOp)
private:
@@ -2076,13 +2098,13 @@
void set_base (Value base) { _base = base; }
void set_index(Value index) { _index = index; }
void set_log2_scale(int log2_scale) { _log2_scale = log2_scale; }
// generic
- virtual void input_values_do(void f(Value*)) { UnsafeOp::input_values_do(f);
- f(&_base);
- if (has_index()) f(&_index); }
+ virtual void input_values_do(ValueVisitor* f) { UnsafeOp::input_values_do(f);
+ f->visit(&_base);
+ if (has_index()) f->visit(&_index); }
};
LEAF(UnsafeGetRaw, UnsafeRawOp)
private:
@@ -2126,12 +2148,12 @@
// accessors
Value value() { return _value; }
// generic
- virtual void input_values_do(void f(Value*)) { UnsafeRawOp::input_values_do(f);
- f(&_value); }
+ virtual void input_values_do(ValueVisitor* f) { UnsafeRawOp::input_values_do(f);
+ f->visit(&_value); }
};
BASE(UnsafeObjectOp, UnsafeOp)
private:
@@ -2147,13 +2169,13 @@
// accessors
Value object() { return _object; }
Value offset() { return _offset; }
bool is_volatile() { return _is_volatile; }
// generic
- virtual void input_values_do(void f(Value*)) { UnsafeOp::input_values_do(f);
- f(&_object);
- f(&_offset); }
+ virtual void input_values_do(ValueVisitor* f) { UnsafeOp::input_values_do(f);
+ f->visit(&_object);
+ f->visit(&_offset); }
};
LEAF(UnsafeGetObject, UnsafeObjectOp)
public:
@@ -2178,12 +2200,12 @@
// accessors
Value value() { return _value; }
// generic
- virtual void input_values_do(void f(Value*)) { UnsafeObjectOp::input_values_do(f);
- f(&_value); }
+ virtual void input_values_do(ValueVisitor* f) { UnsafeObjectOp::input_values_do(f);
+ f->visit(&_value); }
};
BASE(UnsafePrefetch, UnsafeObjectOp)
public:
@@ -2236,11 +2258,11 @@
ciMethod* method() { return _method; }
int bci_of_invoke() { return _bci_of_invoke; }
Value recv() { return _recv; }
ciKlass* known_holder() { return _known_holder; }
- virtual void input_values_do(void f(Value*)) { if (_recv != NULL) f(&_recv); }
+ virtual void input_values_do(ValueVisitor* f) { if (_recv != NULL) f->visit(&_recv); }
};
//
// Simple node representing a counter update generally used for updating MDOs
@@ -2264,11 +2286,11 @@
Value mdo() { return _mdo; }
int offset() { return _offset; }
int increment() { return _increment; }
- virtual void input_values_do(void f(Value*)) { f(&_mdo); }
+ virtual void input_values_do(ValueVisitor* f) { f->visit(&_mdo); }
};
class BlockPair: public CompilationResourceObj {
private: