提交 c82df3ea 编写于 作者: R roland

6991577: add IfOp optimization to C1

Summary: Ifop optimization for c1
Reviewed-by: never, phh, iveresov
上级 766034c2
...@@ -178,15 +178,11 @@ class Compilation: public StackObj { ...@@ -178,15 +178,11 @@ class Compilation: public StackObj {
return (int) NMethodSizeLimit; // default 256K or 512K return (int) NMethodSizeLimit; // default 256K or 512K
#else #else
// conditional branches on PPC are restricted to 16 bit signed // conditional branches on PPC are restricted to 16 bit signed
return MAX2((unsigned int)NMethodSizeLimit,32*K); return MIN2((unsigned int)NMethodSizeLimit,32*K);
#endif #endif
} }
static int desired_max_constant_size() { static int desired_max_constant_size() {
#ifndef PPC return desired_max_code_buffer_size() / 10;
return (int) NMethodSizeLimit / 10; // about 25K
#else
return (MAX2((unsigned int)NMethodSizeLimit, 32*K)) / 10;
#endif
} }
static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate); static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
......
...@@ -321,7 +321,7 @@ class UseCountComputer: public ValueVisitor, BlockClosure { ...@@ -321,7 +321,7 @@ class UseCountComputer: public ValueVisitor, BlockClosure {
void visit(Value* n) { void visit(Value* n) {
// Local instructions and Phis for expression stack values at the // Local instructions and Phis for expression stack values at the
// start of basic blocks are not added to the instruction list // start of basic blocks are not added to the instruction list
if (!(*n)->is_linked()&& (*n)->can_be_linked()) { if (!(*n)->is_linked() && (*n)->can_be_linked()) {
assert(false, "a node was not appended to the graph"); assert(false, "a node was not appended to the graph");
Compilation::current()->bailout("a node was not appended to the graph"); Compilation::current()->bailout("a node was not appended to the graph");
} }
......
...@@ -415,28 +415,26 @@ bool Constant::is_equal(Value v) const { ...@@ -415,28 +415,26 @@ bool Constant::is_equal(Value v) const {
return false; return false;
} }
Constant::CompareResult Constant::compare(Instruction::Condition cond, Value right) const {
BlockBegin* Constant::compare(Instruction::Condition cond, Value right,
BlockBegin* true_sux, BlockBegin* false_sux) {
Constant* rc = right->as_Constant(); Constant* rc = right->as_Constant();
// other is not a constant // other is not a constant
if (rc == NULL) return NULL; if (rc == NULL) return not_comparable;
ValueType* lt = type(); ValueType* lt = type();
ValueType* rt = rc->type(); ValueType* rt = rc->type();
// different types // different types
if (lt->base() != rt->base()) return NULL; if (lt->base() != rt->base()) return not_comparable;
switch (lt->tag()) { switch (lt->tag()) {
case intTag: { case intTag: {
int x = lt->as_IntConstant()->value(); int x = lt->as_IntConstant()->value();
int y = rt->as_IntConstant()->value(); int y = rt->as_IntConstant()->value();
switch (cond) { switch (cond) {
case If::eql: return x == y ? true_sux : false_sux; case If::eql: return x == y ? cond_true : cond_false;
case If::neq: return x != y ? true_sux : false_sux; case If::neq: return x != y ? cond_true : cond_false;
case If::lss: return x < y ? true_sux : false_sux; case If::lss: return x < y ? cond_true : cond_false;
case If::leq: return x <= y ? true_sux : false_sux; case If::leq: return x <= y ? cond_true : cond_false;
case If::gtr: return x > y ? true_sux : false_sux; case If::gtr: return x > y ? cond_true : cond_false;
case If::geq: return x >= y ? true_sux : false_sux; case If::geq: return x >= y ? cond_true : cond_false;
} }
break; break;
} }
...@@ -444,12 +442,12 @@ BlockBegin* Constant::compare(Instruction::Condition cond, Value right, ...@@ -444,12 +442,12 @@ BlockBegin* Constant::compare(Instruction::Condition cond, Value right,
jlong x = lt->as_LongConstant()->value(); jlong x = lt->as_LongConstant()->value();
jlong y = rt->as_LongConstant()->value(); jlong y = rt->as_LongConstant()->value();
switch (cond) { switch (cond) {
case If::eql: return x == y ? true_sux : false_sux; case If::eql: return x == y ? cond_true : cond_false;
case If::neq: return x != y ? true_sux : false_sux; case If::neq: return x != y ? cond_true : cond_false;
case If::lss: return x < y ? true_sux : false_sux; case If::lss: return x < y ? cond_true : cond_false;
case If::leq: return x <= y ? true_sux : false_sux; case If::leq: return x <= y ? cond_true : cond_false;
case If::gtr: return x > y ? true_sux : false_sux; case If::gtr: return x > y ? cond_true : cond_false;
case If::geq: return x >= y ? true_sux : false_sux; case If::geq: return x >= y ? cond_true : cond_false;
} }
break; break;
} }
...@@ -459,14 +457,14 @@ BlockBegin* Constant::compare(Instruction::Condition cond, Value right, ...@@ -459,14 +457,14 @@ BlockBegin* Constant::compare(Instruction::Condition cond, Value right,
assert(xvalue != NULL && yvalue != NULL, "not constants"); assert(xvalue != NULL && yvalue != NULL, "not constants");
if (xvalue->is_loaded() && yvalue->is_loaded()) { if (xvalue->is_loaded() && yvalue->is_loaded()) {
switch (cond) { switch (cond) {
case If::eql: return xvalue == yvalue ? true_sux : false_sux; case If::eql: return xvalue == yvalue ? cond_true : cond_false;
case If::neq: return xvalue != yvalue ? true_sux : false_sux; case If::neq: return xvalue != yvalue ? cond_true : cond_false;
} }
} }
break; break;
} }
} }
return NULL; return not_comparable;
} }
......
...@@ -650,8 +650,24 @@ LEAF(Constant, Instruction) ...@@ -650,8 +650,24 @@ LEAF(Constant, Instruction)
virtual intx hash() const; virtual intx hash() const;
virtual bool is_equal(Value v) const; virtual bool is_equal(Value v) const;
virtual BlockBegin* compare(Instruction::Condition condition, Value right,
BlockBegin* true_sux, BlockBegin* false_sux); enum CompareResult { not_comparable = -1, cond_false, cond_true };
virtual CompareResult compare(Instruction::Condition condition, Value right) const;
BlockBegin* compare(Instruction::Condition cond, Value right,
BlockBegin* true_sux, BlockBegin* false_sux) const {
switch (compare(cond, right)) {
case not_comparable:
return NULL;
case cond_false:
return false_sux;
case cond_true:
return true_sux;
default:
ShouldNotReachHere();
return NULL;
}
}
}; };
......
...@@ -38,18 +38,20 @@ class CE_Eliminator: public BlockClosure { ...@@ -38,18 +38,20 @@ class CE_Eliminator: public BlockClosure {
private: private:
IR* _hir; IR* _hir;
int _cee_count; // the number of CEs successfully eliminated int _cee_count; // the number of CEs successfully eliminated
int _ifop_count; // the number of IfOps successfully simplified
int _has_substitution; int _has_substitution;
public: public:
CE_Eliminator(IR* hir) : _cee_count(0), _hir(hir) { CE_Eliminator(IR* hir) : _cee_count(0), _ifop_count(0), _hir(hir) {
_has_substitution = false; _has_substitution = false;
_hir->iterate_preorder(this); _hir->iterate_preorder(this);
if (_has_substitution) { if (_has_substitution) {
// substituted some phis so resolve the substitution // substituted some ifops/phis, so resolve the substitution
SubstitutionResolver sr(_hir); SubstitutionResolver sr(_hir);
} }
} }
int cee_count() const { return _cee_count; } int cee_count() const { return _cee_count; }
int ifop_count() const { return _ifop_count; }
void adjust_exception_edges(BlockBegin* block, BlockBegin* sux) { void adjust_exception_edges(BlockBegin* block, BlockBegin* sux) {
int e = sux->number_of_exception_handlers(); int e = sux->number_of_exception_handlers();
...@@ -68,7 +70,13 @@ class CE_Eliminator: public BlockClosure { ...@@ -68,7 +70,13 @@ class CE_Eliminator: public BlockClosure {
} }
} }
virtual void block_do(BlockBegin* block) { virtual void block_do(BlockBegin* block);
private:
Value make_ifop(Value x, Instruction::Condition cond, Value y, Value tval, Value fval);
};
void CE_Eliminator::block_do(BlockBegin* block) {
// 1) find conditional expression // 1) find conditional expression
// check if block ends with an If // check if block ends with an If
If* if_ = block->end()->as_If(); If* if_ = block->end()->as_If();
...@@ -155,12 +163,12 @@ class CE_Eliminator: public BlockClosure { ...@@ -155,12 +163,12 @@ class CE_Eliminator: public BlockClosure {
cur_end = cur_end->set_next(f_value); cur_end = cur_end->set_next(f_value);
} }
// it is very unlikely that the condition can be statically decided Value result = make_ifop(if_->x(), if_->cond(), if_->y(), t_value, f_value);
// (this was checked previously by the Canonicalizer), so always assert(result != NULL, "make_ifop must return a non-null instruction");
// append IfOp if (!result->is_linked() && result->can_be_linked()) {
Value result = new IfOp(if_->x(), if_->cond(), if_->y(), t_value, f_value);
NOT_PRODUCT(result->set_printable_bci(if_->printable_bci())); NOT_PRODUCT(result->set_printable_bci(if_->printable_bci()));
cur_end = cur_end->set_next(result); cur_end = cur_end->set_next(result);
}
// append Goto to successor // append Goto to successor
ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL; ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL;
...@@ -205,19 +213,71 @@ class CE_Eliminator: public BlockClosure { ...@@ -205,19 +213,71 @@ class CE_Eliminator: public BlockClosure {
_cee_count++; _cee_count++;
if (PrintCEE) { if (PrintCEE) {
tty->print_cr("%d. CEE in B%d (B%d B%d)", cee_count(), block->block_id(), t_block->block_id(), f_block->block_id()); tty->print_cr("%d. CEE in B%d (B%d B%d)", cee_count(), block->block_id(), t_block->block_id(), f_block->block_id());
tty->print_cr("%d. IfOp in B%d", ifop_count(), block->block_id());
} }
_hir->verify(); _hir->verify();
}
Value CE_Eliminator::make_ifop(Value x, Instruction::Condition cond, Value y, Value tval, Value fval) {
if (!OptimizeIfOps) {
return new IfOp(x, cond, y, tval, fval);
} }
};
tval = tval->subst();
fval = fval->subst();
if (tval == fval) {
_ifop_count++;
return tval;
}
x = x->subst();
y = y->subst();
Constant* y_const = y->as_Constant();
if (y_const != NULL) {
IfOp* x_ifop = x->as_IfOp();
if (x_ifop != NULL) { // x is an ifop, y is a constant
Constant* x_tval_const = x_ifop->tval()->subst()->as_Constant();
Constant* x_fval_const = x_ifop->fval()->subst()->as_Constant();
if (x_tval_const != NULL && x_fval_const != NULL) {
Instruction::Condition x_ifop_cond = x_ifop->cond();
Constant::CompareResult t_compare_res = x_tval_const->compare(cond, y_const);
Constant::CompareResult f_compare_res = x_fval_const->compare(cond, y_const);
guarantee(t_compare_res != Constant::not_comparable && f_compare_res != Constant::not_comparable, "incomparable constants in IfOp");
Value new_tval = t_compare_res == Constant::cond_true ? tval : fval;
Value new_fval = f_compare_res == Constant::cond_true ? tval : fval;
_ifop_count++;
if (new_tval == new_fval) {
return new_tval;
} else {
return new IfOp(x_ifop->x(), x_ifop_cond, x_ifop->y(), new_tval, new_fval);
}
}
} else {
Constant* x_const = x->as_Constant();
if (x_const != NULL) { // x and y are constants
Constant::CompareResult x_compare_res = x_const->compare(cond, y_const);
guarantee(x_compare_res != Constant::not_comparable, "incomparable constants in IfOp");
_ifop_count++;
return x_compare_res == Constant::cond_true ? tval : fval;
}
}
}
return new IfOp(x, cond, y, tval, fval);
}
void Optimizer::eliminate_conditional_expressions() { void Optimizer::eliminate_conditional_expressions() {
// find conditional expressions & replace them with IfOps // find conditional expressions & replace them with IfOps
CE_Eliminator ce(ir()); CE_Eliminator ce(ir());
} }
class BlockMerger: public BlockClosure { class BlockMerger: public BlockClosure {
private: private:
IR* _hir; IR* _hir;
......
...@@ -75,6 +75,9 @@ ...@@ -75,6 +75,9 @@
develop(bool, SelectivePhiFunctions, true, \ develop(bool, SelectivePhiFunctions, true, \
"create phi functions at loop headers only when necessary") \ "create phi functions at loop headers only when necessary") \
\ \
develop(bool, OptimizeIfOps, true, \
"Optimize multiple IfOps") \
\
develop(bool, DoCEE, true, \ develop(bool, DoCEE, true, \
"Do Conditional Expression Elimination to simplify CFG") \ "Do Conditional Expression Elimination to simplify CFG") \
\ \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册