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

Unified Diff: src/hydrogen.cc

Issue 288853003: Allow div and cmp to work in uint32 mode (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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 | « no previous file | src/ia32/assembler-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 34008d162c5c43a31b2fd8ee6bc4b2001b0ecf70..e5ae2b03eab92004f5b8c84b6ff843568fb91788 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -3313,8 +3313,22 @@ class Uint32Analysis BASE_EMBEDDED {
};
+bool IsUint32Operation(HValue* instr) {
+ if (instr->IsShr()) return true;
+ if (instr->IsLoadKeyed() &&
+ HLoadKeyed::cast(instr)->elements_kind() ==
+ EXTERNAL_UNSIGNED_INT_ELEMENTS) {
+ return true;
+ }
+ if (instr->IsInteger32Constant() && instr->GetInteger32Constant() >= 0) {
+ return true;
+ }
+ return false;
+}
+
+
bool Uint32Analysis::IsSafeUint32Use(HValue* val, HValue* use) {
- // Operations that operatate on bits are safe.
+ // Operations that operate on bits are safe.
if (use->IsBitwise() ||
use->IsShl() ||
use->IsSar() ||
@@ -3337,6 +3351,37 @@ bool Uint32Analysis::IsSafeUint32Use(HValue* val, HValue* use) {
return true;
}
}
+ } else if (use->IsCompareIDAndBranch()) {
+ for (int i = 0; i < use->OperandCount(); ++i) {
+ if (!IsUint32Operation(use->OperandAt(i))) return false;
+ }
+ return true;
+ } else if (use->IsDiv()) {
+ // Skip OperandAt(0) which is the context.
+ for (int i = 1; i < use->OperandCount(); ++i) {
+ if (!IsUint32Operation(use->OperandAt(i))) {
+ if (FLAG_trace_representation) {
+ HValue* op = use->OperandAt(i);
+ printf("#%d %s is not a safe uint32 use because of operand #%d %s\n",
+ use->id(), use->Mnemonic(), op->id(), op->Mnemonic());
+ }
+ return false;
+ }
+ }
+ for (HUseIterator it(use->uses()); !it.Done(); it.Advance()) {
+ if (!IsSafeUint32Use(use, it.value())) {
+ if (FLAG_trace_representation) {
+ HValue* op = it.value();
+ printf("#%d %s is not a safe uint32 use because of use #%d %s\n",
+ use->id(), use->Mnemonic(), op->id(), op->Mnemonic());
+ }
+ return false;
+ }
+ }
+ if (FLAG_trace_representation) {
+ printf("#%d %s is a safe uint32 use :-)\n", use->id(), use->Mnemonic());
+ }
+ return true;
}
return false;
@@ -3346,10 +3391,10 @@ bool Uint32Analysis::IsSafeUint32Use(HValue* val, HValue* use) {
// Iterate over all uses and verify that they are uint32 safe: either don't
// distinguish between int32 and uint32 due to their bitwise nature or
// have special support for uint32 values.
-// Encountered phis are optimisitically treated as safe uint32 uses,
+// Encountered phis are optimistically treated as safe uint32 uses,
// marked with kUint32 flag and collected in the phis_ list. A separate
-// path will be performed later by UnmarkUnsafePhis to clear kUint32 from
-// phis that are not actually uint32-safe (it requries fix point iteration).
+// pass will be performed later by UnmarkUnsafePhis to clear kUint32 from
+// phis that are not actually uint32-safe (it requires fix point iteration).
bool Uint32Analysis::Uint32UsesAreSafe(HValue* uint32val) {
bool collect_phi_uses = false;
for (HUseIterator it(uint32val->uses()); !it.Done(); it.Advance()) {
@@ -3405,7 +3450,7 @@ bool Uint32Analysis::CheckPhiOperands(HPhi* phi) {
for (int j = 0; j < phi->OperandCount(); j++) {
HValue* operand = phi->OperandAt(j);
if (!operand->CheckFlag(HInstruction::kUint32)) {
- // Lazyly mark constants that fit into uint32 range with kUint32 flag.
+ // Lazily mark constants that fit into uint32 range with kUint32 flag.
if (operand->IsInteger32Constant() &&
operand->GetInteger32Constant() >= 0) {
operand->SetFlag(HInstruction::kUint32);
@@ -3468,15 +3513,15 @@ void Uint32Analysis::UnmarkUnsafePhis() {
// Now phis array contains only those phis that have safe
// non-phi uses. Start transitively clearing kUint32 flag
- // from phi operands of discovered non-safe phies until
- // only safe phies are left.
+ // from phi operands of discovered non-safe phis until
+ // only safe phis are left.
while (!worklist.is_empty()) {
while (!worklist.is_empty()) {
HPhi* phi = worklist.RemoveLast();
UnmarkPhi(phi, &worklist);
}
- // Check if any operands to safe phies were unmarked
+ // Check if any operands to safe phis were unmarked
// turning a safe phi into unsafe. The same value
// can flow into several phis.
int new_phi_count = 0;
@@ -3511,6 +3556,30 @@ void HGraph::ComputeSafeUint32Operations() {
// this information transitively potentially clearing kUint32 flag
// from some non-phi operations that are used as operands to unsafe phis.
analysis.UnmarkUnsafePhis();
+
+ // Inform possible uint32 instructions that the decision has been
+ // finalized.
+ for (int i = 0; i < uint32_instructions_->length(); ++i) {
+ HInstruction* current = uint32_instructions_->at(i);
+ if (FLAG_trace_representation) {
+ printf("Notifying uint32 instr: #%d %s\n",
+ current->id(), current->Mnemonic());
+ }
+ if (current->IsLinked() && current->CheckFlag(HInstruction::kUint32)) {
+ for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) {
+ HValue* use = it.value();
+ // Only care about special-cased instructions here.
+ if (!use->IsDiv() && !use->IsCompareIDAndBranch()) continue;
+ use->SetFlag(HInstruction::kUint32);
+ use->AssumeRepresentation(Representation::Integer32());
+
+ if (FLAG_trace_representation) {
+ printf("Setting kUint32 flag on #%d %s\n",
+ use->id(), use->Mnemonic());
+ }
+ }
+ }
+ }
}
« no previous file with comments | « no previous file | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698