Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Unified Diff: src/cfg.cc

Issue 160584: Add support to the CFG builder for non-short-circuited binary... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/cfg.h ('k') | src/ia32/cfg-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/cfg.cc
===================================================================
--- src/cfg.cc (revision 2620)
+++ src/cfg.cc (working copy)
@@ -42,8 +42,10 @@
CfgGlobals::CfgGlobals(FunctionLiteral* fun)
: global_fun_(fun),
global_exit_(new ExitNode()),
+ effect_(new Effect()),
#ifdef DEBUG
node_counter_(0),
+ temp_counter_(0),
#endif
previous_(top_) {
top_ = this;
@@ -73,6 +75,9 @@
if (cfg == NULL) {
BAILOUT("unsupported statement type");
}
+ if (cfg->is_empty()) {
+ BAILOUT("function body produces empty cfg");
+ }
if (cfg->has_exit()) {
BAILOUT("control path without explicit return");
}
@@ -90,8 +95,10 @@
void Cfg::Append(Instruction* instr) {
- ASSERT(has_exit());
- ASSERT(!is_empty());
+ ASSERT(is_empty() || has_exit());
+ if (is_empty()) {
+ entry_ = exit_ = new InstructionBlock();
+ }
InstructionBlock::cast(exit_)->Append(instr);
}
@@ -104,6 +111,27 @@
}
+void Cfg::Concatenate(Cfg* other) {
+ ASSERT(is_empty() || has_exit());
+ if (other->is_empty()) return;
+
+ if (is_empty()) {
+ entry_ = other->entry();
+ exit_ = other->exit();
+ } else {
+ // We have a pair of nonempty fragments and this has an available exit.
+ // Destructively glue the fragments together.
+ InstructionBlock* first = InstructionBlock::cast(exit_);
+ InstructionBlock* second = InstructionBlock::cast(other->entry());
+ first->instructions()->AddAll(*second->instructions());
+ if (second->successor() != NULL) {
+ first->set_successor(second->successor());
+ exit_ = other->exit();
+ }
+ }
+}
+
+
void InstructionBlock::Unmark() {
if (is_marked_) {
is_marked_ = false;
@@ -166,6 +194,26 @@
}
+void BinaryOpInstr::FastAllocate(TempLocation* temp) {
+ ASSERT(temp->where() == TempLocation::NOWHERE);
+ if (temp == val0_ || temp == val1_) {
+ temp->set_where(TempLocation::ACCUMULATOR);
+ } else {
+ temp->set_where(TempLocation::STACK);
+ }
+}
+
+
+void ReturnInstr::FastAllocate(TempLocation* temp) {
+ ASSERT(temp->where() == TempLocation::NOWHERE);
+ if (temp == value_) {
+ temp->set_where(TempLocation::ACCUMULATOR);
+ } else {
+ temp->set_where(TempLocation::STACK);
+ }
+}
+
+
// The expression builder should not be used for declarations or statements.
void ExpressionBuilder::VisitDeclaration(Declaration* decl) { UNREACHABLE(); }
@@ -178,13 +226,10 @@
// Macros (temporarily) handling unsupported expression types.
#define BAILOUT(reason) \
do { \
- value_ = NULL; \
+ cfg_ = NULL; \
return; \
} while (false)
-#define CHECK_BAILOUT() \
- if (value_ == NULL) { return; } else {}
-
void ExpressionBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
BAILOUT("FunctionLiteral");
}
@@ -290,7 +335,46 @@
void ExpressionBuilder::VisitBinaryOperation(BinaryOperation* expr) {
- BAILOUT("BinaryOperation");
+ Token::Value op = expr->op();
+ switch (op) {
+ case Token::COMMA:
+ case Token::OR:
+ case Token::AND:
+ BAILOUT("unsupported binary operation");
+
+ case Token::BIT_OR:
+ case Token::BIT_XOR:
+ case Token::BIT_AND:
+ case Token::SHL:
+ case Token::SAR:
+ case Token::SHR:
+ case Token::ADD:
+ case Token::SUB:
+ case Token::MUL:
+ case Token::DIV:
+ case Token::MOD: {
+ ExpressionBuilder left, right;
+ left.Build(expr->left());
+ if (left.cfg() == NULL) {
+ BAILOUT("unsupported left subexpression in binop");
+ }
+ right.Build(expr->right());
+ if (right.cfg() == NULL) {
+ BAILOUT("unsupported right subexpression in binop");
+ }
+
+ Location* temp = new TempLocation();
+ cfg_ = left.cfg();
+ cfg_->Concatenate(right.cfg());
+ cfg_->Append(new BinaryOpInstr(temp, op, left.value(), right.value()));
+
+ value_ = temp;
+ return;
+ }
+
+ default:
+ UNREACHABLE();
+ }
}
@@ -304,7 +388,6 @@
}
#undef BAILOUT
-#undef CHECK_BAILOUT
// Macros (temporarily) handling unsupported statement types.
@@ -367,10 +450,13 @@
void StatementBuilder::VisitReturnStatement(ReturnStatement* stmt) {
ExpressionBuilder builder;
- builder.Visit(stmt->expression());
- Value* value = builder.value();
- if (value == NULL) BAILOUT("unsupported expression type");
- cfg_->AppendReturnInstruction(value);
+ builder.Build(stmt->expression());
+ if (builder.cfg() == NULL) {
+ BAILOUT("unsupported expression in return statement");
+ }
+
+ cfg_->Concatenate(builder.cfg());
+ cfg_->AppendReturnInstruction(builder.value());
}
@@ -430,6 +516,11 @@
}
+void Effect::Print() {
+ PrintF("Effect");
+}
+
+
void SlotLocation::Print() {
PrintF("Slot(");
switch (type_) {
@@ -445,10 +536,26 @@
}
+void TempLocation::Print() {
+ PrintF("Temp(%d)", number());
+}
+
+
+void BinaryOpInstr::Print() {
+ PrintF("BinaryOp(");
+ loc_->Print();
+ PrintF(", %s, ", Token::Name(op_));
+ val0_->Print();
+ PrintF(", ");
+ val1_->Print();
+ PrintF(")\n");
+}
+
+
void ReturnInstr::Print() {
- PrintF("Return ");
+ PrintF("Return(");
value_->Print();
- PrintF("\n");
+ PrintF(")\n");
}
« no previous file with comments | « src/cfg.h ('k') | src/ia32/cfg-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698