Optimize identical-comparisons based on propagated type information.

If the propagated type allows, eliminate the check for numbers at
identical operations in optimized code.

The previous optimizaton was done before full type propagation was run
and was therefore not very effective.

* Made flow-graph printing having no side-effects: calling Type() lazily
initializes the type_ and reaching_type_ fields of Value and Definition.
Access fields directly when printing instead.

Also, fixed two random spelling mistakes.

R=srdjan@google.com

Review URL: https://codereview.chromium.org//27727002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28851 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
fschneider@google.com 2013-10-18 11:13:59 +00:00
parent f35b9c485f
commit 8779bc8d7f
6 changed files with 38 additions and 28 deletions

View file

@ -818,7 +818,7 @@ void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) {
Handle::ScopedLock lock(listen_socket);
// If incomming connections are requested make sure to post already
// If incoming connections are requested make sure to post already
// accepted connections.
if ((msg->data & (1 << kInEvent)) != 0) {
if (listen_socket->CanAccept()) {

View file

@ -3223,27 +3223,6 @@ void FlowGraphOptimizer::VisitBranch(BranchInstr* instr) {
}
static bool MayBeBoxableNumber(intptr_t cid) {
return (cid == kDynamicCid) ||
(cid == kMintCid) ||
(cid == kBigintCid) ||
(cid == kDoubleCid);
}
// Check if number check is not needed.
void FlowGraphOptimizer::VisitStrictCompare(StrictCompareInstr* instr) {
if (!instr->needs_number_check()) return;
// If one of the input is not a boxable number (Mint, Double, Bigint), no
// need for number checks.
if (!MayBeBoxableNumber(instr->left()->Type()->ToCid()) ||
!MayBeBoxableNumber(instr->right()->Type()->ToCid())) {
instr->set_needs_number_check(false);
}
}
// Range analysis for smi values.
class RangeAnalysis : public ValueObject {
public:

View file

@ -58,7 +58,6 @@ class FlowGraphOptimizer : public FlowGraphVisitor {
virtual void VisitInstanceCall(InstanceCallInstr* instr);
virtual void VisitEqualityCompare(EqualityCompareInstr* instr);
virtual void VisitBranch(BranchInstr* instr);
virtual void VisitStrictCompare(StrictCompareInstr* instr);
void InsertBefore(Instruction* next,
Instruction* instr,

View file

@ -73,7 +73,7 @@ void FlowGraphPrinter::PrintInstruction(Instruction* instr) {
void FlowGraphPrinter::PrintOneInstruction(Instruction* instr,
bool print_locations) {
char str[1000];
char str[4000];
BufferFormatter f(str, sizeof(str));
instr->PrintTo(&f);
if (FLAG_print_environments && (instr->env() != NULL)) {
@ -97,8 +97,8 @@ void FlowGraphPrinter::PrintTypeCheck(const ParsedFunction& parsed_function,
const String& dst_name,
bool eliminated) {
const char* compile_type_name = "unknown";
if (value != NULL) {
compile_type_name = value->Type()->ToCString();
if (value != NULL && value->reaching_type_ != NULL) {
compile_type_name = value->reaching_type_->ToCString();
}
OS::Print("%s type check: compile type %s is %s specific than "
"type '%s' of '%s'.\n",
@ -232,7 +232,7 @@ void Definition::PrintOperandsTo(BufferFormatter* f) const {
void Value::PrintTo(BufferFormatter* f) const {
PrintUse(f, *definition());
if ((reaching_type_ != NULL) &&
(reaching_type_ != definition()->Type())) {
(reaching_type_ != definition()->type_)) {
f->Print(" ");
reaching_type_->PrintTo(f);
}

View file

@ -1528,10 +1528,39 @@ Definition* BooleanNegateInstr::Canonicalize(FlowGraph* flow_graph) {
}
static bool MayBeBoxableNumber(intptr_t cid) {
return (cid == kDynamicCid) ||
(cid == kMintCid) ||
(cid == kBigintCid) ||
(cid == kDoubleCid);
}
static bool MaybeNumber(CompileType* type) {
ASSERT(Type::Handle(Type::Number()).IsMoreSpecificThan(
Type::Handle(Type::Number()), NULL));
return type->ToAbstractType()->IsDynamicType()
|| type->IsMoreSpecificThan(Type::Handle(Type::Number()));
}
// Returns a replacement for a strict comparison and signals if the result has
// to be negated.
static Definition* CanonicalizeStrictCompare(StrictCompareInstr* compare,
bool* negated) {
// Use propagated cid and type information to eliminate number checks.
// If one of the inputs is not a boxable number (Mint, Double, Bigint), or
// is not a subtype of num, no need for number checks.
if (compare->needs_number_check()) {
if (!MayBeBoxableNumber(compare->left()->Type()->ToCid()) ||
!MayBeBoxableNumber(compare->right()->Type()->ToCid())) {
compare->set_needs_number_check(false);
} else if (!MaybeNumber(compare->left()->Type()) ||
!MaybeNumber(compare->right()->Type())) {
compare->set_needs_number_check(false);
}
}
*negated = false;
Object& constant = Object::Handle();
Value* other = NULL;

View file

@ -366,7 +366,7 @@ class ConstrainedCompileType : public ZoneCompileType {
// NotNullConstrainedCompileType represents not-null constraint applied to
// the source compile type. Result is non-nullable version of the incomming
// the source compile type. Result is non-nullable version of the incoming
// compile type. It is used to represent compile type propagated downwards
// from strict comparison with the null constant.
class NotNullConstrainedCompileType : public ConstrainedCompileType {
@ -506,6 +506,8 @@ class Value : public ZoneAllocated {
bool Equals(Value* other) const;
private:
friend class FlowGraphPrinter;
Definition* definition_;
Value* previous_use_;
Value* next_use_;
@ -1752,6 +1754,7 @@ class Definition : public Instruction {
protected:
friend class RangeAnalysis;
friend class Value;
Range* range_;
CompileType* type_;