namespace internal {
namespace compiler {
+#define TRACE(...) \
+ do { \
+ if (FLAG_trace_turbo_scheduler) PrintF(__VA_ARGS__); \
+ } while (false)
+
// Determines control dependence equivalence classes for control nodes. Any two
// nodes having the same set of control dependences land in one class. These
// classes can in turn be used to:
// Called at pre-visit during DFS walk.
void VisitPre(Node* node) {
- Trace("CEQ: Pre-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+ TRACE("CEQ: Pre-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
// Dispense a new pre-order number.
SetNumber(node, NewDFSNumber());
- Trace(" Assigned DFS number is %d\n", GetNumber(node));
+ TRACE(" Assigned DFS number is %zu\n", GetNumber(node));
}
// Called at mid-visit during DFS walk.
void VisitMid(Node* node, DFSDirection direction) {
- Trace("CEQ: Mid-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+ TRACE("CEQ: Mid-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
BracketList& blist = GetBracketList(node);
// Remove brackets pointing to this node [line:19].
}
// Potentially start a new equivalence class [line:37].
- BracketListTrace(blist);
+ BracketListTRACE(blist);
Bracket* recent = &blist.back();
if (recent->recent_size != blist.size()) {
recent->recent_size = blist.size();
// Assign equivalence class to node.
SetClass(node, recent->recent_class);
- Trace(" Assigned class number is %d\n", GetClass(node));
+ TRACE(" Assigned class number is %zu\n", GetClass(node));
}
// Called at post-visit during DFS walk.
void VisitPost(Node* node, Node* parent_node, DFSDirection direction) {
- Trace("CEQ: Post-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+ TRACE("CEQ: Post-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
BracketList& blist = GetBracketList(node);
// Remove brackets pointing to this node [line:19].
// Called when hitting a back edge in the DFS walk.
void VisitBackedge(Node* from, Node* to, DFSDirection direction) {
- Trace("CEQ: Backedge from #%d:%s to #%d:%s\n", from->id(),
+ TRACE("CEQ: Backedge from #%d:%s to #%d:%s\n", from->id(),
from->op()->mnemonic(), to->id(), to->op()->mnemonic());
// Push backedge onto the bracket list [line:25].
void BracketListDelete(BracketList& blist, Node* to, DFSDirection direction) {
for (BracketList::iterator i = blist.begin(); i != blist.end(); /*nop*/) {
if (i->to == to && i->direction != direction) {
- Trace(" BList erased: {%d->%d}\n", i->from->id(), i->to->id());
+ TRACE(" BList erased: {%d->%d}\n", i->from->id(), i->to->id());
i = blist.erase(i);
} else {
++i;
}
}
- void BracketListTrace(BracketList& blist) {
+ void BracketListTRACE(BracketList& blist) {
if (FLAG_trace_turbo_scheduler) {
- Trace(" BList: ");
+ TRACE(" BList: ");
for (Bracket bracket : blist) {
- Trace("{%d->%d} ", bracket.from->id(), bracket.to->id());
+ TRACE("{%d->%d} ", bracket.from->id(), bracket.to->id());
}
- Trace("\n");
- }
- }
-
- void Trace(const char* msg, ...) {
- if (FLAG_trace_turbo_scheduler) {
- va_list arguments;
- va_start(arguments, msg);
- base::OS::VPrint(msg, arguments);
- va_end(arguments);
+ TRACE("\n");
}
}
Data node_data_; // Per-node data stored as a side-table.
};
+#undef TRACE
+
} // namespace compiler
} // namespace internal
} // namespace v8
namespace internal {
namespace compiler {
+#define TRACE(...) \
+ do { \
+ if (FLAG_trace_turbo_reduction) PrintF(__VA_ARGS__); \
+ } while (false)
+
enum VisitState { kUnvisited = 0, kOnStack = 1, kRevisit = 2, kVisited = 3 };
enum Decision { kFalse, kUnknown, kTrue };
};
-#define TRACE(x) \
- if (FLAG_trace_turbo_reduction) PrintF x
-
class ControlReducerImpl {
public:
ControlReducerImpl(Zone* zone, JSGraph* jsgraph,
while (!fw_stack.empty()) {
Node* node = fw_stack.back().first;
- TRACE(("ControlFw: #%d:%s\n", node->id(), node->op()->mnemonic()));
+ TRACE("ControlFw: #%d:%s\n", node->id(), node->op()->mnemonic());
bool pop = true;
while (fw_stack.back().second != node->uses().end()) {
Node* succ = *(fw_stack.back().second);
// Connect {loop}, the header of a non-terminating loop, to the end node.
Node* ConnectNTL(Node* loop) {
- TRACE(("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic()));
+ TRACE("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic());
Node* always = graph()->NewNode(common_->Always());
// Mark the node as visited so that we can revisit later.
for (Edge edge : node->use_edges()) {
Node* use = edge.from();
if (!marked.IsReachableFromEnd(use)) {
- TRACE(("DeadLink: #%d:%s(%d) -> #%d:%s\n", use->id(),
- use->op()->mnemonic(), edge.index(), node->id(),
- node->op()->mnemonic()));
+ TRACE("DeadLink: #%d:%s(%d) -> #%d:%s\n", use->id(),
+ use->op()->mnemonic(), edge.index(), node->id(),
+ node->op()->mnemonic());
edge.UpdateTo(NULL);
}
}
if (node->IsDead()) return Pop(); // Node was killed while on stack.
- TRACE(("ControlReduce: #%d:%s\n", node->id(), node->op()->mnemonic()));
+ TRACE("ControlReduce: #%d:%s\n", node->id(), node->op()->mnemonic());
// Recurse on an input if necessary.
for (Node* const input : node->inputs()) {
void Revisit(Node* node) {
size_t id = static_cast<size_t>(node->id());
if (id < state_.size() && state_[id] == kVisited) {
- TRACE((" Revisit #%d:%s\n", node->id(), node->op()->mnemonic()));
+ TRACE(" Revisit #%d:%s\n", node->id(), node->op()->mnemonic());
state_[id] = kRevisit;
revisit_.push_back(node);
}
// If a node has only one control input and it is dead, replace with dead.
Node* control = NodeProperties::GetControlInput(node);
if (control->opcode() == IrOpcode::kDead) {
- TRACE(("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic()));
+ TRACE("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic());
return control;
}
}
index++;
}
- TRACE(("ReduceMerge: #%d:%s (%d live)\n", node->id(),
- node->op()->mnemonic(), live));
+ TRACE("ReduceMerge: #%d:%s (%d live)\n", node->id(), node->op()->mnemonic(),
+ live);
if (live == 0) return dead(); // no remaining inputs.
if (live < node->InputCount()) {
// Edit phis in place, removing dead inputs and revisiting them.
for (Node* const phi : phis) {
- TRACE((" PhiInMerge: #%d:%s (%d live)\n", phi->id(),
- phi->op()->mnemonic(), live));
+ TRACE(" PhiInMerge: #%d:%s (%d live)\n", phi->id(),
+ phi->op()->mnemonic(), live);
RemoveDeadInputs(node, phi);
Revisit(phi);
}
// have users except for the Merge and the Merge has no Phi or
// EffectPhi uses, so replace the Merge with the control input of the
// diamond.
- TRACE((" DeadDiamond: #%d:%s #%d:%s #%d:%s\n", node0->id(),
- node0->op()->mnemonic(), node1->id(), node1->op()->mnemonic(),
- branch0->id(), branch0->op()->mnemonic()));
+ TRACE(" DeadDiamond: #%d:%s #%d:%s #%d:%s\n", node0->id(),
+ node0->op()->mnemonic(), node1->id(), node1->op()->mnemonic(),
+ branch0->id(), branch0->op()->mnemonic());
return NodeProperties::GetControlInput(branch0);
}
}
Decision result = DecideCondition(branch->InputAt(0));
if (result == kTrue) {
// fold a true branch by replacing IfTrue with the branch control.
- TRACE(("BranchReduce: #%d:%s => #%d:%s\n", branch->id(),
- branch->op()->mnemonic(), node->id(), node->op()->mnemonic()));
+ TRACE("BranchReduce: #%d:%s => #%d:%s\n", branch->id(),
+ branch->op()->mnemonic(), node->id(), node->op()->mnemonic());
return branch->InputAt(1);
}
return result == kUnknown ? node : dead();
Decision result = DecideCondition(branch->InputAt(0));
if (result == kFalse) {
// fold a false branch by replacing IfFalse with the branch control.
- TRACE(("BranchReduce: #%d:%s => #%d:%s\n", branch->id(),
- branch->op()->mnemonic(), node->id(), node->op()->mnemonic()));
+ TRACE("BranchReduce: #%d:%s => #%d:%s\n", branch->id(),
+ branch->op()->mnemonic(), node->id(), node->op()->mnemonic());
return branch->InputAt(1);
}
return result == kUnknown ? node : dead();
// Replace uses of {node} with {replacement} and revisit the uses.
void ReplaceNode(Node* node, Node* replacement) {
if (node == replacement) return;
- TRACE((" Replace: #%d:%s with #%d:%s\n", node->id(),
- node->op()->mnemonic(), replacement->id(),
- replacement->op()->mnemonic()));
+ TRACE(" Replace: #%d:%s with #%d:%s\n", node->id(), node->op()->mnemonic(),
+ replacement->id(), replacement->op()->mnemonic());
for (Node* const use : node->uses()) {
// Don't revisit this node if it refers to itself.
if (use != node) Revisit(use);
namespace internal {
namespace compiler {
+#define TRACE(...) \
+ do { \
+ if (FLAG_trace_turbo_inlining) PrintF(__VA_ARGS__); \
+ } while (false)
+
// Provides convenience accessors for calls to JS functions.
class JSCallFunctionAccessor {
if (info.scope()->arguments() != NULL && is_sloppy(info.language_mode())) {
// For now do not inline functions that use their arguments array.
- SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
- if (FLAG_trace_turbo_inlining) {
- PrintF(
- "Not Inlining %s into %s because inlinee uses arguments "
- "array\n",
- name.get(), info_->shared_info()->DebugName()->ToCString().get());
- }
+ TRACE("Not Inlining %s into %s because inlinee uses arguments array\n",
+ function->shared()->DebugName()->ToCString().get(),
+ info_->shared_info()->DebugName()->ToCString().get());
return NoChange();
}
- if (FLAG_trace_turbo_inlining) {
- SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
- PrintF("Inlining %s into %s\n", name.get(),
- info_->shared_info()->DebugName()->ToCString().get());
- }
+ TRACE("Inlining %s into %s\n",
+ function->shared()->DebugName()->ToCString().get(),
+ info_->shared_info()->DebugName()->ToCString().get());
Graph graph(info.zone());
JSGraph jsgraph(info.isolate(), &graph, jsgraph_->common(),
namespace internal {
namespace compiler {
-#define TRACE(x) \
- if (FLAG_trace_turbo_jt) PrintF x
+#define TRACE(...) \
+ do { \
+ if (FLAG_trace_turbo_jt) PrintF(__VA_ARGS__); \
+ } while (false)
struct JumpThreadingState {
bool forwarded;
RpoNumber to_to = result[to.ToInt()];
bool pop = true;
if (to == from) {
- TRACE((" xx %d\n", from.ToInt()));
+ TRACE(" xx %d\n", from.ToInt());
result[from.ToInt()] = from;
} else if (to_to == unvisited()) {
- TRACE((" fw %d -> %d (recurse)\n", from.ToInt(), to.ToInt()));
+ TRACE(" fw %d -> %d (recurse)\n", from.ToInt(), to.ToInt());
stack.push(to);
result[to.ToInt()] = onstack();
pop = false; // recurse.
} else if (to_to == onstack()) {
- TRACE((" fw %d -> %d (cycle)\n", from.ToInt(), to.ToInt()));
+ TRACE(" fw %d -> %d (cycle)\n", from.ToInt(), to.ToInt());
result[from.ToInt()] = to; // break the cycle.
forwarded = true;
} else {
- TRACE((" fw %d -> %d (forward)\n", from.ToInt(), to.ToInt()));
+ TRACE(" fw %d -> %d (forward)\n", from.ToInt(), to.ToInt());
result[from.ToInt()] = to_to; // forward the block.
forwarded = true;
}
while (!state.stack.empty()) {
InstructionBlock* block = code->InstructionBlockAt(state.stack.top());
// Process the instructions in a block up to a non-empty instruction.
- TRACE(("jt [%d] B%d\n", static_cast<int>(stack.size()),
- block->rpo_number().ToInt()));
+ TRACE("jt [%d] B%d\n", static_cast<int>(stack.size()),
+ block->rpo_number().ToInt());
bool fallthru = true;
RpoNumber fw = block->rpo_number();
for (int i = block->code_start(); i < block->code_end(); ++i) {
Instruction* instr = code->InstructionAt(i);
if (instr->IsGapMoves() && GapInstruction::cast(instr)->IsRedundant()) {
// skip redundant gap moves.
- TRACE((" nop gap\n"));
+ TRACE(" nop gap\n");
continue;
} else if (instr->IsSourcePosition()) {
// skip source positions.
- TRACE((" src pos\n"));
+ TRACE(" src pos\n");
continue;
} else if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
// can't skip instructions with flags continuations.
- TRACE((" flags\n"));
+ TRACE(" flags\n");
fallthru = false;
} else if (instr->IsNop()) {
// skip nops.
- TRACE((" nop\n"));
+ TRACE(" nop\n");
continue;
} else if (instr->arch_opcode() == kArchJmp) {
// try to forward the jump instruction.
- TRACE((" jmp\n"));
+ TRACE(" jmp\n");
fw = code->InputRpo(instr, 0);
fallthru = false;
} else {
// can't skip other instructions.
- TRACE((" other\n"));
+ TRACE(" other\n");
fallthru = false;
}
break;
if (FLAG_trace_turbo_jt) {
for (int i = 0; i < static_cast<int>(result.size()); i++) {
- TRACE(("B%d ", i));
+ TRACE("B%d ", i);
int to = result[i].ToInt();
if (i != to) {
- TRACE(("-> B%d\n", to));
+ TRACE("-> B%d\n", to);
} else {
- TRACE(("\n"));
+ TRACE("\n");
}
}
}
} else if (instr->arch_opcode() == kArchJmp) {
if (skip[block_num]) {
// Overwrite a redundant jump with a nop.
- TRACE(("jt-fw nop @%d\n", i));
+ TRACE("jt-fw nop @%d\n", i);
instr->OverwriteWithNop();
}
fallthru = false; // jumps don't fall through to the next block.
namespace internal {
namespace compiler {
-static inline void Trace(const char* msg, ...) {
- if (FLAG_trace_turbo_scheduler) {
- va_list arguments;
- va_start(arguments, msg);
- base::OS::VPrint(msg, arguments);
- va_end(arguments);
- }
-}
-
+#define TRACE(...) \
+ do { \
+ if (FLAG_trace_turbo_scheduler) PrintF(__VA_ARGS__); \
+ } while (false)
Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags)
: zone_(zone),
++(GetData(node)->unscheduled_count_);
if (FLAG_trace_turbo_scheduler) {
- Trace(" Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(),
+ TRACE(" Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(),
node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
GetData(node)->unscheduled_count_);
}
DCHECK(GetData(node)->unscheduled_count_ > 0);
--(GetData(node)->unscheduled_count_);
if (FLAG_trace_turbo_scheduler) {
- Trace(" Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(),
+ TRACE(" Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(),
node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
GetData(node)->unscheduled_count_);
}
if (GetData(node)->unscheduled_count_ == 0) {
- Trace(" newly eligible #%d:%s\n", node->id(), node->op()->mnemonic());
+ TRACE(" newly eligible #%d:%s\n", node->id(), node->op()->mnemonic());
schedule_queue_.push(node);
}
}
// Use control dependence equivalence to find a canonical single-entry
// single-exit region that makes up a minimal component to be scheduled.
if (IsSingleEntrySingleExitRegion(node, exit)) {
- Trace("Found SESE at #%d:%s\n", node->id(), node->op()->mnemonic());
+ TRACE("Found SESE at #%d:%s\n", node->id(), node->op()->mnemonic());
DCHECK(!component_entry_);
component_entry_ = node;
continue;
BasicBlock* block = schedule_->block(node);
if (block == NULL) {
block = schedule_->NewBasicBlock();
- Trace("Create block id:%d for #%d:%s\n", block->id().ToInt(), node->id(),
+ TRACE("Create block id:%d for #%d:%s\n", block->id().ToInt(), node->id(),
node->op()->mnemonic());
FixNode(block, node);
}
void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
DCHECK_NOT_NULL(block);
if (succ == NULL) {
- Trace("Connect #%d:%s, id:%d -> end\n", node->id(),
+ TRACE("Connect #%d:%s, id:%d -> end\n", node->id(),
node->op()->mnemonic(), block->id().ToInt());
} else {
- Trace("Connect #%d:%s, id:%d -> id:%d\n", node->id(),
+ TRACE("Connect #%d:%s, id:%d -> id:%d\n", node->id(),
node->op()->mnemonic(), block->id().ToInt(), succ->id().ToInt());
}
}
void Scheduler::BuildCFG() {
- Trace("--- CREATING CFG -------------------------------------------\n");
+ TRACE("--- CREATING CFG -------------------------------------------\n");
// Instantiate a new control equivalence algorithm for the graph.
equivalence_ = new (zone_) ControlEquivalence(zone_, graph_);
BasicBlock* end = current_loop->end;
current->set_loop_end(end == NULL ? BeyondEndSentinel() : end);
current_header = current_loop->header;
- Trace("id:%d is a loop header, increment loop depth to %d\n",
+ TRACE("id:%d is a loop header, increment loop depth to %d\n",
current->id().ToInt(), loop_depth);
}
current->set_loop_depth(loop_depth);
if (current->loop_header() == NULL) {
- Trace("id:%d is not in a loop (depth == %d)\n", current->id().ToInt(),
+ TRACE("id:%d is not in a loop (depth == %d)\n", current->id().ToInt(),
current->loop_depth());
} else {
- Trace("id:%d has loop header id:%d, (depth == %d)\n",
+ TRACE("id:%d has loop header id:%d, (depth == %d)\n",
current->id().ToInt(), current->loop_header()->id().ToInt(),
current->loop_depth());
}
void Scheduler::ComputeSpecialRPONumbering() {
- Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n");
+ TRACE("--- COMPUTING SPECIAL RPO ----------------------------------\n");
// Compute the special reverse-post-order for basic blocks.
special_rpo_ = new (zone_) SpecialRPONumberer(zone_, schedule_);
block->set_dominator(dominator);
block->set_dominator_depth(dominator->dominator_depth() + 1);
block->set_deferred(deferred | block->deferred());
- Trace("Block id:%d's idom is id:%d, depth = %d\n", block->id().ToInt(),
+ TRACE("Block id:%d's idom is id:%d, depth = %d\n", block->id().ToInt(),
dominator->id().ToInt(), block->dominator_depth());
}
}
void Scheduler::GenerateImmediateDominatorTree() {
- Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n");
+ TRACE("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n");
// Seed start block to be the first dominator.
schedule_->start()->set_dominator_depth(0);
scheduler_->schedule_root_nodes_.push_back(node);
if (!schedule_->IsScheduled(node)) {
// Make sure root nodes are scheduled in their respective blocks.
- Trace("Scheduling fixed position node #%d:%s\n", node->id(),
+ TRACE("Scheduling fixed position node #%d:%s\n", node->id(),
node->op()->mnemonic());
IrOpcode::Value opcode = node->opcode();
BasicBlock* block =
void Scheduler::PrepareUses() {
- Trace("--- PREPARE USES -------------------------------------------\n");
+ TRACE("--- PREPARE USES -------------------------------------------\n");
// Count the uses of every node, which is used to ensure that all of a
// node's uses are scheduled before the node itself.
// Fixed nodes already know their schedule early position.
if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
data->minimum_block_ = schedule_->block(node);
- Trace("Fixing #%d:%s minimum_block = id:%d, dominator_depth = %d\n",
+ TRACE("Fixing #%d:%s minimum_block = id:%d, dominator_depth = %d\n",
node->id(), node->op()->mnemonic(),
data->minimum_block_->id().ToInt(),
data->minimum_block_->dominator_depth());
if (block->dominator_depth() > data->minimum_block_->dominator_depth()) {
data->minimum_block_ = block;
queue_.push(node);
- Trace("Propagating #%d:%s minimum_block = id:%d, dominator_depth = %d\n",
+ TRACE("Propagating #%d:%s minimum_block = id:%d, dominator_depth = %d\n",
node->id(), node->op()->mnemonic(),
data->minimum_block_->id().ToInt(),
data->minimum_block_->dominator_depth());
void Scheduler::ScheduleEarly() {
- Trace("--- SCHEDULE EARLY -----------------------------------------\n");
+ TRACE("--- SCHEDULE EARLY -----------------------------------------\n");
if (FLAG_trace_turbo_scheduler) {
- Trace("roots: ");
+ TRACE("roots: ");
for (Node* node : schedule_root_nodes_) {
- Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+ TRACE("#%d:%s ", node->id(), node->op()->mnemonic());
}
- Trace("\n");
+ TRACE("\n");
}
// Compute the minimum block for each node thereby determining the earliest
// Determine the dominating block for all of the uses of this node. It is
// the latest block that this node can be scheduled in.
- Trace("Scheduling #%d:%s\n", node->id(), node->op()->mnemonic());
+ TRACE("Scheduling #%d:%s\n", node->id(), node->op()->mnemonic());
BasicBlock* block = GetCommonDominatorOfUses(node);
DCHECK_NOT_NULL(block);
// The schedule early block dominates the schedule late block.
BasicBlock* min_block = scheduler_->GetData(node)->minimum_block_;
DCHECK_EQ(min_block, BasicBlock::GetCommonDominator(block, min_block));
- Trace(
+ TRACE(
"Schedule late of #%d:%s is id:%d at loop depth %d, minimum = id:%d\n",
node->id(), node->op()->mnemonic(), block->id().ToInt(),
block->loop_depth(), min_block->id().ToInt());
if (hoist_block &&
hoist_block->dominator_depth() >= min_block->dominator_depth()) {
do {
- Trace(" hoisting #%d:%s to block id:%d\n", node->id(),
+ TRACE(" hoisting #%d:%s to block id:%d\n", node->id(),
node->op()->mnemonic(), hoist_block->id().ToInt());
DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
block = hoist_block;
BasicBlock* use_block = GetBlockForUse(edge);
if (use_block == nullptr || marked_[use_block->id().ToSize()]) continue;
if (use_block == block) {
- Trace(" not splitting #%d:%s, it is used in id:%d\n", node->id(),
+ TRACE(" not splitting #%d:%s, it is used in id:%d\n", node->id(),
node->op()->mnemonic(), block->id().ToInt());
marking_queue_.clear();
return block;
// {block} to the end contain at least one use of {node}, and hence there's
// no point in splitting the {node} in this case.
if (marked_[block->id().ToSize()]) {
- Trace(" not splitting #%d:%s, its common dominator id:%d is perfect\n",
+ TRACE(" not splitting #%d:%s, its common dominator id:%d is perfect\n",
node->id(), node->op()->mnemonic(), block->id().ToInt());
return block;
}
// Place the {node} at {use_block}.
block = use_block;
use_node = node;
- Trace(" pushing #%d:%s down to id:%d\n", node->id(),
+ TRACE(" pushing #%d:%s down to id:%d\n", node->id(),
node->op()->mnemonic(), block->id().ToInt());
} else {
// Place a copy of {node} at {use_block}.
use_node = CloneNode(node);
- Trace(" cloning #%d:%s for id:%d\n", use_node->id(),
+ TRACE(" cloning #%d:%s for id:%d\n", use_node->id(),
use_node->op()->mnemonic(), use_block->id().ToInt());
scheduler_->schedule_queue_.push(use_node);
}
// If the use is from a coupled (i.e. floating) phi, compute the common
// dominator of its uses. This will not recurse more than one level.
if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) {
- Trace(" inspecting uses of coupled #%d:%s\n", use->id(),
+ TRACE(" inspecting uses of coupled #%d:%s\n", use->id(),
use->op()->mnemonic());
DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use));
return GetCommonDominatorOfUses(use);
// If the use is from a fixed (i.e. non-floating) phi, we use the
// predecessor block of the corresponding control input to the merge.
if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
- Trace(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(),
+ TRACE(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(),
use->op()->mnemonic());
Node* merge = NodeProperties::GetControlInput(use, 0);
DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
// If the use is from a fixed (i.e. non-floating) merge, we use the
// predecessor block of the current input to the merge.
if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
- Trace(" input@%d into a fixed merge #%d:%s\n", edge.index(), use->id(),
+ TRACE(" input@%d into a fixed merge #%d:%s\n", edge.index(), use->id(),
use->op()->mnemonic());
return FindPredecessorBlock(edge.to());
}
}
BasicBlock* result = schedule_->block(use);
if (result == NULL) return NULL;
- Trace(" must dominate use #%d:%s in id:%d\n", use->id(),
+ TRACE(" must dominate use #%d:%s in id:%d\n", use->id(),
use->op()->mnemonic(), result->id().ToInt());
return result;
}
void Scheduler::ScheduleLate() {
- Trace("--- SCHEDULE LATE ------------------------------------------\n");
+ TRACE("--- SCHEDULE LATE ------------------------------------------\n");
if (FLAG_trace_turbo_scheduler) {
- Trace("roots: ");
+ TRACE("roots: ");
for (Node* node : schedule_root_nodes_) {
- Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+ TRACE("#%d:%s ", node->id(), node->op()->mnemonic());
}
- Trace("\n");
+ TRACE("\n");
}
// Schedule: Places nodes in dominator block of all their uses.
void Scheduler::SealFinalSchedule() {
- Trace("--- SEAL FINAL SCHEDULE ------------------------------------\n");
+ TRACE("--- SEAL FINAL SCHEDULE ------------------------------------\n");
// Serialize the assembly order and reverse-post-order numbering.
special_rpo_->SerializeRPOIntoSchedule();
void Scheduler::FuseFloatingControl(BasicBlock* block, Node* node) {
- Trace("--- FUSE FLOATING CONTROL ----------------------------------\n");
+ TRACE("--- FUSE FLOATING CONTROL ----------------------------------\n");
if (FLAG_trace_turbo_scheduler) {
OFStream os(stdout);
os << "Schedule before control flow fusion:\n" << *schedule_;
}
}
if (FLAG_trace_turbo_scheduler) {
- Trace("propagation roots: ");
+ TRACE("propagation roots: ");
for (Node* node : propagation_roots) {
- Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+ TRACE("#%d:%s ", node->id(), node->op()->mnemonic());
}
- Trace("\n");
+ TRACE("\n");
}
ScheduleEarlyNodeVisitor schedule_early_visitor(zone_, this);
schedule_early_visitor.Run(&propagation_roots);
void Scheduler::MovePlannedNodes(BasicBlock* from, BasicBlock* to) {
- Trace("Move planned nodes from id:%d to id:%d\n", from->id().ToInt(),
+ TRACE("Move planned nodes from id:%d to id:%d\n", from->id().ToInt(),
to->id().ToInt());
NodeVector* nodes = &(scheduled_nodes_[from->id().ToSize()]);
for (Node* const node : *nodes) {
namespace compiler {
// Macro for outputting trace information from representation inference.
-#define TRACE(x) \
- if (FLAG_trace_representation) PrintF x
+#define TRACE(...) \
+ do { \
+ if (FLAG_trace_representation) PrintF(__VA_ARGS__); \
+ } while (false)
// Representation selection and lowering of {Simplified} operators to machine
// operators are interwined. We use a fixpoint calculation to compute both the
void Run(SimplifiedLowering* lowering) {
// Run propagation phase to a fixpoint.
- TRACE(("--{Propagation phase}--\n"));
+ TRACE("--{Propagation phase}--\n");
phase_ = PROPAGATE;
Enqueue(jsgraph_->graph()->end());
// Process nodes from the queue until it is empty.
NodeInfo* info = GetInfo(node);
queue_.pop();
info->queued = false;
- TRACE((" visit #%d: %s\n", node->id(), node->op()->mnemonic()));
+ TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
VisitNode(node, info->use, NULL);
- TRACE((" ==> output "));
+ TRACE(" ==> output ");
PrintInfo(info->output);
- TRACE(("\n"));
+ TRACE("\n");
}
// Run lowering and change insertion phase.
- TRACE(("--{Simplified lowering phase}--\n"));
+ TRACE("--{Simplified lowering phase}--\n");
phase_ = LOWER;
// Process nodes from the collected {nodes_} vector.
for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
Node* node = *i;
- TRACE((" visit #%d: %s\n", node->id(), node->op()->mnemonic()));
+ TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
// Reuse {VisitNode()} so the representation rules are in one place.
if (FLAG_turbo_source_positions) {
SourcePositionTable::Scope scope(
info->queued = true;
nodes_.push_back(node);
queue_.push(node);
- TRACE((" initial: "));
+ TRACE(" initial: ");
info->use |= use;
PrintUseInfo(node);
return;
}
- TRACE((" queue?: "));
+ TRACE(" queue?: ");
PrintUseInfo(node);
if ((info->use & use) != use) {
// New usage information for the node is available.
if (!info->queued) {
queue_.push(node);
info->queued = true;
- TRACE((" added: "));
+ TRACE(" added: ");
} else {
- TRACE((" inqueue: "));
+ TRACE(" inqueue: ");
}
info->use |= use;
PrintUseInfo(node);
MachineTypeUnion output = GetInfo(input)->output;
if ((output & (kRepBit | kRepWord8 | kRepWord16 | kRepWord32)) == 0) {
// Output representation doesn't match usage.
- TRACE((" truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(),
- node->op()->mnemonic(), index, input->id(),
- input->op()->mnemonic()));
- TRACE((" from "));
+ TRACE(" truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(),
+ node->op()->mnemonic(), index, input->id(),
+ input->op()->mnemonic());
+ TRACE(" from ");
PrintInfo(output);
- TRACE((" to "));
+ TRACE(" to ");
PrintInfo(use);
- TRACE(("\n"));
+ TRACE("\n");
Node* n = changer_->GetTruncatedWord32For(input, output);
node->ReplaceInput(index, n);
}
MachineTypeUnion output = GetInfo(input)->output;
if ((output & kRepMask & use) == 0) {
// Output representation doesn't match usage.
- TRACE((" change: #%d:%s(@%d #%d:%s) ", node->id(),
- node->op()->mnemonic(), index, input->id(),
- input->op()->mnemonic()));
- TRACE((" from "));
+ TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(),
+ node->op()->mnemonic(), index, input->id(),
+ input->op()->mnemonic());
+ TRACE(" from ");
PrintInfo(output);
- TRACE((" to "));
+ TRACE(" to ");
PrintInfo(use);
- TRACE(("\n"));
+ TRACE("\n");
Node* n = changer_->GetRepresentationFor(input, output, use);
node->ReplaceInput(index, n);
}
}
void DeferReplacement(Node* node, Node* replacement) {
- if (FLAG_trace_representation) {
- TRACE(("defer replacement #%d:%s with #%d:%s\n", node->id(),
- node->op()->mnemonic(), replacement->id(),
- replacement->op()->mnemonic()));
- }
+ TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
+ node->op()->mnemonic(), replacement->id(),
+ replacement->op()->mnemonic());
+
if (replacement->id() < count_ &&
GetInfo(replacement)->output == GetInfo(node)->output) {
// Replace with a previously existing node eagerly only if the type is the
}
void PrintUseInfo(Node* node) {
- TRACE(("#%d:%-20s ", node->id(), node->op()->mnemonic()));
+ TRACE("#%d:%-20s ", node->id(), node->op()->mnemonic());
PrintInfo(GetUseInfo(node));
- TRACE(("\n"));
+ TRACE("\n");
}
void PrintInfo(MachineTypeUnion info) {
do { \
Node* __n[] = {__VA_ARGS__}; \
ASSERT_TRUE(IsEquivalenceClass(arraysize(__n), __n)); \
- } while (false);
+ } while (false)
class ControlEquivalenceTest : public GraphTest {
public: