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

Side by Side Diff: src/jump-target-ia32.cc

Issue 21040: Experimental: handle single-entry basic blocks as a special case.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/jump-target.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 24 matching lines...) Expand all
35 // ------------------------------------------------------------------------- 35 // -------------------------------------------------------------------------
36 // JumpTarget implementation. 36 // JumpTarget implementation.
37 37
38 #define __ masm_-> 38 #define __ masm_->
39 39
40 JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction) 40 JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction)
41 : cgen_(cgen), 41 : cgen_(cgen),
42 direction_(direction), 42 direction_(direction),
43 reaching_frames_(0), 43 reaching_frames_(0),
44 merge_labels_(0), 44 merge_labels_(0),
45 expected_frame_(NULL) { 45 expected_frame_(NULL),
46 is_bound_(false),
47 is_linked_(false) {
46 ASSERT(cgen_ != NULL); 48 ASSERT(cgen_ != NULL);
47 masm_ = cgen_->masm(); 49 masm_ = cgen_->masm();
48 } 50 }
49 51
50 52
51 JumpTarget::JumpTarget() 53 JumpTarget::JumpTarget()
52 : cgen_(NULL), 54 : cgen_(NULL),
53 masm_(NULL), 55 masm_(NULL),
54 direction_(FORWARD_ONLY), 56 direction_(FORWARD_ONLY),
55 reaching_frames_(0), 57 reaching_frames_(0),
56 merge_labels_(0), 58 merge_labels_(0),
57 expected_frame_(NULL) { 59 expected_frame_(NULL),
60 is_bound_(false),
61 is_linked_(false) {
58 } 62 }
59 63
60 64
61 void JumpTarget::Initialize(CodeGenerator* cgen, Directionality direction) { 65 void JumpTarget::Initialize(CodeGenerator* cgen, Directionality direction) {
62 ASSERT(cgen != NULL); 66 ASSERT(cgen != NULL);
63 ASSERT(cgen_ == NULL); 67 ASSERT(cgen_ == NULL);
64 cgen_ = cgen; 68 cgen_ = cgen;
65 masm_ = cgen->masm(); 69 masm_ = cgen->masm();
66 direction_ = direction; 70 direction_ = direction;
67 } 71 }
68 72
69 73
74 void JumpTarget::Unuse() {
75 ASSERT(!is_linked());
76 entry_label_.Unuse();
77 delete expected_frame_;
78 expected_frame_ = NULL;
79 is_bound_ = false;
80 is_linked_ = false;
81 }
82
83
84 void JumpTarget::Reset() {
85 reaching_frames_.Clear();
86 merge_labels_.Clear();
87 expected_frame_ = NULL;
88 entry_label_.Unuse();
89 is_bound_ = false;
90 is_linked_ = false;
91 }
92
93
70 void JumpTarget::Jump() { 94 void JumpTarget::Jump() {
71 ASSERT(cgen_ != NULL); 95 ASSERT(cgen_ != NULL);
72 ASSERT(cgen_->has_valid_frame()); 96 ASSERT(cgen_->has_valid_frame());
73 // Live non-frame registers are not allowed at unconditional jumps 97 // Live non-frame registers are not allowed at unconditional jumps
74 // because we have no way of invalidating the corresponding results 98 // because we have no way of invalidating the corresponding results
75 // which are still live in the C++ code. 99 // which are still live in the C++ code.
76 ASSERT(cgen_->HasValidEntryRegisters()); 100 ASSERT(cgen_->HasValidEntryRegisters());
77 101
78 if (is_bound()) { 102 if (is_bound()) {
79 // Backward jump. There is an expected frame to merge to. 103 // Backward jump. There is an expected frame to merge to.
80 ASSERT(direction_ == BIDIRECTIONAL); 104 ASSERT(direction_ == BIDIRECTIONAL);
81 cgen_->frame()->MergeTo(expected_frame_); 105 cgen_->frame()->MergeTo(expected_frame_);
82 cgen_->DeleteFrame(); 106 cgen_->DeleteFrame();
83 __ jmp(&entry_label_); 107 __ jmp(&entry_label_);
84 } else { 108 } else {
85 // Forward jump. The current frame is added to the end of the list 109 // Forward jump. The current frame is added to the end of the list
86 // of frames reaching the target block and a jump to the merge code 110 // of frames reaching the target block and a jump to the merge code
87 // is emitted. 111 // is emitted.
88 AddReachingFrame(cgen_->frame()); 112 AddReachingFrame(cgen_->frame());
89 RegisterFile empty; 113 RegisterFile empty;
90 cgen_->SetFrame(NULL, &empty); 114 cgen_->SetFrame(NULL, &empty);
91 __ jmp(&merge_labels_.last()); 115 __ jmp(&merge_labels_.last());
92 } 116 }
117
118 is_linked_ = !is_bound_;
93 } 119 }
94 120
95 121
96 void JumpTarget::Jump(Result* arg) { 122 void JumpTarget::Jump(Result* arg) {
97 ASSERT(cgen_ != NULL); 123 ASSERT(cgen_ != NULL);
98 ASSERT(cgen_->has_valid_frame()); 124 ASSERT(cgen_->has_valid_frame());
99 125
100 cgen_->frame()->Push(arg); 126 cgen_->frame()->Push(arg);
101 Jump(); 127 Jump();
102 } 128 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // Restore the frame and its associated non-frame registers. 179 // Restore the frame and its associated non-frame registers.
154 cgen_->SetFrame(original_frame, &non_frame_registers); 180 cgen_->SetFrame(original_frame, &non_frame_registers);
155 __ bind(&original_fall_through); 181 __ bind(&original_fall_through);
156 } else { 182 } else {
157 // Forward branch. A copy of the current frame is added to the end 183 // Forward branch. A copy of the current frame is added to the end
158 // of the list of frames reaching the target block and a branch to 184 // of the list of frames reaching the target block and a branch to
159 // the merge code is emitted. 185 // the merge code is emitted.
160 AddReachingFrame(new VirtualFrame(cgen_->frame())); 186 AddReachingFrame(new VirtualFrame(cgen_->frame()));
161 __ j(cc, &merge_labels_.last(), hint); 187 __ j(cc, &merge_labels_.last(), hint);
162 } 188 }
189
190 is_linked_ = !is_bound_;
163 } 191 }
164 192
165 193
166 #ifdef DEBUG 194 #ifdef DEBUG
167 #define DECLARE_ARGCHECK_VARS(name) \ 195 #define DECLARE_ARGCHECK_VARS(name) \
168 Result::Type name##_type = name->type(); \ 196 Result::Type name##_type = name->type(); \
169 Register name##_reg = name->is_register() ? name->reg() : no_reg 197 Register name##_reg = name->is_register() ? name->reg() : no_reg
170 198
171 #define ASSERT_ARGCHECK(name) \ 199 #define ASSERT_ARGCHECK(name) \
172 ASSERT(name->type() == name##_type); \ 200 ASSERT(name->type() == name##_type); \
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 ASSERT(cgen_->has_valid_frame()); 319 ASSERT(cgen_->has_valid_frame());
292 // There are no non-frame references across the call. 320 // There are no non-frame references across the call.
293 ASSERT(cgen_->HasValidEntryRegisters()); 321 ASSERT(cgen_->HasValidEntryRegisters());
294 ASSERT(!is_linked()); 322 ASSERT(!is_linked());
295 323
296 cgen_->frame()->SpillAll(); 324 cgen_->frame()->SpillAll();
297 VirtualFrame* target_frame = new VirtualFrame(cgen_->frame()); 325 VirtualFrame* target_frame = new VirtualFrame(cgen_->frame());
298 target_frame->Adjust(1); 326 target_frame->Adjust(1);
299 AddReachingFrame(target_frame); 327 AddReachingFrame(target_frame);
300 __ call(&merge_labels_.last()); 328 __ call(&merge_labels_.last());
329
330 is_linked_ = !is_bound_;
301 } 331 }
302 332
303 333
304 void JumpTarget::Bind() { 334 void JumpTarget::Bind() {
305 ASSERT(cgen_ != NULL); 335 ASSERT(cgen_ != NULL);
306 ASSERT(is_linked() || cgen_->has_valid_frame());
307 ASSERT(!is_bound()); 336 ASSERT(!is_bound());
308 337
309 if (is_linked()) { 338 if (is_linked()) {
310 // There were forward jumps. A mergable frame is created and all 339 // There were forward jumps. A mergable frame is created and all
311 // the frames reaching the block via forward jumps are merged to it. 340 // the frames reaching the block via forward jumps are merged to it.
312 ASSERT(reaching_frames_.length() == merge_labels_.length()); 341 ASSERT(reaching_frames_.length() == merge_labels_.length());
313 342
314 // Choose a frame as the basis of the expected frame, and make it 343 // A special case is that there was only one jump to the block so
315 // mergable. If there is a current frame use it, otherwise use the 344 // far, no fall-through, and there cannot be another entry because
316 // first in the list (there will be at least one). 345 // the block is forward only. In that case, simply use the single
317 int start_index = 0; 346 // frame.
318 if (cgen_->has_valid_frame()) { 347 bool single_entry = (direction_ == FORWARD_ONLY) &&
319 // Live non-frame registers are not allowed at the start of a labeled 348 !cgen_->has_valid_frame() &&
320 // basic block. 349 (reaching_frames_.length() == 1);
321 ASSERT(cgen_->HasValidEntryRegisters()); 350 if (single_entry) {
351 // Pick up the only forward reaching frame and bind its merge
352 // label. No merge code is emitted.
353 RegisterFile reserved_registers = RegisterAllocator::Reserved();
354 cgen_->SetFrame(reaching_frames_[0], &reserved_registers);
355 __ bind(&merge_labels_[0]);
322 } else { 356 } else {
323 RegisterFile reserved_registers = RegisterAllocator::Reserved(); 357 // Otherwise, choose a frame as the basis of the expected frame,
324 cgen_->SetFrame(reaching_frames_[start_index], &reserved_registers); 358 // and make it mergable. If there is a current frame use it,
325 __ bind(&merge_labels_[start_index++]); 359 // otherwise use the first in the list (there will be at least
360 // one).
361 int start_index = 0;
362 if (cgen_->has_valid_frame()) {
363 // Live non-frame registers are not allowed at the start of a
364 // labeled basic block.
365 ASSERT(cgen_->HasValidEntryRegisters());
366 } else {
367 RegisterFile reserved_registers = RegisterAllocator::Reserved();
368 cgen_->SetFrame(reaching_frames_[start_index], &reserved_registers);
369 __ bind(&merge_labels_[start_index++]);
370 }
371 cgen_->frame()->MakeMergable();
372 expected_frame_ = new VirtualFrame(cgen_->frame());
373
374 for (int i = start_index; i < reaching_frames_.length(); i++) {
375 cgen_->DeleteFrame();
376 __ jmp(&entry_label_);
377
378 RegisterFile reserved_registers = RegisterAllocator::Reserved();
379 cgen_->SetFrame(reaching_frames_[i], &reserved_registers);
380 __ bind(&merge_labels_[i]);
381
382 cgen_->frame()->MergeTo(expected_frame_);
383 }
384
385 __ bind(&entry_label_);
326 } 386 }
327 cgen_->frame()->MakeMergable();
328 expected_frame_ = new VirtualFrame(cgen_->frame());
329
330 for (int i = start_index; i < reaching_frames_.length(); i++) {
331 cgen_->DeleteFrame();
332 __ jmp(&entry_label_);
333
334 RegisterFile reserved_registers = RegisterAllocator::Reserved();
335 cgen_->SetFrame(reaching_frames_[i], &reserved_registers);
336 __ bind(&merge_labels_[i]);
337
338 cgen_->frame()->MergeTo(expected_frame_);
339 }
340 __ bind(&entry_label_);
341 387
342 // All but the last reaching virtual frame have been deleted, and 388 // All but the last reaching virtual frame have been deleted, and
343 // the last one is the current frame. 389 // the last one is the current frame.
344 reaching_frames_.Clear(); 390 reaching_frames_.Clear();
345 merge_labels_.Clear(); 391 merge_labels_.Clear();
392
346 } else { 393 } else {
347 // There were no forward jumps. There must be a current frame, 394 // There were no forward jumps. If this jump target is not
348 // which is made mergable and used as the expected frame. 395 // bidirectional, there is no need to do anything. For
349 ASSERT(cgen_->HasValidEntryRegisters()); 396 // bidirectional jump targets, the current frame is made mergable
350 cgen_->frame()->MakeMergable(); 397 // and used for the expected frame.
351 expected_frame_ = new VirtualFrame(cgen_->frame()); 398 if (direction_ == BIDIRECTIONAL) {
352 __ bind(&entry_label_); 399 ASSERT(cgen_->HasValidEntryRegisters());
400 cgen_->frame()->MakeMergable();
401 expected_frame_ = new VirtualFrame(cgen_->frame());
402 __ bind(&entry_label_);
403 }
353 } 404 }
405
406 is_linked_ = false;
407 is_bound_ = true;
354 } 408 }
355 409
356 410
357 void JumpTarget::Bind(Result* arg) { 411 void JumpTarget::Bind(Result* arg) {
358 ASSERT(cgen_ != NULL); 412 ASSERT(cgen_ != NULL);
359 413
360 if (cgen_->has_valid_frame()) { 414 if (cgen_->has_valid_frame()) {
361 cgen_->frame()->Push(arg); 415 cgen_->frame()->Push(arg);
362 } 416 }
363 Bind(); 417 Bind();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 destination->direction_ = direction_; 471 destination->direction_ = direction_;
418 destination->reaching_frames_.Clear(); 472 destination->reaching_frames_.Clear();
419 destination->merge_labels_.Clear(); 473 destination->merge_labels_.Clear();
420 ASSERT(reaching_frames_.length() == merge_labels_.length()); 474 ASSERT(reaching_frames_.length() == merge_labels_.length());
421 for (int i = 0; i < reaching_frames_.length(); i++) { 475 for (int i = 0; i < reaching_frames_.length(); i++) {
422 destination->reaching_frames_.Add(reaching_frames_[i]); 476 destination->reaching_frames_.Add(reaching_frames_[i]);
423 destination->merge_labels_.Add(merge_labels_[i]); 477 destination->merge_labels_.Add(merge_labels_[i]);
424 } 478 }
425 destination->expected_frame_ = expected_frame_; 479 destination->expected_frame_ = expected_frame_;
426 destination->entry_label_ = entry_label_; 480 destination->entry_label_ = entry_label_;
481 destination->is_bound_ = is_bound_;
482 destination->is_linked_ = is_linked_;
427 } 483 }
428 484
429 485
430 void JumpTarget::AddReachingFrame(VirtualFrame* frame) { 486 void JumpTarget::AddReachingFrame(VirtualFrame* frame) {
431 ASSERT(reaching_frames_.length() == merge_labels_.length()); 487 ASSERT(reaching_frames_.length() == merge_labels_.length());
432 Label fresh; 488 Label fresh;
433 merge_labels_.Add(fresh); 489 merge_labels_.Add(fresh);
434 reaching_frames_.Add(frame); 490 reaching_frames_.Add(frame);
435 } 491 }
436 492
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 534
479 #ifdef DEBUG 535 #ifdef DEBUG
480 is_shadowing_ = false; 536 is_shadowing_ = false;
481 #endif 537 #endif
482 } 538 }
483 539
484 #undef __ 540 #undef __
485 541
486 542
487 } } // namespace v8::internal 543 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jump-target.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698